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 { getCommits, git, IGitExecutionOptions } from '.'
|
||||
import { CommitOneLine } from '../../models/commit'
|
||||
import { getCommits, revRange } from '.'
|
||||
import { Commit, CommitOneLine } from '../../models/commit'
|
||||
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 previousCommit - sha of commit before all commits in squash operation
|
||||
* @param commitSummary - summary of new commit made by squash
|
||||
|
@ -16,72 +17,54 @@ import { Repository } from '../../models/repository'
|
|||
*/
|
||||
export async function squash(
|
||||
repository: Repository,
|
||||
squash: ReadonlyArray<CommitOneLine>,
|
||||
toSquash: ReadonlyArray<CommitOneLine>,
|
||||
squashOnto: CommitOneLine,
|
||||
logIndex: number,
|
||||
lastRetainedCommitRef: string,
|
||||
commitSummary: string,
|
||||
commitDescription: string
|
||||
): Promise<ReadonlyArray<string>> {
|
||||
const options: IGitExecutionOptions = {
|
||||
env: {
|
||||
// if we don't provide editor, we can't detect git errors
|
||||
// GIT_EDITOR: ':',
|
||||
},
|
||||
}
|
||||
): Promise<RebaseResult> {
|
||||
const commits: Commit[] = [
|
||||
...(await getCommits(repository, revRange(lastRetainedCommitRef, 'HEAD'))),
|
||||
]
|
||||
|
||||
// get commits from log to cherry pick
|
||||
/*
|
||||
const commits = await getCommits(
|
||||
let todoOutput = ''
|
||||
commits.forEach(c => {
|
||||
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,
|
||||
'HEAD~' + logIndex + 1,
|
||||
logIndex + 1
|
||||
)
|
||||
*/
|
||||
|
||||
//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,
|
||||
todoPath,
|
||||
lastRetainedCommitRef,
|
||||
'squash',
|
||||
options
|
||||
`cat "${messagePath}" >`
|
||||
// TODO: add progress
|
||||
)
|
||||
|
||||
return []
|
||||
FSE.remove(todoPath)
|
||||
FSE.remove(messagePath)
|
||||
|
||||
// parse todo
|
||||
|
||||
// build new todo
|
||||
|
||||
// save todo
|
||||
|
||||
//return true
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import * as Path from 'path'
|
||||
import * as FSE from 'fs-extra'
|
||||
import { getCommit, getCommits, git } from '../../../src/lib/git'
|
||||
import { getCommit, getCommits, RebaseResult } from '../../../src/lib/git'
|
||||
import { CommitOneLine } from '../../../src/models/commit'
|
||||
import { Repository } from '../../../src/models/repository'
|
||||
import { setupEmptyRepositoryDefaultMain } from '../../helpers/repositories'
|
||||
import { makeCommit } from '../../helpers/repository-scaffolding'
|
||||
import { squash } from '../../../src/lib/git/squash'
|
||||
|
||||
describe('git/cherry-pick', () => {
|
||||
let repository: Repository
|
||||
|
@ -17,36 +16,23 @@ describe('git/cherry-pick', () => {
|
|||
|
||||
it('squashes one commit onto the next (non-conflicting)', async () => {
|
||||
const firstCommit = await makeSquashCommit(repository, 'first')
|
||||
const firstShortSha = firstCommit.sha.slice(0, 7)
|
||||
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')
|
||||
await FSE.writeFile(
|
||||
Path.join(repository.path, 'test'),
|
||||
`pick ${firstShortSha} 1\nsquash ${secondShortSha} 2\nsquash ${thirdShortSha} 3\n`
|
||||
const result = await squash(
|
||||
repository,
|
||||
[secondCommit],
|
||||
firstCommit,
|
||||
initialCommit.sha,
|
||||
'Test Summary',
|
||||
'Test Body'
|
||||
)
|
||||
|
||||
await git(
|
||||
[
|
||||
'-c',
|
||||
`sequence.editor=cat "${path}" >`,
|
||||
'rebase',
|
||||
'-i',
|
||||
initialCommit.sha,
|
||||
],
|
||||
repository.path,
|
||||
'squash',
|
||||
{
|
||||
env: {
|
||||
GIT_EDITOR: ':',
|
||||
},
|
||||
}
|
||||
)
|
||||
expect(result).toBe(RebaseResult.CompletedWithoutError)
|
||||
|
||||
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)
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue