Skip to content

Commit 74a57e3

Browse files
Refinements
- Only shows changes for "open in worktree" action - Removes unnecessary state transition - Only shows changes if worktree is created in flow - Applies to branches in views and graph
1 parent 861824b commit 74a57e3

File tree

6 files changed

+80
-10
lines changed

6 files changed

+80
-10
lines changed

src/commands/git/switch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ interface Context {
3434

3535
interface State {
3636
repos: string | string[] | Repository | Repository[];
37-
onWorkspaceChanging?: (() => Promise<void>) | (() => void);
37+
onWorkspaceChanging?: ((isNewWorktree?: boolean) => Promise<void>) | ((isNewWorktree?: boolean) => void);
3838
reference: GitReference;
3939
createBranch?: string;
4040
fastForwardTo?: GitReference;

src/commands/git/worktree.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ interface CreateState {
102102
title?: string;
103103
};
104104

105-
onWorkspaceChanging?: (() => Promise<void>) | (() => void);
105+
onWorkspaceChanging?: ((isNewWorktree?: boolean) => Promise<void>) | ((isNewWorktree?: boolean) => void);
106106
skipWorktreeConfirmations?: boolean;
107107
}
108108

@@ -139,7 +139,8 @@ interface OpenState {
139139
};
140140
};
141141

142-
onWorkspaceChanging?: (() => Promise<void>) | (() => void);
142+
onWorkspaceChanging?: ((isNewWorktree?: boolean) => Promise<void>) | ((isNewWorktree?: boolean) => void);
143+
isNewWorktree?: boolean;
143144
skipWorktreeConfirmations?: boolean;
144145
}
145146

