diff --git a/package.json b/package.json index 121adffe67..2e048810e4 100644 --- a/package.json +++ b/package.json @@ -711,6 +711,21 @@ "default": "on", "markdownDescription": "%githubIssues.useBranchForIssues.markdownDescription%" }, + "githubIssues.workingBaseBranch": { + "type": "string", + "enum": [ + "currentBranch", + "defaultBranch", + "prompt" + ], + "enumDescriptions": [ + "%githubIssues.workingBaseBranch.currentBranch%", + "%githubIssues.workingBaseBranch.defaultBranch%", + "%githubIssues.workingBaseBranch.prompt%" + ], + "default": "currentBranch", + "markdownDescription": "%githubIssues.workingBaseBranch.markdownDescription%" + }, "githubIssues.issueCompletionFormatScm": { "type": "string", "default": "${issueTitle}\nFixes ${issueNumberLabel}", diff --git a/package.nls.json b/package.nls.json index 73c02b7684..becdc0583d 100644 --- a/package.nls.json +++ b/package.nls.json @@ -130,6 +130,15 @@ "githubIssues.useBranchForIssues.on": "A branch will always be checked out when you start working on an issue. If the branch doesn't exist, it will be created.", "githubIssues.useBranchForIssues.off": "A branch will not be created when you start working on an issue. If you have worked on an issue before and a branch was created for it, that same branch will be checked out.", "githubIssues.useBranchForIssues.prompt": "A prompt will show for setting the name of the branch that will be created and checked out.", + "githubIssues.workingBaseBranch.markdownDescription": { + "message": "Determines which branch to use as the base when creating a new branch for an issue. This setting controls what branch the new issue branch is created from.", + "comment": [ + "Describes the base branch selection for issue branches" + ] + }, + "githubIssues.workingBaseBranch.currentBranch": "Create the issue branch from the current branch without switching to the default branch first.", + "githubIssues.workingBaseBranch.defaultBranch": "Always switch to the default branch before creating the issue branch.", + "githubIssues.workingBaseBranch.prompt": "Prompt which branch to use as the base when creating an issue branch.", "githubIssues.issueCompletionFormatScm.markdownDescription": { "message": "Sets the format of issue completions in the SCM inputbox. \n- `${user}` will be replace with the currently logged in username \n- `${issueNumber}` will be replaced with the current issue number \n- `${issueNumberLabel}` will be replaced with a label formatted as #number or owner/repository#number, depending on whether the issue is in the current repository", "comment": [ diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index 71520fa1ec..aa7001a3d2 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -105,6 +105,7 @@ declare module 'vscode' { isComplete?: boolean; toolSpecificData?: ChatTerminalToolInvocationData; fromSubAgent?: boolean; + presentation?: 'hidden' | 'hiddenAfterComplete' | undefined; constructor(toolName: string, toolCallId: string, isError?: boolean); } diff --git a/src/common/settingKeys.ts b/src/common/settingKeys.ts index 1376c4c7bc..f1ec323578 100644 --- a/src/common/settingKeys.ts +++ b/src/common/settingKeys.ts @@ -49,6 +49,7 @@ export const IGNORE_USER_COMPLETION_TRIGGER = 'ignoreUserCompletionTrigger'; export const CREATE_INSERT_FORMAT = 'createInsertFormat'; export const ISSUE_BRANCH_TITLE = 'issueBranchTitle'; export const USE_BRANCH_FOR_ISSUES = 'useBranchForIssues'; +export const WORKING_BASE_BRANCH = 'workingBaseBranch'; export const WORKING_ISSUE_FORMAT_SCM = 'workingIssueFormatScm'; export const IGNORE_COMPLETION_TRIGGER = 'ignoreCompletionTrigger'; export const ISSUE_COMPLETION_FORMAT_SCM = 'issueCompletionFormatScm'; diff --git a/src/issues/issueFeatureRegistrar.ts b/src/issues/issueFeatureRegistrar.ts index a4f253a57d..8acf1385e2 100644 --- a/src/issues/issueFeatureRegistrar.ts +++ b/src/issues/issueFeatureRegistrar.ts @@ -20,6 +20,7 @@ import { ISSUE_COMPLETIONS, ISSUES_SETTINGS_NAMESPACE, USER_COMPLETIONS, + WORKING_BASE_BRANCH, } from '../common/settingKeys'; import { editQuery } from '../common/settingsUtils'; import { ITelemetry } from '../common/telemetry'; @@ -809,7 +810,7 @@ export class IssueFeatureRegistrar extends Disposable { let githubRepository = issueModel.githubRepository; let remote = issueModel.remote; if (!repoManager) { - repoManager = await this.chooseRepo(vscode.l10n.t('Choose which repository you want to work on this isssue in.')); + repoManager = await this.chooseRepo(vscode.l10n.t('Choose which repository you want to work on this issue in.')); if (!repoManager) { return; } @@ -824,10 +825,40 @@ export class IssueFeatureRegistrar extends Disposable { } } + // Determine whether to checkout the default branch based on workingBaseBranch setting + const workingBaseBranchConfig = vscode.workspace.getConfiguration(ISSUES_SETTINGS_NAMESPACE).get(WORKING_BASE_BRANCH); + let checkoutDefaultBranch = false; + + if (workingBaseBranchConfig === 'defaultBranch') { + checkoutDefaultBranch = true; + } else if (workingBaseBranchConfig === 'prompt') { + const currentBranchName = repoManager.repository.state.HEAD?.name; + const defaults = await repoManager.getPullRequestDefaults(); + const defaultBranchName = defaults.base; + + if (!currentBranchName) { + // If we can't determine the current branch, default to the default branch + checkoutDefaultBranch = true; + } else if (currentBranchName === defaultBranchName) { + // If already on the default branch, no need to prompt + checkoutDefaultBranch = false; + } else { + const choice = await vscode.window.showQuickPick([currentBranchName, defaultBranchName], { + placeHolder: vscode.l10n.t('Which branch should be used as the base for the new issue branch?'), + }); + if (choice === undefined) { + // User cancelled the prompt + return; + } + checkoutDefaultBranch = choice === defaultBranchName; + } + } + // else workingBaseBranchConfig === 'currentBranch', checkoutDefaultBranch remains false + await this._stateManager.setCurrentIssue( repoManager, new CurrentIssue(issueModel, repoManager, this._stateManager, remoteNameResult.remote, needsBranchPrompt), - true + checkoutDefaultBranch ); }