diff --git a/src/commands/git/merge.ts b/src/commands/git/merge.ts index a8bd120..d12c080 100644 --- a/src/commands/git/merge.ts +++ b/src/commands/git/merge.ts @@ -24,6 +24,7 @@ interface Context { cache: Map>; destination: GitBranch; pickCommit: boolean; + pickCommitForItem: boolean; selectedBranchOrTag: GitReference | undefined; showTags: boolean; title: string; @@ -80,6 +81,7 @@ export class MergeGitCommand extends QuickCommand { cache: new Map>(), destination: undefined!, pickCommit: false, + pickCommitForItem: false, selectedBranchOrTag: undefined, showTags: true, title: this.title, @@ -120,6 +122,7 @@ export class MergeGitCommand extends QuickCommand { } context.title = `${this.title} into ${GitReference.toString(context.destination, { icon: false })}`; + context.pickCommitForItem = false; if (state.counter < 2 || state.reference == null) { const pickCommitToggle = new QuickCommandButtons.PickCommitToggle(context.pickCommit, context, () => { @@ -153,7 +156,7 @@ export class MergeGitCommand extends QuickCommand { if ( state.counter < 3 && context.selectedBranchOrTag != null && - (context.pickCommit || state.reference.ref === context.destination.ref) + (context.pickCommit || context.pickCommitForItem || state.reference.ref === context.destination.ref) ) { const ref = context.selectedBranchOrTag.ref; diff --git a/src/commands/git/rebase.ts b/src/commands/git/rebase.ts index a6d6156..4e288d0 100644 --- a/src/commands/git/rebase.ts +++ b/src/commands/git/rebase.ts @@ -25,6 +25,7 @@ interface Context { cache: Map>; destination: GitBranch; pickCommit: boolean; + pickCommitForItem: boolean; selectedBranchOrTag: GitReference | undefined; showTags: boolean; title: string; @@ -101,6 +102,7 @@ export class RebaseGitCommand extends QuickCommand { cache: new Map>(), destination: undefined!, pickCommit: false, + pickCommitForItem: false, selectedBranchOrTag: undefined, showTags: true, title: this.title, @@ -141,6 +143,7 @@ export class RebaseGitCommand extends QuickCommand { } context.title = `${this.title} ${GitReference.toString(context.destination, { icon: false })}`; + context.pickCommitForItem = false; if (state.counter < 2 || state.reference == null) { const pickCommitToggle = new QuickCommandButtons.PickCommitToggle(context.pickCommit, context, () => { @@ -174,7 +177,7 @@ export class RebaseGitCommand extends QuickCommand { if ( state.counter < 3 && context.selectedBranchOrTag != null && - (context.pickCommit || state.reference.ref === context.destination.ref) + (context.pickCommit || context.pickCommitForItem || state.reference.ref === context.destination.ref) ) { const ref = context.selectedBranchOrTag.ref; diff --git a/src/commands/gitCommands.ts b/src/commands/gitCommands.ts index 8529d91..44fdebd 100644 --- a/src/commands/gitCommands.ts +++ b/src/commands/gitCommands.ts @@ -468,9 +468,11 @@ export class GitCommandsCommand extends Command { disposables.push( scope, quickpick.onDidHide(() => resolve(undefined)), - quickpick.onDidTriggerItemButton(async e => - step.onDidClickItemButton?.(quickpick, e.button, e.item), - ), + quickpick.onDidTriggerItemButton(async e => { + if ((await step.onDidClickItemButton?.(quickpick, e.button, e.item)) === true) { + resolve(await this.nextStep(quickpick, commandsStep.command!, [e.item])); + } + }), quickpick.onDidTriggerButton(async e => { if (e === QuickInputButtons.Back) { void goBack(); diff --git a/src/commands/quickCommand.buttons.ts b/src/commands/quickCommand.buttons.ts index c02ee6b..04fb0b5 100644 --- a/src/commands/quickCommand.buttons.ts +++ b/src/commands/quickCommand.buttons.ts @@ -38,10 +38,7 @@ export class ToggleQuickInputButton implements QuickInputButton { } /** - * - * @param quickInput * @returns `true` if the step should be retried (refreshed) - * */ onDidClick?(quickInput: QuickInput): boolean | void | Promise; @@ -89,6 +86,11 @@ export namespace QuickCommandButtons { } }; + export const PickCommit: QuickInputButton = { + iconPath: new ThemeIcon('git-commit'), + tooltip: 'Choose a Specific Commit', + }; + export const PickCommitToggle = class extends ToggleQuickInputButton { constructor(on = false, context: { showTags: boolean }, onDidClick?: (quickInput: QuickInput) => void) { super( diff --git a/src/commands/quickCommand.steps.ts b/src/commands/quickCommand.steps.ts index 8c113e2..0900437 100644 --- a/src/commands/quickCommand.steps.ts +++ b/src/commands/quickCommand.steps.ts @@ -563,7 +563,7 @@ export async function* pickBranchesStep< export async function* pickBranchOrTagStep< State extends PartialStepState & { repo: Repository }, - Context extends { repos: Repository[]; showTags?: boolean; title: string }, + Context extends { repos: Repository[]; pickCommitForItem?: boolean; showTags?: boolean; title: string }, >( state: State, context: Context, @@ -591,7 +591,10 @@ export async function* pickBranchOrTagStep< const getBranchesAndOrTagsFn = async () => { return getBranchesAndOrTags(state.repo, context.showTags ? ['branches', 'tags'] : ['branches'], { - buttons: [QuickCommandButtons.RevealInSideBar], + buttons: + typeof context.pickCommitForItem === 'boolean' + ? [QuickCommandButtons.PickCommit, QuickCommandButtons.RevealInSideBar] + : [QuickCommandButtons.RevealInSideBar], filter: filter, picked: picked, sort: true, @@ -616,6 +619,11 @@ export async function* pickBranchOrTagStep< : branchesAndOrTags, additionalButtons: [...(additionalButtons ?? []), showTagsButton], onDidClickItemButton: (quickpick, button, { item }) => { + if (button === QuickCommandButtons.PickCommit) { + context.pickCommitForItem = true; + return true; + } + if (button === QuickCommandButtons.RevealInSideBar) { if (GitReference.isBranch(item)) { void GitActions.Branch.reveal(item, { select: true, expand: true }); @@ -625,6 +633,7 @@ export async function* pickBranchOrTagStep< void GitActions.Commit.reveal(item, { select: true, expand: true }); } } + return false; }, onDidClickButton: async (quickpick, button) => { if (button === showTagsButton) { diff --git a/src/commands/quickCommand.ts b/src/commands/quickCommand.ts index fecbfee..cee8f04 100644 --- a/src/commands/quickCommand.ts +++ b/src/commands/quickCommand.ts @@ -46,7 +46,14 @@ export interface QuickPickStep { onDidAccept?(quickpick: QuickPick): boolean | Promise; onDidChangeValue?(quickpick: QuickPick): boolean | Promise; onDidClickButton?(quickpick: QuickPick, button: QuickInputButton): boolean | void | Promise; - onDidClickItemButton?(quickpick: QuickPick, button: QuickInputButton, item: T): void | Promise; + /** + * @returns `true` if the current item should be selected + */ + onDidClickItemButton?( + quickpick: QuickPick, + button: QuickInputButton, + item: T, + ): boolean | void | Promise; onDidLoadMore?(quickpick: QuickPick): (DirectiveQuickPickItem | T)[] | Promise<(DirectiveQuickPickItem | T)[]>; onDidPressKey?(quickpick: QuickPick, key: Keys): void | Promise; onValidateValue?(quickpick: QuickPick, value: string, items: T[]): boolean | Promise;