Create base rebase multi commit operation

This commit is contained in:
tidy-dev 2021-08-12 15:39:43 -04:00
parent e25541134a
commit 502cf3a0f1
4 changed files with 95 additions and 134 deletions

View file

@ -134,13 +134,7 @@ export type CreateBranchStep = {
targetBranchName: string
}
interface IInteractiveRebaseDetails {
/**
* The reference to the last retained commit on the branch during an
* interactive rebase or null if rebasing to the root.
*/
readonly lastRetainedCommitRef: string | null
interface IBaseRebaseDetails {
/**
* Array of commits used during the operation.
*/
@ -153,6 +147,14 @@ interface IInteractiveRebaseDetails {
readonly currentTip: string
}
interface IInteractiveRebaseDetails extends IBaseRebaseDetails {
/**
* The reference to the last retained commit on the branch during an
* interactive rebase or null if rebasing to the root.
*/
readonly lastRetainedCommitRef: string | null
}
interface ISourceBranchDetails {
/**
* The branch that are the source of the commits for the operation.
@ -201,7 +203,7 @@ interface ICherryPickDetails extends ISourceBranchDetails {
readonly commits: ReadonlyArray<CommitOneLine>
}
interface IRebaseDetails extends ISourceBranchDetails {
interface IRebaseDetails extends ISourceBranchDetails, IBaseRebaseDetails {
readonly kind: MultiCommitOperationKind.Rebase
}
@ -216,3 +218,9 @@ export type MultiCommitOperationDetail =
| ICherryPickDetails
| IRebaseDetails
| IMergeDetails
export function instanceOfIBaseRebaseDetails(
object: any
): object is IBaseRebaseDetails {
return 'commits' in object && 'currentTip' in object
}

View file

@ -0,0 +1,71 @@
import { RebaseConflictState } from '../../lib/app-state'
import {
instanceOfIBaseRebaseDetails,
MultiCommitOperationKind,
} from '../../models/multi-commit-operation'
import { BaseMultiCommitOperation } from './base-multi-commit-operation'
export abstract class BaseRebase extends BaseMultiCommitOperation {
protected abstract conflictDialogOperationPrefix: string
protected abstract rebaseKind: MultiCommitOperationKind
protected onContinueAfterConflicts = async (): Promise<void> => {
const {
repository,
dispatcher,
workingDirectory,
state,
conflictState,
} = this.props
const { operationDetail, targetBranch, originalBranchTip } = state
if (
conflictState === null ||
targetBranch === null ||
originalBranchTip === null ||
!instanceOfIBaseRebaseDetails(operationDetail)
) {
this.endFlowInvalidState()
return
}
const { commits, currentTip } = operationDetail
await dispatcher.switchMultiCommitOperationToShowProgress(repository)
const rebaseConflictState: RebaseConflictState = {
kind: 'rebase',
currentTip,
targetBranch: targetBranch.name,
baseBranch: undefined,
originalBranchTip,
baseBranchTip: currentTip,
manualResolutions: conflictState.manualResolutions,
}
const rebaseResult = await dispatcher.continueRebase(
this.rebaseKind,
repository,
workingDirectory,
rebaseConflictState
)
return dispatcher.processMultiCommitOperationRebaseResult(
this.rebaseKind,
repository,
rebaseResult,
commits.length + 1,
targetBranch.name
)
}
protected onAbort = async (): Promise<void> => {
const { repository, dispatcher } = this.props
this.onFlowEnded()
return dispatcher.abortRebase(repository)
}
protected onConflictsDialogDismissed = () => {
this.onInvokeConflictsDialogDismissed(this.conflictDialogOperationPrefix)
}
}

View file

@ -1,8 +1,9 @@
import { RebaseConflictState } from '../../lib/app-state'
import { MultiCommitOperationKind } from '../../models/multi-commit-operation'
import { BaseMultiCommitOperation } from './base-multi-commit-operation'
import { BaseRebase } from './base-rebase'
export abstract class Reorder extends BaseRebase {
protected conflictDialogOperationPrefix = 'reordering commits on'
export abstract class Reorder extends BaseMultiCommitOperation {
protected onBeginOperation = () => {
const { repository, dispatcher, state } = this.props
const { operationDetail } = state
@ -22,64 +23,4 @@ export abstract class Reorder extends BaseMultiCommitOperation {
true
)
}
protected onContinueAfterConflicts = async (): Promise<void> => {
const {
repository,
dispatcher,
workingDirectory,
state,
conflictState,
} = this.props
const { operationDetail, targetBranch, originalBranchTip } = state
if (
conflictState === null ||
targetBranch === null ||
originalBranchTip === null ||
operationDetail.kind !== MultiCommitOperationKind.Reorder
) {
this.endFlowInvalidState()
return
}
const { commits, currentTip } = operationDetail
await dispatcher.switchMultiCommitOperationToShowProgress(repository)
const rebaseConflictState: RebaseConflictState = {
kind: 'rebase',
currentTip,
targetBranch: targetBranch.name,
baseBranch: undefined,
originalBranchTip,
baseBranchTip: currentTip,
manualResolutions: conflictState.manualResolutions,
}
const rebaseResult = await dispatcher.continueRebase(
MultiCommitOperationKind.Reorder,
repository,
workingDirectory,
rebaseConflictState
)
return dispatcher.processMultiCommitOperationRebaseResult(
MultiCommitOperationKind.Reorder,
repository,
rebaseResult,
commits.length,
targetBranch.name
)
}
protected onAbort = async (): Promise<void> => {
const { repository, dispatcher } = this.props
this.onFlowEnded()
return dispatcher.abortRebase(repository)
}
protected onConflictsDialogDismissed = () => {
this.onInvokeConflictsDialogDismissed('reordering commits on')
}
}

View file

@ -1,8 +1,9 @@
import { RebaseConflictState } from '../../lib/app-state'
import { MultiCommitOperationKind } from '../../models/multi-commit-operation'
import { BaseMultiCommitOperation } from './base-multi-commit-operation'
import { BaseRebase } from './base-rebase'
export abstract class Squash extends BaseRebase {
protected conflictDialogOperationPrefix = 'squashing commits on'
export abstract class Squash extends BaseMultiCommitOperation {
protected onBeginOperation = () => {
const { repository, dispatcher, state } = this.props
const { operationDetail } = state
@ -28,64 +29,4 @@ export abstract class Squash extends BaseMultiCommitOperation {
true
)
}
protected onContinueAfterConflicts = async (): Promise<void> => {
const {
repository,
dispatcher,
workingDirectory,
state,
conflictState,
} = this.props
const { operationDetail, targetBranch, originalBranchTip } = state
if (
conflictState === null ||
targetBranch === null ||
originalBranchTip === null ||
operationDetail.kind !== MultiCommitOperationKind.Squash
) {
this.endFlowInvalidState()
return
}
const { commits, currentTip } = operationDetail
await dispatcher.switchMultiCommitOperationToShowProgress(repository)
const rebaseConflictState: RebaseConflictState = {
kind: 'rebase',
currentTip,
targetBranch: targetBranch.name,
baseBranch: undefined,
originalBranchTip,
baseBranchTip: currentTip,
manualResolutions: conflictState.manualResolutions,
}
const rebaseResult = await dispatcher.continueRebase(
MultiCommitOperationKind.Squash,
repository,
workingDirectory,
rebaseConflictState
)
return dispatcher.processMultiCommitOperationRebaseResult(
MultiCommitOperationKind.Squash,
repository,
rebaseResult,
commits.length + 1,
targetBranch.name
)
}
protected onAbort = async (): Promise<void> => {
const { repository, dispatcher } = this.props
this.onFlowEnded()
return dispatcher.abortRebase(repository)
}
protected onConflictsDialogDismissed = () => {
this.onInvokeConflictsDialogDismissed('squashing commits on')
}
}