From 13585b23b37e3abfc4f82f9c772e3aaa5d528358 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Thu, 16 Feb 2023 01:23:02 -0500 Subject: [PATCH] Changes PR worktree create to open if possible Aligns worktree open prompting using quick picks --- CHANGELOG.md | 3 +- package.json | 8 +- src/commands.ts | 2 +- src/commands/ghpr/createWorktree.ts | 136 ---------------------------- src/commands/ghpr/openOrCreateWorktree.ts | 144 ++++++++++++++++++++++++++++++ src/commands/git/worktree.ts | 120 ++++++++++++------------- src/commands/quickCommand.steps.ts | 6 +- src/constants.ts | 3 +- src/git/actions/worktree.ts | 38 +++++++- src/views/viewCommands.ts | 4 +- 10 files changed, 249 insertions(+), 215 deletions(-) delete mode 100644 src/commands/ghpr/createWorktree.ts create mode 100644 src/commands/ghpr/openOrCreateWorktree.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 76d9499..37f3cdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Adds a `worktrees.openAfterCreate` setting to specify how and when to open a worktree after it is created - Ensures new worktrees are created from the "main" repo, if already in a worktree - Adds a new _remote_ command to the _Git Command Palette_ to add, prune, and remove remotes -- Adds a _Create Worktree for Pull Request via GitLens..._ context menu command on pull requests in the _GitHub Pull Requests and Issues_ extension's views +- Adds a _Open Worktree for Pull Request via GitLens..._ context menu command on pull requests in the _GitHub Pull Requests and Issues_ extension's views + - Opens an associated worktree, if one exists, otherwise it creates a new worktree for the pull request - Adds settings to control the format of commits in the GitLens views ### Changed diff --git a/package.json b/package.json index 89dce51..0fc2666 100644 --- a/package.json +++ b/package.json @@ -5571,8 +5571,8 @@ "enablement": "!operationInProgress" }, { - "command": "gitlens.ghpr.views.createWorktree", - "title": "Create Worktree for Pull Request via GitLens...", + "command": "gitlens.ghpr.views.openOrCreateWorktree", + "title": "Open Worktree for Pull Request via GitLens...", "category": "GitLens", "enablement": "!operationInProgress" }, @@ -8064,7 +8064,7 @@ "when": "false" }, { - "command": "gitlens.ghpr.views.createWorktree", + "command": "gitlens.ghpr.views.openOrCreateWorktree", "when": "false" }, { @@ -11483,7 +11483,7 @@ "group": "1_gitlens@0" }, { - "command": "gitlens.ghpr.views.createWorktree", + "command": "gitlens.ghpr.views.openOrCreateWorktree", "when": "!gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && view == pr:github && viewItem =~ /pullrequest(:local)?:nonactive|description/", "group": "pullrequest@2" } diff --git a/src/commands.ts b/src/commands.ts index bf07659..07b9d88 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -17,7 +17,7 @@ export * from './commands/diffWithRevision'; export * from './commands/diffWithRevisionFrom'; export * from './commands/diffWithWorking'; export * from './commands/externalDiff'; -export * from './commands/ghpr/createWorktree'; +export * from './commands/ghpr/openOrCreateWorktree'; export * from './commands/gitCommands'; export * from './commands/inviteToLiveShare'; export * from './commands/logging'; diff --git a/src/commands/ghpr/createWorktree.ts b/src/commands/ghpr/createWorktree.ts deleted file mode 100644 index 9571843..0000000 --- a/src/commands/ghpr/createWorktree.ts +++ /dev/null @@ -1,136 +0,0 @@ -import type { Uri } from 'vscode'; -import { window } from 'vscode'; -import { Commands } from '../../constants'; -import type { Container } from '../../container'; -import { add as addRemote } from '../../git/actions/remote'; -import { create as createWorktree } from '../../git/actions/worktree'; -import { GitReference } from '../../git/models/reference'; -import type { GitRemote } from '../../git/models/remote'; -import { parseGitRemoteUrl } from '../../git/parsers/remoteParser'; -import { Logger } from '../../logger'; -import { command } from '../../system/command'; -import { waitUntilNextTick } from '../../system/promise'; -import { Command } from '../base'; - -interface PullRequestNode { - readonly pullRequestModel: PullRequest; -} - -interface PullRequest { - readonly base: { - readonly repositoryCloneUrl: { - readonly owner: string; - readonly repositoryName: string; - }; - }; - readonly githubRepository: { - readonly rootUri: Uri; - }; - readonly head: { - readonly ref: string; - readonly sha: string; - readonly repositoryCloneUrl: { - readonly owner: string; - readonly url: Uri; - }; - }; - - readonly item: { - readonly number: number; - }; -} - -@command() -export class CreateWorktreeCommand extends Command { - constructor(private readonly container: Container) { - super(Commands.CreateWorktreeForGHPR); - } - - async execute(...args: [PullRequestNode | PullRequest, ...unknown[]]) { - const [arg] = args; - let pr; - if ('pullRequestModel' in arg) { - pr = arg.pullRequestModel; - } else { - pr = arg; - } - - const { - base: { - repositoryCloneUrl: { owner: rootOwner, repositoryName: rootRepository }, - }, - githubRepository: { rootUri }, - head: { - repositoryCloneUrl: { url: remoteUri, owner: remoteOwner }, - ref, - }, - item: { number }, - } = pr; - - let repo = this.container.git.getRepository(rootUri); - if (repo == null) { - void window.showWarningMessage(`Unable to find repository(${rootUri.toString()}) for PR #${number}`); - return; - } - - repo = await repo.getMainRepository(); - if (repo == null) { - void window.showWarningMessage(`Unable to find main repository(${rootUri.toString()}) for PR #${number}`); - return; - } - - const remoteUrl = remoteUri.toString(); - const [, remoteDomain, remotePath] = parseGitRemoteUrl(remoteUrl); - - let remote: GitRemote | undefined; - [remote] = await repo.getRemotes({ filter: r => r.matches(remoteDomain, remotePath) }); - if (remote == null) { - const result = await window.showInformationMessage( - `Unable to find a remote for '${remoteUrl}'. Would you like to add a new remote?`, - { modal: true }, - { title: 'Yes' }, - { title: 'No', isCloseAffordance: true }, - ); - if (result?.title !== 'Yes') return; - - await addRemote(repo, remoteOwner, remoteUrl, { - confirm: false, - fetch: true, - reveal: false, - }); - [remote] = await repo.getRemotes({ filter: r => r.url === remoteUrl }); - if (remote == null) return; - } else { - await this.container.git.fetch(repo.path, { remote: remote.name }); - } - - await waitUntilNextTick(); - - try { - await createWorktree( - repo, - undefined, - GitReference.create(`${remote.name}/${ref}`, repo.path, { - refType: 'branch', - name: `${remote.name}/${ref}`, - remote: true, - }), - ); - - // Ensure that the worktree was created - const worktree = await this.container.git.getWorktree(repo.path, w => w.branch === ref); - if (worktree == null) return; - - // Save the PR number in the branch config - // https://github.com/Microsoft/vscode-pull-request-github/blob/0c556c48c69a3df2f9cf9a45ed2c40909791b8ab/src/github/pullRequestGitHelper.ts#L18 - void this.container.git.setConfig( - repo.path, - `branch.${ref}.github-pr-owner-number`, - `${rootOwner}#${rootRepository}#${number}`, - ); - } catch (ex) { - Logger.error(ex, 'CreateWorktreeCommand', 'Unable to create worktree'); - void window.showErrorMessage(`Unable to create worktree for ${ref}`); - } - } -} diff --git a/src/commands/ghpr/openOrCreateWorktree.ts b/src/commands/ghpr/openOrCreateWorktree.ts new file mode 100644 index 0000000..2b0fc12 --- /dev/null +++ b/src/commands/ghpr/openOrCreateWorktree.ts @@ -0,0 +1,144 @@ +import type { Uri } from 'vscode'; +import { window } from 'vscode'; +import { Commands } from '../../constants'; +import type { Container } from '../../container'; +import { add as addRemote } from '../../git/actions/remote'; +import { create as createWorktree, open as openWorktree } from '../../git/actions/worktree'; +import { GitReference } from '../../git/models/reference'; +import type { GitRemote } from '../../git/models/remote'; +import { parseGitRemoteUrl } from '../../git/parsers/remoteParser'; +import { Logger } from '../../logger'; +import { command } from '../../system/command'; +import { waitUntilNextTick } from '../../system/promise'; +import { Command } from '../base'; + +interface PullRequestNode { + readonly pullRequestModel: PullRequest; +} + +interface PullRequest { + readonly base: { + readonly repositoryCloneUrl: { + readonly owner: string; + readonly repositoryName: string; + }; + }; + readonly githubRepository: { + readonly rootUri: Uri; + }; + readonly head: { + readonly ref: string; + readonly sha: string; + readonly repositoryCloneUrl: { + readonly owner: string; + readonly url: Uri; + }; + }; + + readonly item: { + readonly number: number; + }; +} + +@command() +export class OpenOrCreateWorktreeCommand extends Command { + constructor(private readonly container: Container) { + super(Commands.OpenOrCreateWorktreeForGHPR); + } + + async execute(...args: [PullRequestNode | PullRequest, ...unknown[]]) { + const [arg] = args; + let pr; + if ('pullRequestModel' in arg) { + pr = arg.pullRequestModel; + } else { + pr = arg; + } + + const { + base: { + repositoryCloneUrl: { owner: rootOwner, repositoryName: rootRepository }, + }, + githubRepository: { rootUri }, + head: { + repositoryCloneUrl: { url: remoteUri, owner: remoteOwner }, + ref, + }, + item: { number }, + } = pr; + + let repo = this.container.git.getRepository(rootUri); + if (repo == null) { + void window.showWarningMessage(`Unable to find repository(${rootUri.toString()}) for PR #${number}`); + return; + } + + repo = await repo.getMainRepository(); + if (repo == null) { + void window.showWarningMessage(`Unable to find main repository(${rootUri.toString()}) for PR #${number}`); + return; + } + + const worktrees = await repo.getWorktrees(); + const worktree = worktrees.find(w => w.branch === ref); + if (worktree != null) { + void openWorktree(worktree); + + return; + } + + const remoteUrl = remoteUri.toString(); + const [, remoteDomain, remotePath] = parseGitRemoteUrl(remoteUrl); + + let remote: GitRemote | undefined; + [remote] = await repo.getRemotes({ filter: r => r.matches(remoteDomain, remotePath) }); + if (remote == null) { + const result = await window.showInformationMessage( + `Unable to find a remote for '${remoteUrl}'. Would you like to add a new remote?`, + { modal: true }, + { title: 'Yes' }, + { title: 'No', isCloseAffordance: true }, + ); + if (result?.title !== 'Yes') return; + + await addRemote(repo, remoteOwner, remoteUrl, { + confirm: false, + fetch: true, + reveal: false, + }); + [remote] = await repo.getRemotes({ filter: r => r.url === remoteUrl }); + if (remote == null) return; + } else { + await this.container.git.fetch(repo.path, { remote: remote.name }); + } + + await waitUntilNextTick(); + + try { + await createWorktree( + repo, + undefined, + GitReference.create(`${remote.name}/${ref}`, repo.path, { + refType: 'branch', + name: `${remote.name}/${ref}`, + remote: true, + }), + ); + + // Ensure that the worktree was created + const worktree = await this.container.git.getWorktree(repo.path, w => w.branch === ref); + if (worktree == null) return; + + // Save the PR number in the branch config + // https://github.com/Microsoft/vscode-pull-request-github/blob/0c556c48c69a3df2f9cf9a45ed2c40909791b8ab/src/github/pullRequestGitHelper.ts#L18 + void this.container.git.setConfig( + repo.path, + `branch.${ref}.github-pr-owner-number`, + `${rootOwner}#${rootRepository}#${number}`, + ); + } catch (ex) { + Logger.error(ex, 'CreateWorktreeCommand', 'Unable to create worktree'); + void window.showErrorMessage(`Unable to create worktree for ${ref}`); + } + } +} diff --git a/src/commands/git/worktree.ts b/src/commands/git/worktree.ts index eff4b99..1fa8cbf 100644 --- a/src/commands/git/worktree.ts +++ b/src/commands/git/worktree.ts @@ -1,10 +1,10 @@ import type { MessageItem } from 'vscode'; -import { QuickInputButtons, Uri, window } from 'vscode'; +import { QuickInputButtons, Uri, window, workspace } from 'vscode'; import type { Config } from '../../configuration'; import { configuration } from '../../configuration'; import type { Container } from '../../container'; import { PlusFeatures } from '../../features'; -import { open, reveal, revealInFileExplorer } from '../../git/actions/worktree'; +import { convertOpenFlagsToLocation, reveal, revealInFileExplorer } from '../../git/actions/worktree'; import { WorktreeCreateError, WorktreeCreateErrorReason, @@ -22,7 +22,7 @@ import type { FlagsQuickPickItem } from '../../quickpicks/items/flags'; import { createFlagsQuickPickItem } from '../../quickpicks/items/flags'; import { basename, isDescendent } from '../../system/path'; import { pluralize, truncateLeft } from '../../system/string'; -import { OpenWorkspaceLocation } from '../../system/utils'; +import { openWorkspace, OpenWorkspaceLocation } from '../../system/utils'; import type { ViewsWithRepositoryFolders } from '../../views/viewBase'; import type { AsyncStepResultGenerator, @@ -85,7 +85,7 @@ interface DeleteState { flags: DeleteFlags[]; } -type OpenFlags = '--new-window' | '--reveal-explorer'; +type OpenFlags = '--add-to-workspace' | '--new-window' | '--reveal-explorer'; interface OpenState { subcommand: 'open'; @@ -385,8 +385,9 @@ export class WorktreeGitCommand extends QuickCommand { ...(state.createBranch ?? state.reference.name).replace(/\\/g, '/').split('/'), ); + let worktree: GitWorktree | undefined; try { - const worktree = await state.repo.createWorktree(uri, { + worktree = await state.repo.createWorktree(uri, { commitish: state.reference?.name, createBranch: state.flags.includes('-b') ? state.createBranch : undefined, detach: state.flags.includes('--detach'), @@ -399,55 +400,6 @@ export class WorktreeGitCommand extends QuickCommand { focus: true, }); } - - if (worktree == null) return; - - type OpenAction = Config['worktrees']['openAfterCreate'] | 'addToWorkspace'; - let action: OpenAction = configuration.get('worktrees.openAfterCreate'); - if (action === 'never') return; - - queueMicrotask(async () => { - if (action === 'prompt') { - type ActionMessageItem = MessageItem & { action: OpenAction }; - const open: ActionMessageItem = { title: 'Open', action: 'always' }; - const openNewWindow: ActionMessageItem = { - title: 'Open in New Window', - action: 'alwaysNewWindow', - }; - const addToWorkspace: ActionMessageItem = { - title: 'Add to Workspace', - action: 'addToWorkspace', - }; - const cancel: ActionMessageItem = { title: 'Cancel', isCloseAffordance: true, action: 'never' }; - - const result = await window.showInformationMessage( - `Would you like to open the new worktree, or add it to the current workspace?`, - { modal: true }, - open, - openNewWindow, - addToWorkspace, - cancel, - ); - - action = result?.action ?? 'never'; - } - - switch (action) { - case 'always': - open(worktree, { - location: OpenWorkspaceLocation.CurrentWindow, - }); - break; - case 'alwaysNewWindow': - open(worktree, { location: OpenWorkspaceLocation.NewWindow }); - break; - case 'addToWorkspace': - open(worktree, { - location: OpenWorkspaceLocation.AddToWorkspace, - }); - break; - } - }); } catch (ex) { if ( WorktreeCreateError.is(ex, WorktreeCreateErrorReason.AlreadyCheckedOut) && @@ -495,6 +447,44 @@ export class WorktreeGitCommand extends QuickCommand { } endSteps(state); + if (worktree == null) break; + + type OpenAction = Config['worktrees']['openAfterCreate']; + const action: OpenAction = configuration.get('worktrees.openAfterCreate'); + if (action === 'never') break; + + if (action === 'prompt') { + yield* this.openCommandSteps( + { + subcommand: 'open', + repo: state.repo, + uri: worktree.uri, + counter: 3, + confirm: true, + } as OpenStepState, + context, + ); + + break; + } + + queueMicrotask(() => { + switch (action) { + case 'always': + openWorkspace(worktree!.uri, { location: OpenWorkspaceLocation.CurrentWindow }); + break; + case 'alwaysNewWindow': + openWorkspace(worktree!.uri, { location: OpenWorkspaceLocation.NewWindow }); + break; + case 'onlyWhenEmpty': + openWorkspace(worktree!.uri, { + location: workspace.workspaceFolders?.length + ? OpenWorkspaceLocation.CurrentWindow + : OpenWorkspaceLocation.NewWindow, + }); + break; + } + }); } } @@ -804,15 +794,13 @@ export class WorktreeGitCommand extends QuickCommand { endSteps(state); - const worktree = context.worktrees.find(wt => wt.uri.toString() === state.uri.toString())!; + const worktree = context.worktrees.find(wt => wt.uri.toString() === state.uri.toString()); + if (worktree == null) break; + if (state.flags.includes('--reveal-explorer')) { void revealInFileExplorer(worktree); } else { - open(worktree, { - location: state.flags.includes('--new-window') - ? OpenWorkspaceLocation.NewWindow - : OpenWorkspaceLocation.CurrentWindow, - }); + openWorkspace(worktree.uri, { location: convertOpenFlagsToLocation(state.flags) }); } } } @@ -823,19 +811,25 @@ export class WorktreeGitCommand extends QuickCommand { [ createFlagsQuickPickItem(state.flags, [], { label: context.title, - detail: `Will open, in the current window, the worktree in $(folder) ${GitWorktree.getFriendlyPath( + detail: `Will open in the current window, the worktree in $(folder) ${GitWorktree.getFriendlyPath( state.uri, )}`, }), createFlagsQuickPickItem(state.flags, ['--new-window'], { label: `${context.title} in a New Window`, - detail: `Will open, in a new window, the worktree in $(folder) ${GitWorktree.getFriendlyPath( + detail: `Will open in a new window, the worktree in $(folder) ${GitWorktree.getFriendlyPath( + state.uri, + )}`, + }), + createFlagsQuickPickItem(state.flags, ['--add-to-workspace'], { + label: `Add Worktree to Workspace`, + detail: `Will add into the current workspace, the worktree in $(folder) ${GitWorktree.getFriendlyPath( state.uri, )}`, }), createFlagsQuickPickItem(state.flags, ['--reveal-explorer'], { label: `Reveal in File Explorer`, - detail: `Will open, in the File Explorer, the worktree in $(folder) ${GitWorktree.getFriendlyPath( + detail: `Will open in the File Explorer, the worktree in $(folder) ${GitWorktree.getFriendlyPath( state.uri, )}`, }), diff --git a/src/commands/quickCommand.steps.ts b/src/commands/quickCommand.steps.ts index 2067ab3..d05189c 100644 --- a/src/commands/quickCommand.steps.ts +++ b/src/commands/quickCommand.steps.ts @@ -89,7 +89,7 @@ import { formatPath } from '../system/formatPath'; import { map } from '../system/iterable'; import { getSettledValue } from '../system/promise'; import { pad, pluralize, truncate } from '../system/string'; -import { OpenWorkspaceLocation } from '../system/utils'; +import { openWorkspace, OpenWorkspaceLocation } from '../system/utils'; import type { ViewsWithRepositoryFolders } from '../views/viewBase'; import type { AsyncStepResultGenerator, @@ -1635,7 +1635,7 @@ export async function* pickWorktreeStep< onDidClickItemButton: (quickpick, button, { item }) => { switch (button) { case QuickCommandButtons.OpenInNewWindow: - WorktreeActions.open(item, { location: OpenWorkspaceLocation.NewWindow }); + openWorkspace(item.uri, { location: OpenWorkspaceLocation.NewWindow }); break; case QuickCommandButtons.RevealInSideBar: void WorktreeActions.reveal(item, { select: true, focus: false, expand: true }); @@ -1696,7 +1696,7 @@ export async function* pickWorktreesStep< onDidClickItemButton: (quickpick, button, { item }) => { switch (button) { case QuickCommandButtons.OpenInNewWindow: - WorktreeActions.open(item, { location: OpenWorkspaceLocation.NewWindow }); + openWorkspace(item.uri, { location: OpenWorkspaceLocation.NewWindow }); break; case QuickCommandButtons.RevealInSideBar: void WorktreeActions.reveal(item, { select: true, focus: false, expand: true }); diff --git a/src/constants.ts b/src/constants.ts index 42a571e..555a003 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -170,6 +170,7 @@ export const enum Commands { GitCommandsSwitch = 'gitlens.gitCommands.switch', GitCommandsTag = 'gitlens.gitCommands.tag', GitCommandsWorktree = 'gitlens.gitCommands.worktree', + OpenOrCreateWorktreeForGHPR = 'gitlens.ghpr.views.openOrCreateWorktree', PlusHide = 'gitlens.plus.hide', PlusLearn = 'gitlens.plus.learn', PlusLoginOrSignUp = 'gitlens.plus.loginOrSignUp', @@ -259,8 +260,6 @@ export const enum Commands { ViewsOpenDirectoryDiff = 'gitlens.views.openDirectoryDiff', ViewsOpenDirectoryDiffWithWorking = 'gitlens.views.openDirectoryDiffWithWorking', - CreateWorktreeForGHPR = 'gitlens.ghpr.views.createWorktree', - Deprecated_DiffHeadWith = 'gitlens.diffHeadWith', Deprecated_DiffWorkingWith = 'gitlens.diffWorkingWith', Deprecated_OpenBranchesInRemote = 'gitlens.openBranchesInRemote', diff --git a/src/git/actions/worktree.ts b/src/git/actions/worktree.ts index 5c69197..b7e2813 100644 --- a/src/git/actions/worktree.ts +++ b/src/git/actions/worktree.ts @@ -1,10 +1,10 @@ import type { Uri } from 'vscode'; +import type { WorktreeGitCommandArgs } from '../../commands/git/worktree'; import { CoreCommands } from '../../constants'; import { Container } from '../../container'; import { ensure } from '../../system/array'; import { executeCoreCommand } from '../../system/command'; -import type { OpenWorkspaceLocation } from '../../system/utils'; -import { openWorkspace } from '../../system/utils'; +import { OpenWorkspaceLocation } from '../../system/utils'; import { executeGitCommand } from '../actions'; import type { GitReference } from '../models/reference'; import type { Repository } from '../models/repository'; @@ -18,7 +18,15 @@ export function create(repo?: string | Repository, uri?: Uri, ref?: GitReference } export function open(worktree: GitWorktree, options?: { location?: OpenWorkspaceLocation }) { - return openWorkspace(worktree.uri, options); + return executeGitCommand({ + command: 'worktree', + state: { + subcommand: 'open', + repo: worktree.repoPath, + uri: worktree.uri, + flags: convertLocationToOpenFlags(options?.location), + }, + }); } export function remove(repo?: string | Repository, uri?: Uri) { @@ -48,3 +56,27 @@ export async function reveal( export async function revealInFileExplorer(worktree: GitWorktree) { void (await executeCoreCommand(CoreCommands.RevealInFileExplorer, worktree.uri)); } + +type OpenFlagsArray = Extract>, { subcommand: 'open' }>['flags']; + +export function convertLocationToOpenFlags(location: OpenWorkspaceLocation | undefined): OpenFlagsArray | undefined { + if (location == null) return undefined; + + switch (location) { + case OpenWorkspaceLocation.NewWindow: + return ['--new-window']; + case OpenWorkspaceLocation.AddToWorkspace: + return ['--add-to-workspace']; + case OpenWorkspaceLocation.CurrentWindow: + default: + return []; + } +} + +export function convertOpenFlagsToLocation(flags: OpenFlagsArray | undefined): OpenWorkspaceLocation | undefined { + if (flags == null) return undefined; + + if (flags.includes('--new-window')) return OpenWorkspaceLocation.NewWindow; + if (flags.includes('--add-to-workspace')) return OpenWorkspaceLocation.AddToWorkspace; + return OpenWorkspaceLocation.CurrentWindow; +} diff --git a/src/views/viewCommands.ts b/src/views/viewCommands.ts index 5fa86f5..8238680 100644 --- a/src/views/viewCommands.ts +++ b/src/views/viewCommands.ts @@ -33,7 +33,7 @@ import { } from '../system/command'; import { debug } from '../system/decorators/log'; import { sequentialize } from '../system/function'; -import { OpenWorkspaceLocation } from '../system/utils'; +import { openWorkspace, OpenWorkspaceLocation } from '../system/utils'; import type { BranchesNode } from './nodes/branchesNode'; import { BranchNode } from './nodes/branchNode'; import { BranchTrackingStatusNode } from './nodes/branchTrackingStatusNode'; @@ -572,7 +572,7 @@ export class ViewCommands { private openWorktree(node: WorktreeNode, options?: { location?: OpenWorkspaceLocation }) { if (!(node instanceof WorktreeNode)) return undefined; - return WorktreeActions.open(node.worktree, options); + return openWorkspace(node.worktree.uri, options); } @debug()