diff --git a/package.json b/package.json index 41ffcb61ad..1426c5a4df 100644 --- a/package.json +++ b/package.json @@ -504,6 +504,12 @@ "title": "Refresh Pull Request Description", "category": "GitHub Pull Requests" }, + { + "command": "pr.checkoutByNumber", + "title": "Checkout Pull Request by Number", + "category": "GitHub Pull Requests", + "icon": "$(symbol-numeric)" + }, { "command": "review.openFile", "title": "Open File", @@ -1069,15 +1075,20 @@ "when": "gitHubOpenRepositoryCount != 0 && github:initialized && view == pr:github", "group": "navigation@1" }, + { + "command": "pr.checkoutByNumber", + "when": "gitHubOpenRepositoryCount != 0 && github:initialized && view == pr:github", + "group": "navigation@2" + }, { "command": "pr.configurePRViewlet", "when": "gitHubOpenRepositoryCount != 0 && github:initialized && view =~ /(pr|issues):github/", - "group": "navigation@3" + "group": "navigation@4" }, { "command": "pr.refreshList", "when": "gitHubOpenRepositoryCount != 0 && github:initialized && view == pr:github", - "group": "navigation@2" + "group": "navigation@3" }, { "command": "pr.refreshChanges", diff --git a/src/commands.ts b/src/commands.ts index 1f3dcbdc8b..4dfd83c12c 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -17,6 +17,7 @@ import { formatError } from './common/utils'; import { EXTENSION_ID } from './constants'; import { CredentialStore } from './github/credentials'; import { FolderRepositoryManager } from './github/folderRepositoryManager'; +import { GitHubRepository } from './github/githubRepository'; import { PullRequest } from './github/interface'; import { GHPRComment, TemporaryComment } from './github/prComment'; import { PullRequestModel } from './github/pullRequestModel'; @@ -845,4 +846,35 @@ export function registerCommands( vscode.commands.registerCommand('pr.collapseAllComments', () => { sessionState.commentsExpandState = false; })); + + context.subscriptions.push( + vscode.commands.registerCommand('pr.checkoutByNumber', async () => { + + const githubRepositories: { manager: FolderRepositoryManager, repo: GitHubRepository }[] = []; + reposManager.folderManagers.forEach(manager => { + githubRepositories.push(...(manager.gitHubRepositories.map(repo => { return { manager, repo }; }))); + }); + const githubRepo = await chooseItem<{ manager: FolderRepositoryManager, repo: GitHubRepository }>( + githubRepositories, + itemValue => `${itemValue.repo.remote.owner}/${itemValue.repo.remote.repositoryName}`, + { placeHolder: 'Which GitHub repository do you want to checkout the pull request from?' } + ); + if (!githubRepo) { + return; + } + const prNumber = await vscode.window.showInputBox({ + ignoreFocusOut: true, prompt: 'Enter the a pull request number', + validateInput: (input) => { + const asNumber = Number(input); + if (Number.isNaN(asNumber)) { + return 'Value must be a number'; + } + return undefined; + } + }); + if (prNumber === undefined) { + return; + } + return githubRepo.manager.checkoutById(githubRepo.repo, Number(prNumber)); + })); } diff --git a/src/github/folderRepositoryManager.ts b/src/github/folderRepositoryManager.ts index b92657443b..e6a25722da 100644 --- a/src/github/folderRepositoryManager.ts +++ b/src/github/folderRepositoryManager.ts @@ -1821,6 +1821,22 @@ export class FolderRepositoryManager implements vscode.Disposable { return this.repository.checkout(branchName); } + async checkoutById(githubRepo: GitHubRepository, id: number): Promise { + const pullRequest = await githubRepo.getPullRequest(id); + if (pullRequest) { + try { + await this.fetchAndCheckout(pullRequest); + } catch (e) { + Logger.appendLine(e.stderr, 'FolderRepositoryManager'); + if ((e.stderr as string).startsWith('fatal: couldn\'t find remote ref')) { + vscode.window.showErrorMessage(`The branch for request number ${id} has been deleted from ${githubRepo.remote.owner}/${githubRepo.remote.owner}`); + } + } + } else { + vscode.window.showErrorMessage(`Pull request number ${id} does not exist in ${githubRepo.remote.owner}/${githubRepo.remote.owner}`); + } + } + public async checkoutDefaultBranch(branch: string): Promise { try { const branchObj = await this.repository.getBranch(branch);