Skip to content

Commit f6030a4

Browse files
dvsergeibbb
authored andcommitted
Lets user reset their choice of Merge Target
(#4224, #4258)
1 parent 32c8c23 commit f6030a4

File tree

5 files changed

+104
-14
lines changed

5 files changed

+104
-14
lines changed

src/commands/changeUserDefinedMergeBase.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { Repository } from '../git/models/repository';
44
import type { ViewsWithRepositoryFolders } from '../views/viewBase';
55
import type { PartialStepState, StepGenerator, StepState } from './quickCommand';
66
import { endSteps, QuickCommand, StepResultBreak } from './quickCommand';
7-
import { pickBranchOrTagStep, pickBranchStep, pickRepositoryStep } from './quickCommand.steps';
7+
import { pickBranchStep, pickOrResetBranchStep, pickRepositoryStep } from './quickCommand.steps';
88

99
interface Context {
1010
repos: Repository[];
@@ -84,22 +84,30 @@ export class ChangeUserDefinedMergeBaseCommand extends QuickCommand {
8484
state.branch = branches.name;
8585
}
8686

87-
const result = yield* pickBranchOrTagStep(state, context, {
87+
if (!state.mergeBranch) {
88+
state.mergeBranch = await this.container.git
89+
.branches(state.repo.path)
90+
.getBaseBranchName?.(state.branch);
91+
}
92+
93+
const detectedMergeTarget = await this.container.git
94+
.branches(state.repo.path)
95+
.getBaseBranchName?.(state.branch, true);
96+
97+
const result = yield* pickOrResetBranchStep(state, context, {
8898
picked: state.mergeBranch,
8999
placeholder: 'Pick a merge target branch',
90-
value: undefined,
91-
filter: {
92-
branches: (branch: GitBranch) => branch.remote && branch.name !== state.branch,
93-
tags: () => false,
94-
},
100+
filter: (branch: GitBranch) => branch.remote && branch.name !== state.branch,
101+
resetTitle: 'Reset Merge Target',
102+
resetDescription: `Reset to "${detectedMergeTarget}"`,
95103
});
96104
if (result === StepResultBreak) {
97105
continue;
98106
}
99-
if (result && state.branch) {
107+
if (state.branch) {
100108
await this.container.git
101109
.branches(state.repo.path)
102-
.setUserDefinedBaseBranchName?.(state.branch, result.name);
110+
.setUserDefinedBaseBranchName?.(state.branch, result?.name);
103111
}
104112

105113
endSteps(state);

src/commands/quickCommand.steps.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,84 @@ export function* pickBranchStep<
783783
return canPickStepContinue(step, state, selection) ? selection[0].item : StepResultBreak;
784784
}
785785

786+
export function* pickOrResetBranchStep<
787+
State extends PartialStepState & { repo: Repository },
788+
Context extends { repos: Repository[]; showTags?: boolean; title: string },
789+
>(
790+
state: State,
791+
context: Context,
792+
{
793+
filter,
794+
picked,
795+
placeholder,
796+
title,
797+
resetTitle,
798+
resetDescription,
799+
}: {
800+
filter?: (b: GitBranch) => boolean;
801+
picked?: string | string[];
802+
placeholder: string;
803+
title?: string;
804+
resetTitle: string;
805+
resetDescription: string;
806+
},
807+
): StepResultGenerator<GitBranchReference | undefined> {
808+
const items = getBranches(state.repo, {
809+
buttons: [RevealInSideBarQuickInputButton],
810+
filter: filter,
811+
picked: picked,
812+
}).then(branches =>
813+
branches.length === 0
814+
? [createDirectiveQuickPickItem(Directive.Back, true), createDirectiveQuickPickItem(Directive.Cancel)]
815+
: [
816+
createDirectiveQuickPickItem(Directive.Reset, false, {
817+
label: resetTitle,
818+
description: resetDescription,
819+
}),
820+
...branches,
821+
],
822+
);
823+
824+
const resetButton: QuickInputButton = {
825+
iconPath: new ThemeIcon('notebook-revert'),
826+
tooltip: resetDescription,
827+
};
828+
let resetButtonClicked = false;
829+
const step = createPickStep<BranchQuickPickItem>({
830+
title: appendReposToTitle(title ?? context.title, state, context),
831+
placeholder: count => (!count ? `No branches found in ${state.repo.formattedName}` : placeholder),
832+
matchOnDetail: true,
833+
items: items,
834+
additionalButtons: [resetButton],
835+
onDidClickButton: (_quickpick, button) => {
836+
if (button === resetButton) {
837+
resetButtonClicked = true;
838+
return true;
839+
}
840+
return false;
841+
},
842+
onDidClickItemButton: (_quickpick, button, { item }) => {
843+
if (button === RevealInSideBarQuickInputButton) {
844+
void BranchActions.reveal(item, { select: true, focus: false, expand: true });
845+
}
846+
},
847+
keys: ['right', 'alt+right', 'ctrl+right'],
848+
onDidPressKey: async (_quickpick, _key, { item }) => {
849+
await BranchActions.reveal(item, {
850+
select: true,
851+
focus: false,
852+
expand: true,
853+
});
854+
},
855+
});
856+
857+
const selection: StepSelection<typeof step> = yield step;
858+
if (resetButtonClicked) {
859+
return undefined;
860+
}
861+
return canPickStepContinue(step, state, selection) ? selection[0].item : StepResultBreak;
862+
}
863+
786864
export function* pickBranchesStep<
787865
State extends PartialStepState & { repo: Repository },
788866
Context extends { repos: Repository[]; showTags?: boolean; title: string },

src/env/node/git/sub-providers/branches.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
574574
}
575575

576576
@log({ exit: true })
577-
async getBaseBranchName(repoPath: string, ref: string): Promise<string | undefined> {
577+
async getBaseBranchName(repoPath: string, ref: string, detectedOnly?: boolean): Promise<string | undefined> {
578578
try {
579579
const pattern = `^branch\\.${ref}\\.`;
580580
const data = await this.git.config__get_regex(pattern, repoPath);
@@ -592,7 +592,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
592592
if (match == null) break;
593593

594594
const [, key, value] = match;
595-
if (key === 'gk-user-defined-merge-base' && gkUserPriority <= priority) {
595+
if (!detectedOnly && key === 'gk-user-defined-merge-base' && gkUserPriority <= priority) {
596596
mergeBase = value;
597597
update = false;
598598
} else if (key === 'gk-merge-base' && gkDetectedPriority <= priority) {
@@ -633,7 +633,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
633633
}
634634

635635
@log()
636-
async setUserDefinedBaseBranchName(repoPath: string, ref: string, base: string): Promise<void> {
636+
async setUserDefinedBaseBranchName(repoPath: string, ref: string, base: string | undefined): Promise<void> {
637637
const mergeBaseConfigKey: GitConfigKeys = `branch.${ref}.gk-user-defined-merge-base`;
638638
await this.provider.config.setConfig(repoPath, mergeBaseConfigKey, base);
639639
}

src/git/gitProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,9 @@ export interface GitBranchesSubProvider {
254254
branch: string,
255255
targetBranch: string,
256256
): Promise<MergeConflict | undefined>;
257-
getBaseBranchName?(repoPath: string, ref: string): Promise<string | undefined>;
257+
getBaseBranchName?(repoPath: string, ref: string, detectedOnly?: boolean): Promise<string | undefined>;
258258
setBaseBranchName?(repoPath: string, ref: string, base: string): Promise<void>;
259-
setUserDefinedBaseBranchName?(repoPath: string, ref: string, base: string): Promise<void>;
259+
setUserDefinedBaseBranchName?(repoPath: string, ref: string, base: string | undefined): Promise<void>;
260260
getTargetBranchName?(repoPath: string, ref: string): Promise<string | undefined>;
261261
setTargetBranchName?(repoPath: string, ref: string, target: string): Promise<void>;
262262
renameBranch?(repoPath: string, oldName: string, newName: string): Promise<void>;

src/quickpicks/items/directive.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { pluralize } from '../../system/string';
55
export enum Directive {
66
Back,
77
Cancel,
8+
Reset,
89
LoadMore,
910
Noop,
1011
Reload,
@@ -57,6 +58,9 @@ export function createDirectiveQuickPickItem(
5758
case Directive.Reload:
5859
label = 'Refresh';
5960
break;
61+
case Directive.Reset:
62+
label = 'Reset';
63+
break;
6064
case Directive.SignIn:
6165
label = 'Sign In';
6266
break;

0 commit comments

Comments
 (0)