@@ -628,6 +629,7 @@ export class WorktreeGitCommand extends QuickCommand<State> {
628629
confirm: action === 'prompt',
629630
openOnly: true,
630631
overrides: { disallowBack: true },
632+
isNewWorktree: true,
631633
skipWorktreeConfirmations: state.skipWorktreeConfirmations,
632634
onWorkspaceChanging: state.onWorkspaceChanging,
633635
} satisfies OpenStepState,
@@ -1081,7 +1083,7 @@ export class WorktreeGitCommand extends QuickCommand<State> {
10811083

10821084
const location = convertOpenFlagsToLocation(state.flags);
10831085
if (location === 'currentWindow' || location === 'newWindow') {
1084-
await state.onWorkspaceChanging?.();
1086+
await state.onWorkspaceChanging?.(state.isNewWorktree);
10851087
}
10861088

10871089
openWorkspace(state.worktree.uri, { location: convertOpenFlagsToLocation(state.flags), name: name });

src/plus/webviews/graph/graphWebview.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@ import { GitContributor } from '../../../git/models/contributor';
6262
import type { GitGraph, GitGraphRowType } from '../../../git/models/graph';
6363
import { getGkProviderThemeIconString } from '../../../git/models/graph';
6464
import type { PullRequest } from '../../../git/models/pullRequest';
65-
import { getComparisonRefsForPullRequest, serializePullRequest } from '../../../git/models/pullRequest';
65+
import {
66+
getComparisonRefsForPullRequest,
67+
getRepositoryIdentityForPullRequest,
68+
serializePullRequest,
69+
} from '../../../git/models/pullRequest';
6670
import type {
6771
GitBranchReference,
6872
GitReference,
@@ -115,6 +119,7 @@ import { getContext, onDidChangeContext } from '../../../system/vscode/context';
115119
import type { OpenWorkspaceLocation } from '../../../system/vscode/utils';
116120
import { isDarkTheme, isLightTheme, openWorkspace } from '../../../system/vscode/utils';
117121
import { isWebviewItemContext, isWebviewItemGroupContext, serializeWebviewItemContext } from '../../../system/webview';
122+
import { DeepLinkActionType } from '../../../uris/deepLinks/deepLink';
118123
import { RepositoryFolderNode } from '../../../views/nodes/abstract/repositoryFolderNode';
119124
import type { IpcCallMessageType, IpcMessage, IpcNotification } from '../../../webviews/protocol';
120125
import type { WebviewHost, WebviewProvider, WebviewShowingArgs } from '../../../webviews/webviewProvider';
@@ -123,6 +128,7 @@ import { isSerializedState } from '../../../webviews/webviewsController';
123128
import type { SubscriptionChangeEvent } from '../../gk/account/subscriptionService';
124129
import type { ConnectionStateChangeEvent } from '../../integrations/integrationService';
125130
import { remoteProviderIdToIntegrationId } from '../../integrations/integrationService';
131+
import { getPullRequestBranchDeepLink } from '../../launchpad/launchpadProvider';
126132
import type {
127133
BranchState,
128134
DidChangeRefsVisibilityParams,
@@ -3643,6 +3649,24 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
36433649
private async openInWorktree(item?: GraphItemContext) {
36443650
if (isGraphItemRefContext(item, 'branch')) {
36453651
const { ref } = item.webviewItemValue;
3652+
const repo = this.container.git.getRepository(ref.repoPath);
3653+
const branch = await repo?.git.getBranch(ref.name);
3654+
const pr = await branch?.getAssociatedPullRequest();
3655+
if (branch != null && repo != null && pr != null) {
3656+
const remoteUrl = (await branch.getRemote())?.url ?? getRepositoryIdentityForPullRequest(pr).remote.url;
3657+
if (remoteUrl != null) {
3658+
const deepLink = getPullRequestBranchDeepLink(
3659+
this.container,
3660+
branch.getNameWithoutRemote(),
3661+
remoteUrl,
3662+
DeepLinkActionType.SwitchToPullRequestWorktree,
3663+
pr,
3664+
);
3665+
3666+
return this.container.deepLinks.processDeepLinkUri(deepLink, false, repo);
3667+
}
3668+
}
3669+
36463670
await executeGitCommand({
36473671
command: 'switch',
36483672
state: {

src/uris/deepLinks/deepLink.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,6 @@ export const deepLinkStateTransitionTable: Record<string, Record<string, DeepLin
391391
[DeepLinkServiceAction.OpenGraph]: DeepLinkServiceState.OpenGraph,
392392
[DeepLinkServiceAction.OpenFile]: DeepLinkServiceState.OpenFile,
393393
[DeepLinkServiceAction.OpenSwitch]: DeepLinkServiceState.SwitchToRef,
394-
[DeepLinkServiceAction.OpenAllPrChanges]: DeepLinkServiceState.OpenAllPrChanges,
395394
[DeepLinkServiceAction.OpenComparison]: DeepLinkServiceState.OpenComparison,
396395
[DeepLinkServiceAction.DeepLinkErrored]: DeepLinkServiceState.Idle,
397396
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,

src/uris/deepLinks/deepLinkService.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,9 +1321,25 @@ export class DeepLinkService implements Disposable {
13211321
state: this._context.state,
13221322
};
13231323

1324+
// Form a new link URL with PR info stripped out in case we are opening an existing PR worktree,
1325+
// in which case we do not want to advance to the "Open All PR Changes" step in the flow.
1326+
// We should only advance to that step if a worktree is newly created in the flow.
1327+
const oldUrl = Uri.parse(this._context.url ?? '').toString(true);
1328+
const urlParams = new URL(oldUrl).searchParams;
1329+
urlParams.delete('prId');
1330+
urlParams.delete('prTitle');
1331+
urlParams.delete('prBaseRef');
1332+
urlParams.delete('prHeadRef');
1333+
const newUrlParams = urlParams.toString();
1334+
const nonPrUrl =
1335+
newUrlParams.length > 0 ? `${oldUrl.split('?')[0]}?${newUrlParams}` : oldUrl.split('?')[0];
1336+
13241337
// Storing link info in case the switch causes a new window to open
1325-
const onWorkspaceChanging = async () =>
1326-
this.container.storage.store('deepLinks:pending', pendingDeepLink);
1338+
const onWorkspaceChanging = async (isNewWorktree?: boolean) =>
1339+
this.container.storage.store(
1340+
'deepLinks:pending',
1341+
isNewWorktree ? pendingDeepLink : { ...pendingDeepLink, url: nonPrUrl },
1342+
);
13271343

13281344
await executeGitCommand({
13291345
command: 'switch',
@@ -1385,15 +1401,27 @@ export class DeepLinkService implements Disposable {
13851401
repository: repo,
13861402
source: 'launchpad',
13871403
} satisfies ShowWipArgs);
1388-
action = DeepLinkServiceAction.OpenAllPrChanges;
1404+
const { params } = this._context;
1405+
if (
1406+
this._context.action === DeepLinkActionType.SwitchToPullRequestWorktree &&
1407+
params != null &&
1408+
(params.get('prId') != null || params.get('prTitle') != null) &&
1409+
params.get('prBaseRef') != null &&
1410+
params.get('prHeadRef') != null
1411+
) {
1412+
action = DeepLinkServiceAction.OpenAllPrChanges;
1413+
break;
1414+
}
1415+
1416+
action = DeepLinkServiceAction.DeepLinkResolved;
13891417
break;
13901418
}
13911419
case DeepLinkServiceState.OpenAllPrChanges: {
13921420
const prId = this._context.params?.get('prId');
13931421
const prHeadRef = this._context.params?.get('prHeadRef');
13941422
const prBaseRef = this._context.params?.get('prBaseRef');
13951423
const prTitle = this._context.params?.get('prTitle');
1396-
if (!repoPath || !prId || !prHeadRef || !prBaseRef) {
1424+
if (!repoPath || (!prId && !prTitle) || !prHeadRef || !prBaseRef) {
13971425
action = DeepLinkServiceAction.DeepLinkErrored;
13981426
if (!repoPath) {
13991427
message = 'No repository path was provided.';

src/views/viewCommands.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,23 @@ export class ViewCommands {
786786
if (!node.is('branch') && !node.is('pullrequest') && !node.is('launchpad-item')) return;
787787

788788
if (node.is('branch')) {
789+
const pr = await node.branch.getAssociatedPullRequest();
790+
if (pr != null) {
791+
const remoteUrl =
792+
(await node.branch.getRemote())?.url ?? getRepositoryIdentityForPullRequest(pr).remote.url;
793+
if (remoteUrl != null) {
794+
const deepLink = getPullRequestBranchDeepLink(
795+
this.container,
796+
node.branch.getNameWithoutRemote(),
797+
remoteUrl,
798+
DeepLinkActionType.SwitchToPullRequestWorktree,
799+
pr,
800+
);
801+
802+
return this.container.deepLinks.processDeepLinkUri(deepLink, false, node.repo);
803+
}
804+
}
805+
789806
return executeGitCommand({
790807
command: 'switch',
791808
state: {

0 commit comments

Comments
 (0)