diff --git a/src/commands/ghpr/createWorktree.ts b/src/commands/ghpr/createWorktree.ts index b184479..8cc9e09 100644 --- a/src/commands/ghpr/createWorktree.ts +++ b/src/commands/ghpr/createWorktree.ts @@ -15,6 +15,12 @@ interface PullRequestNode { } interface PullRequest { + readonly base: { + readonly repositoryCloneUrl: { + readonly owner: string; + readonly repositoryName: string; + }; + }; readonly githubRepository: { readonly rootUri: Uri; }; @@ -48,26 +54,26 @@ export class CreateWorktreeCommand extends Command { } 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 #${pr.item.number}`, - ); + 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 #${pr.item.number}`, - ); + void window.showWarningMessage(`Unable to find main repository(${rootUri.toString()}) for PR #${number}`); return; } @@ -103,6 +109,17 @@ export class CreateWorktreeCommand extends Command { remote: true, }), ); + + // Save the PR number in the branch config + const cfg = await this.container.git.getConfig(repo.path, `branch.${ref}.remote`); + if (cfg != null) { + // 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/env/node/git/git.ts b/src/env/node/git/git.ts index 42a80ec..6e17915 100644 --- a/src/env/node/git/git.ts +++ b/src/env/node/git/git.ts @@ -502,9 +502,9 @@ export class Git { return this.git({ cwd: repoPath }, ...params); } - async config__get(key: string, repoPath?: string, options: { local?: boolean } = {}) { + async config__get(key: string, repoPath?: string, options?: { local?: boolean }) { const data = await this.git( - { cwd: repoPath ?? '', errors: GitErrorHandling.Ignore, local: options.local }, + { cwd: repoPath ?? '', errors: GitErrorHandling.Ignore, local: options?.local }, 'config', '--get', key, @@ -512,9 +512,9 @@ export class Git { return data.length === 0 ? undefined : data.trim(); } - async config__get_regex(pattern: string, repoPath?: string, options: { local?: boolean } = {}) { + async config__get_regex(pattern: string, repoPath?: string, options?: { local?: boolean }) { const data = await this.git( - { cwd: repoPath ?? '', errors: GitErrorHandling.Ignore, local: options.local }, + { cwd: repoPath ?? '', errors: GitErrorHandling.Ignore, local: options?.local }, 'config', '--get-regex', pattern, @@ -522,6 +522,16 @@ export class Git { return data.length === 0 ? undefined : data.trim(); } + async config__set(key: string, value: string | undefined, repoPath?: string) { + const params = ['config', '--local']; + if (value == null) { + params.push('--unset', key); + } else { + params.push(key, value); + } + await this.git({ cwd: repoPath ?? '', local: true }, ...params); + } + async diff( repoPath: string, fileName: string, diff --git a/src/env/node/git/localGitProvider.ts b/src/env/node/git/localGitProvider.ts index cffed23..b50161e 100644 --- a/src/env/node/git/localGitProvider.ts +++ b/src/env/node/git/localGitProvider.ts @@ -2133,6 +2133,14 @@ export class LocalGitProvider implements GitProvider, Disposable { return getCommitsForGraphCore.call(this, defaultLimit, selectSha); } + getConfig(repoPath: string, key: string): Promise { + return this.git.config__get(key, repoPath); + } + + setConfig(repoPath: string, key: string, value: string | undefined): Promise { + return this.git.config__set(key, value, repoPath); + } + @log() async getContributors( repoPath: string, diff --git a/src/git/gitProvider.ts b/src/git/gitProvider.ts index 7e7332a..4f6d3fd 100644 --- a/src/git/gitProvider.ts +++ b/src/git/gitProvider.ts @@ -236,6 +236,8 @@ export interface GitProvider extends Disposable { ref?: string; }, ): Promise; + getConfig?(repoPath: string, key: string): Promise; + setConfig?(repoPath: string, key: string, value: string | undefined): Promise; getContributors( repoPath: string, options?: { all?: boolean | undefined; ref?: string | undefined; stats?: boolean | undefined }, diff --git a/src/git/gitProviderService.ts b/src/git/gitProviderService.ts index f525413..bded4fc 100644 --- a/src/git/gitProviderService.ts +++ b/src/git/gitProviderService.ts @@ -1412,9 +1412,15 @@ export class GitProviderService implements Disposable { } @log() - async getOldestUnpushedRefForFile(repoPath: string | Uri, uri: Uri): Promise { + async getConfig(repoPath: string, key: string): Promise { const { provider, path } = this.getProvider(repoPath); - return provider.getOldestUnpushedRefForFile(path, uri); + return provider.getConfig?.(path, key); + } + + @log() + async setConfig(repoPath: string, key: string, value: string | undefined): Promise { + const { provider, path } = this.getProvider(repoPath); + return provider.setConfig?.(path, key, value); } @log()