diff --git a/extensions/github/package.json b/extensions/github/package.json index a9ba2e87d30..0e33a21f918 100644 --- a/extensions/github/package.json +++ b/extensions/github/package.json @@ -74,6 +74,11 @@ "command": "github.createPullRequest", "title": "%command.createPullRequest%", "icon": "$(git-pull-request)" + }, + { + "command": "github.openPullRequest", + "title": "%command.openPullRequest%", + "icon": "$(git-pull-request)" } ], "continueEditSession": [ @@ -95,6 +100,10 @@ "command": "github.createPullRequest", "when": "false" }, + { + "command": "github.openPullRequest", + "when": "false" + }, { "command": "github.graph.openOnGitHub", "when": "false" @@ -179,7 +188,13 @@ "command": "github.createPullRequest", "group": "navigation", "order": 1, - "when": "isSessionsWindow && agentSessionHasChanges && chatSessionType == copilotcli" + "when": "isSessionsWindow && agentSessionHasChanges && chatSessionType == copilotcli && !github.hasOpenPullRequest" + }, + { + "command": "github.openPullRequest", + "group": "navigation", + "order": 1, + "when": "isSessionsWindow && agentSessionHasChanges && chatSessionType == copilotcli && github.hasOpenPullRequest" } ] }, diff --git a/extensions/github/package.nls.json b/extensions/github/package.nls.json index ced536e4bd7..4acc8acabcb 100644 --- a/extensions/github/package.nls.json +++ b/extensions/github/package.nls.json @@ -6,6 +6,7 @@ "command.openOnGitHub": "Open on GitHub", "command.openOnVscodeDev": "Open in vscode.dev", "command.createPullRequest": "Create Pull Request", + "command.openPullRequest": "Open Pull Request", "config.branchProtection": "Controls whether to query repository rules for GitHub repositories", "config.gitAuthentication": "Controls whether to enable automatic GitHub authentication for git commands within VS Code.", "config.gitProtocol": "Controls which protocol is used to clone a GitHub repository", diff --git a/extensions/github/src/commands.ts b/extensions/github/src/commands.ts index 496772ededf..eee730b853a 100644 --- a/extensions/github/src/commands.ts +++ b/extensions/github/src/commands.ts @@ -8,6 +8,7 @@ import { API as GitAPI, RefType, Repository } from './typings/git.js'; import { publishRepository } from './publish.js'; import { DisposableStore, getRepositoryFromUrl } from './util.js'; import { LinkContext, getCommitLink, getLink, getVscodeDevHost } from './links.js'; +import { getOctokit } from './auth.js'; async function copyVscodeDevLink(gitAPI: GitAPI, useSelection: boolean, context: LinkContext, includeRange = true) { try { @@ -89,6 +90,27 @@ async function createPullRequest(gitAPI: GitAPI, sessionResource: vscode.Uri | u } } + // Check if a PR already exists for this branch + try { + const octokit = await getOctokit(); + const { data: pullRequests } = await octokit.pulls.list({ + owner: remoteInfo.owner, + repo: remoteInfo.repo, + head: `${remoteInfo.owner}:${head.name}`, + state: 'open', + }); + + if (pullRequests.length > 0) { + vscode.commands.executeCommand('setContext', 'github.hasOpenPullRequest', true); + vscode.env.openExternal(vscode.Uri.parse(pullRequests[0].html_url)); + return; + } + } catch { + // If the API call fails, fall through to open the creation URL + } + + vscode.commands.executeCommand('setContext', 'github.hasOpenPullRequest', false); + // Build the GitHub PR creation URL // Format: https://github.com/owner/repo/compare/base...head const prUrl = `https://github.com/${remoteInfo.owner}/${remoteInfo.repo}/compare/${head.name}?expand=1`; @@ -181,5 +203,9 @@ export function registerCommands(gitAPI: GitAPI): vscode.Disposable { return createPullRequest(gitAPI, sessionResource, sessionMetadata); })); + disposables.add(vscode.commands.registerCommand('github.openPullRequest', async (sessionResource: vscode.Uri | undefined, sessionMetadata: { worktreePath?: string } | undefined) => { + return createPullRequest(gitAPI, sessionResource, sessionMetadata); + })); + return disposables; } diff --git a/src/vs/sessions/contrib/changesView/browser/changesView.ts b/src/vs/sessions/contrib/changesView/browser/changesView.ts index d437e6e19a0..e09785f5682 100644 --- a/src/vs/sessions/contrib/changesView/browser/changesView.ts +++ b/src/vs/sessions/contrib/changesView/browser/changesView.ts @@ -562,7 +562,7 @@ export class ChangesViewPane extends ViewPane { ); return { showIcon: true, showLabel: true, isSecondary: true, customClass: 'working-set-diff-stats', customLabel: diffStatsLabel }; } - if (action.id === 'github.createPullRequest') { + if (action.id === 'github.createPullRequest' || action.id === 'github.openPullRequest') { return { showIcon: true, showLabel: true, isSecondary: true, customClass: 'flex-grow' }; } if (action.id === 'chatEditing.synchronizeChanges') {