mirror of
https://github.com/desktop/desktop
synced 2024-09-19 16:12:20 +00:00
Squashing with interactive rebase one test
This commit is contained in:
parent
18e298ae6b
commit
a28b7503d7
|
@ -1,13 +1,14 @@
|
||||||
import * as Path from 'path'
|
|
||||||
import * as FSE from 'fs-extra'
|
import * as FSE from 'fs-extra'
|
||||||
import { getCommits, git, IGitExecutionOptions } from '.'
|
import { getCommits, revRange } from '.'
|
||||||
import { CommitOneLine } from '../../models/commit'
|
import { Commit, CommitOneLine } from '../../models/commit'
|
||||||
import { Repository } from '../../models/repository'
|
import { Repository } from '../../models/repository'
|
||||||
|
import { getTempFilePath } from '../file-system'
|
||||||
|
import { rebaseInteractive, RebaseResult } from './rebase'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiates an interactive rebase and squashes provided commits
|
* Squashes provided commits by calling interactive rebase
|
||||||
*
|
*
|
||||||
* @param squash - commits to squash onto another commit
|
* @param toSquash - commits to squash onto another commit
|
||||||
* @param squashOnto - commit to squash the `squash` commits onto
|
* @param squashOnto - commit to squash the `squash` commits onto
|
||||||
* @param previousCommit - sha of commit before all commits in squash operation
|
* @param previousCommit - sha of commit before all commits in squash operation
|
||||||
* @param commitSummary - summary of new commit made by squash
|
* @param commitSummary - summary of new commit made by squash
|
||||||
|
@ -16,72 +17,54 @@ import { Repository } from '../../models/repository'
|
||||||
*/
|
*/
|
||||||
export async function squash(
|
export async function squash(
|
||||||
repository: Repository,
|
repository: Repository,
|
||||||
squash: ReadonlyArray<CommitOneLine>,
|
toSquash: ReadonlyArray<CommitOneLine>,
|
||||||
squashOnto: CommitOneLine,
|
squashOnto: CommitOneLine,
|
||||||
logIndex: number,
|
lastRetainedCommitRef: string,
|
||||||
commitSummary: string,
|
commitSummary: string,
|
||||||
commitDescription: string
|
commitDescription: string
|
||||||
): Promise<ReadonlyArray<string>> {
|
): Promise<RebaseResult> {
|
||||||
const options: IGitExecutionOptions = {
|
const commits: Commit[] = [
|
||||||
env: {
|
...(await getCommits(repository, revRange(lastRetainedCommitRef, 'HEAD'))),
|
||||||
// if we don't provide editor, we can't detect git errors
|
]
|
||||||
// GIT_EDITOR: ':',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// get commits from log to cherry pick
|
let todoOutput = ''
|
||||||
/*
|
commits.forEach(c => {
|
||||||
const commits = await getCommits(
|
if (toSquash.map(sq => sq.sha).includes(c.sha)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.sha === squashOnto.sha) {
|
||||||
|
todoOutput += `pick ${c.sha} ${c.summary}\n`
|
||||||
|
toSquash.forEach(async sq => {
|
||||||
|
todoOutput += `squash ${sq.sha} ${sq.summary}\n`
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
todoOutput += `pick ${c.sha} ${c.summary}\n`
|
||||||
|
})
|
||||||
|
|
||||||
|
const todoPath = await getTempFilePath('squashTodo')
|
||||||
|
await FSE.writeFile(todoPath, todoOutput)
|
||||||
|
|
||||||
|
const messagePath = await getTempFilePath('squashCommitMessage')
|
||||||
|
const message =
|
||||||
|
commitDescription !== ''
|
||||||
|
? `${commitSummary}\n\n${commitDescription}`
|
||||||
|
: commitSummary
|
||||||
|
await FSE.writeFile(messagePath, message)
|
||||||
|
|
||||||
|
const result = await rebaseInteractive(
|
||||||
repository,
|
repository,
|
||||||
'HEAD~' + logIndex + 1,
|
todoPath,
|
||||||
logIndex + 1
|
lastRetainedCommitRef,
|
||||||
)
|
|
||||||
*/
|
|
||||||
|
|
||||||
//return commits.map(c => c.shortSha)
|
|
||||||
|
|
||||||
// current branch name
|
|
||||||
// const currentBranch = git current branch...
|
|
||||||
|
|
||||||
// Create a temporary branch from the head before the earliest squash commit
|
|
||||||
// - const tempBranch = git checkout head~x -b temp branch... pick a branch name that doesn't exist..
|
|
||||||
|
|
||||||
// loop through log
|
|
||||||
// if commit === SquashOnto
|
|
||||||
// - cherry pick -n squash onto
|
|
||||||
// - loop through ToSquash -> cherry pick -n (may have conflicts/Progress?)
|
|
||||||
// - commit -m commitsummary and commitDescription
|
|
||||||
// if commit in squashOnto
|
|
||||||
// - continue loop
|
|
||||||
// else
|
|
||||||
// - cherry pick regular
|
|
||||||
// This loop process could be aborted at anytime.. if so delete temp branch, check out current branch
|
|
||||||
|
|
||||||
// check out current branch
|
|
||||||
// git hard reset --> HEAD~logIndex+1
|
|
||||||
// git rebase tempBranch ... this should not have conflicts since the branches base history should be the same..
|
|
||||||
|
|
||||||
// Start interactive rebase
|
|
||||||
await git(
|
|
||||||
[
|
|
||||||
'rebase',
|
|
||||||
'-c',
|
|
||||||
'"sequence.editor=sed -i /123456/d"',
|
|
||||||
'-i',
|
|
||||||
'HEAD~'logIndex+1,
|
|
||||||
],
|
|
||||||
repository.path,
|
|
||||||
'squash',
|
'squash',
|
||||||
options
|
`cat "${messagePath}" >`
|
||||||
|
// TODO: add progress
|
||||||
)
|
)
|
||||||
|
|
||||||
return []
|
FSE.remove(todoPath)
|
||||||
|
FSE.remove(messagePath)
|
||||||
|
|
||||||
// parse todo
|
return result
|
||||||
|
|
||||||
// build new todo
|
|
||||||
|
|
||||||
// save todo
|
|
||||||
|
|
||||||
//return true
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import * as Path from 'path'
|
import { getCommit, getCommits, RebaseResult } from '../../../src/lib/git'
|
||||||
import * as FSE from 'fs-extra'
|
|
||||||
import { getCommit, getCommits, git } from '../../../src/lib/git'
|
|
||||||
import { CommitOneLine } from '../../../src/models/commit'
|
import { CommitOneLine } from '../../../src/models/commit'
|
||||||
import { Repository } from '../../../src/models/repository'
|
import { Repository } from '../../../src/models/repository'
|
||||||
import { setupEmptyRepositoryDefaultMain } from '../../helpers/repositories'
|
import { setupEmptyRepositoryDefaultMain } from '../../helpers/repositories'
|
||||||
import { makeCommit } from '../../helpers/repository-scaffolding'
|
import { makeCommit } from '../../helpers/repository-scaffolding'
|
||||||
|
import { squash } from '../../../src/lib/git/squash'
|
||||||
|
|
||||||
describe('git/cherry-pick', () => {
|
describe('git/cherry-pick', () => {
|
||||||
let repository: Repository
|
let repository: Repository
|
||||||
|
@ -17,36 +16,23 @@ describe('git/cherry-pick', () => {
|
||||||
|
|
||||||
it('squashes one commit onto the next (non-conflicting)', async () => {
|
it('squashes one commit onto the next (non-conflicting)', async () => {
|
||||||
const firstCommit = await makeSquashCommit(repository, 'first')
|
const firstCommit = await makeSquashCommit(repository, 'first')
|
||||||
const firstShortSha = firstCommit.sha.slice(0, 7)
|
|
||||||
const secondCommit = await makeSquashCommit(repository, 'second')
|
const secondCommit = await makeSquashCommit(repository, 'second')
|
||||||
const secondShortSha = secondCommit.sha.slice(0, 7)
|
|
||||||
const thirdCommit = await makeSquashCommit(repository, 'third')
|
|
||||||
const thirdShortSha = thirdCommit.sha.slice(0, 7)
|
|
||||||
|
|
||||||
const path = Path.join(repository.path, 'test')
|
const result = await squash(
|
||||||
await FSE.writeFile(
|
repository,
|
||||||
Path.join(repository.path, 'test'),
|
[secondCommit],
|
||||||
`pick ${firstShortSha} 1\nsquash ${secondShortSha} 2\nsquash ${thirdShortSha} 3\n`
|
firstCommit,
|
||||||
|
initialCommit.sha,
|
||||||
|
'Test Summary',
|
||||||
|
'Test Body'
|
||||||
)
|
)
|
||||||
|
|
||||||
await git(
|
expect(result).toBe(RebaseResult.CompletedWithoutError)
|
||||||
[
|
|
||||||
'-c',
|
|
||||||
`sequence.editor=cat "${path}" >`,
|
|
||||||
'rebase',
|
|
||||||
'-i',
|
|
||||||
initialCommit.sha,
|
|
||||||
],
|
|
||||||
repository.path,
|
|
||||||
'squash',
|
|
||||||
{
|
|
||||||
env: {
|
|
||||||
GIT_EDITOR: ':',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const log = await getCommits(repository, 'HEAD', 5)
|
const log = await getCommits(repository, 'HEAD', 5)
|
||||||
|
const squashed = log[0]
|
||||||
|
expect(squashed.summary).toBe('Test Summary')
|
||||||
|
expect(squashed.body).toBe('Test Body\n')
|
||||||
expect(log.length).toBe(2)
|
expect(log.length).toBe(2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue