Merge pull request #12390 from desktop/squash-merge-abort

Abort squash merge
This commit is contained in:
tidy-dev 2021-06-07 10:26:37 -04:00 committed by GitHub
commit b618498843
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 6 deletions

View file

@ -1962,7 +1962,7 @@ export class AppStore extends TypedBaseStore<IAppState> {
this.updateMultiCommitOperationConflictsIfFound(repository)
if (this.selectedRepository === repository) {
this._triggerConflictsFlow(repository)
this._triggerConflictsFlow(repository, status)
}
this.emitUpdate()
@ -2072,7 +2072,10 @@ export class AppStore extends TypedBaseStore<IAppState> {
}
}
private async _triggerConflictsFlow(repository: Repository) {
private async _triggerConflictsFlow(
repository: Repository,
status: IStatusResult
) {
const state = this.repositoryStateCache.get(repository)
const {
changesState: { conflictState },
@ -2090,7 +2093,8 @@ export class AppStore extends TypedBaseStore<IAppState> {
repository,
conflictState,
multiCommitOperationState,
branchesState.tip
branchesState.tip,
status.squashMsgFound
)
} else if (isRebaseConflictState(conflictState)) {
// TODO: This will likely get refactored to a showConflictsDialog method
@ -2175,14 +2179,15 @@ export class AppStore extends TypedBaseStore<IAppState> {
repository: Repository,
conflictState: MergeConflictState,
multiCommitOperationState: IMultiCommitOperationState | null,
tip: Tip
tip: Tip,
isSquash: boolean
) {
if (multiCommitOperationState === null && tip.kind === TipState.Valid) {
this._initializeMultiCommitOperation(
repository,
{
kind: MultiCommitOperationKind.Merge,
isSquash: false,
isSquash,
sourceBranch: null,
},
tip.branch,
@ -4652,6 +4657,44 @@ export class AppStore extends TypedBaseStore<IAppState> {
return await gitStore.performFailableOperation(() => abortMerge(repository))
}
/** This shouldn't be called directly. See `Dispatcher`. */
public async _abortSquashMerge(repository: Repository): Promise<void> {
const gitStore = this.gitStoreCache.get(repository)
const {
branchesState,
changesState: { workingDirectory },
} = this.repositoryStateCache.get(repository)
const commitResult = await this._finishConflictedMerge(
repository,
workingDirectory,
new Map<string, ManualConflictResolution>()
)
// By committing, we clear out the SQUASH_MSG (and anything else git would
// choose to store for the --squash merge operation)
if (commitResult === undefined) {
log.error(
`[_abortSquashMerge] - Could not abort squash merge - commiting squash msg failed`
)
return
}
// Since we have not reloaded the status, this tip is the tip before the
// squash commit above.
const { tip } = branchesState
if (tip.kind !== TipState.Valid) {
log.error(
`[_abortSquashMerge] - Could not abort squash merge - tip was invalid`
)
return
}
await gitStore.performFailableOperation(() =>
reset(repository, GitResetMode.Hard, tip.branch.tip.sha)
)
}
/** This shouldn't be called directly. See `Dispatcher`.
* This method only used in the Merge Conflicts dialog flow,
* not committing a conflicted merge via the "Changes" pane.

View file

@ -1223,6 +1223,12 @@ export class Dispatcher {
await this.appStore._loadStatus(repository)
}
/** aborts an in-flight merge and refreshes the repository's status */
public async abortSquashMerge(repository: Repository) {
await this.appStore._abortSquashMerge(repository)
return this.appStore._refreshRepository(repository)
}
/**
* commits an in-flight merge and shows a banner if successful
*

View file

@ -47,8 +47,18 @@ export abstract class Merge extends BaseMultiCommitOperation {
}
protected onAbort = async (): Promise<void> => {
const { repository, dispatcher } = this.props
const {
repository,
dispatcher,
state: { operationDetail },
} = this.props
this.onFlowEnded()
if (
operationDetail.kind === MultiCommitOperationKind.Merge &&
operationDetail.isSquash
) {
return dispatcher.abortSquashMerge(repository)
}
return dispatcher.abortMerge(repository)
}