diff --git a/src/git/models/pullRequest.ts b/src/git/models/pullRequest.ts index 9496d787bd82a..688de1e6c747e 100644 --- a/src/git/models/pullRequest.ts +++ b/src/git/models/pullRequest.ts @@ -309,7 +309,7 @@ export function getVirtualUriForPullRequest(pr: PullRequest): Uri | undefined { export async function getOrOpenPullRequestRepository( container: Container, pr: PullRequest, - options?: { promptIfNeeded?: boolean }, + options?: { promptIfNeeded?: boolean; skipVirtual?: boolean }, ): Promise { const identity = getRepositoryIdentityForPullRequest(pr); let repo = await container.repositoryIdentity.getRepository(identity, { @@ -318,7 +318,7 @@ export async function getOrOpenPullRequestRepository( prompt: false, }); - if (repo == null) { + if (repo == null && !options?.skipVirtual) { const virtualUri = getVirtualUriForPullRequest(pr); if (virtualUri != null) { repo = await container.git.getOrOpenRepository(virtualUri, { closeOnOpen: true, detectNested: false }); diff --git a/src/plus/launchpad/launchpadProvider.ts b/src/plus/launchpad/launchpadProvider.ts index 33c52ef83124a..ae74d4a130498 100644 --- a/src/plus/launchpad/launchpadProvider.ts +++ b/src/plus/launchpad/launchpadProvider.ts @@ -16,7 +16,11 @@ import type { Account } from '../../git/models/author'; import type { GitBranch } from '../../git/models/branch'; import { getLocalBranchByUpstream } from '../../git/models/branch'; import type { PullRequest, SearchedPullRequest } from '../../git/models/pullRequest'; -import { getComparisonRefsForPullRequest, getRepositoryIdentityForPullRequest } from '../../git/models/pullRequest'; +import { + getComparisonRefsForPullRequest, + getOrOpenPullRequestRepository, + getRepositoryIdentityForPullRequest, +} from '../../git/models/pullRequest'; import type { GitRemote } from '../../git/models/remote'; import type { Repository } from '../../git/models/repository'; import type { CodeSuggestionCounts, Draft } from '../../gk/models/drafts'; @@ -488,8 +492,11 @@ export class LaunchpadProvider implements Disposable { ); if (deepLinkUrl == null) return; + const prRepo = await getOrOpenPullRequestRepository(this.container, item.underlyingPullRequest, { + skipVirtual: true, + }); this._codeSuggestions?.delete(item.uuid); - await this.container.deepLinks.processDeepLinkUri(deepLinkUrl, false); + await this.container.deepLinks.processDeepLinkUri(deepLinkUrl, false, prRepo); } @log({ args: { 0: i => `${i.id} (${i.provider.name} ${i.type})` } }) diff --git a/src/uris/deepLinks/deepLinkService.ts b/src/uris/deepLinks/deepLinkService.ts index 79f260f768245..8415928ec7b4a 100644 --- a/src/uris/deepLinks/deepLinkService.ts +++ b/src/uris/deepLinks/deepLinkService.ts @@ -10,7 +10,7 @@ import { getBranchNameWithoutRemote } from '../../git/models/branch'; import type { GitCommit } from '../../git/models/commit'; import type { GitReference } from '../../git/models/reference'; import { createReference, isSha } from '../../git/models/reference'; -import type { RepositoryChangeEvent } from '../../git/models/repository'; +import type { Repository, RepositoryChangeEvent } from '../../git/models/repository'; import { RepositoryChange, RepositoryChangeComparisonMode } from '../../git/models/repository'; import type { GitTag } from '../../git/models/tag'; import { parseGitRemoteUrl } from '../../git/parsers/remoteParser'; @@ -100,7 +100,7 @@ export class DeepLinkService implements Disposable { }; } - private setContextFromDeepLink(link: DeepLink, url: string) { + private setContextFromDeepLink(link: DeepLink, url: string, repo?: Repository) { this._context = { ...this._context, mainId: link.mainId, @@ -115,9 +115,14 @@ export class DeepLinkService implements Disposable { action: link.action, params: link.params, }; + + if (repo != null) { + this._context.repo = repo; + this._context.repoPath = repo.path; + } } - async processDeepLinkUri(uri: Uri, useProgress: boolean = true) { + async processDeepLinkUri(uri: Uri, useProgress: boolean = true, repo?: Repository) { const link = parseDeepLinkUri(uri); if (link == null) return; @@ -150,7 +155,7 @@ export class DeepLinkService implements Disposable { return; } - this.setContextFromDeepLink(link, uri.toString()); + this.setContextFromDeepLink(link, uri.toString(), repo); await this.processDeepLink(undefined, useProgress); } @@ -499,6 +504,9 @@ export class DeepLinkService implements Disposable { return remoteName; } + // TODO @axosoft-ramint: Move all the logic for matching a repo, prompting to add repo, matching remote, etc. for a target (branch, PR, etc.) + // to a separate service where it can be used outside of the context of deep linking. Then the deep link service should leverage it, + // and we should stop using deep links to process things like Launchpad switch actions, Open in Worktree command, etc. private async processDeepLink( initialAction: DeepLinkServiceAction = DeepLinkServiceAction.DeepLinkEventFired, useProgress: boolean = true, @@ -660,7 +668,7 @@ export class DeepLinkService implements Disposable { } case DeepLinkServiceState.RepoMatch: case DeepLinkServiceState.AddedRepoMatch: { - if (repo != null && repoOpenUri != null && repoOpenLocation != null) { + if (repo != null) { action = DeepLinkServiceAction.RepoMatched; break; } diff --git a/src/views/viewCommands.ts b/src/views/viewCommands.ts index 3d28b718283f6..db39cce59f16c 100644 --- a/src/views/viewCommands.ts +++ b/src/views/viewCommands.ts @@ -27,6 +27,7 @@ import { ensurePullRequestRefs, getComparisonRefsForPullRequest, getOpenedPullRequestRepo, + getOrOpenPullRequestRepository, getRepositoryIdentityForPullRequest, } from '../git/models/pullRequest'; import { createReference, shortenRevision } from '../git/models/reference'; @@ -807,7 +808,11 @@ export class ViewCommands { repoIdentity.remote.url, DeepLinkActionType.SwitchToPullRequestWorktree, ); - return this.container.deepLinks.processDeepLinkUri(deepLink, false); + + const prRepo = await getOrOpenPullRequestRepository(this.container, pr, { + skipVirtual: true, + }); + return this.container.deepLinks.processDeepLinkUri(deepLink, false, prRepo); } }