diff --git a/extensions/github/package.json b/extensions/github/package.json index a1d9b4eb961..55e04b30804 100644 --- a/extensions/github/package.json +++ b/extensions/github/package.json @@ -32,7 +32,8 @@ "contribShareMenu", "contribSourceControlHistoryItemMenu", "scmHistoryProvider", - "shareProvider" + "shareProvider", + "timeline" ], "contributes": { "commands": [ @@ -61,6 +62,11 @@ "command": "github.graph.openOnGitHub", "title": "%command.openOnGitHub%", "icon": "$(github)" + }, + { + "command": "github.timeline.openOnGitHub", + "title": "%command.openOnGitHub%", + "icon": "$(github)" } ], "continueEditSession": [ @@ -97,6 +103,10 @@ { "command": "github.openOnVscodeDev", "when": "false" + }, + { + "command": "github.timeline.openOnGitHub", + "when": "false" } ], "file/share": [ @@ -152,6 +162,13 @@ "when": "github.hasGitHubRepo", "group": "1_open@1" } + ], + "timeline/item/context": [ + { + "command": "github.timeline.openOnGitHub", + "group": "1_actions@3", + "when": "github.hasGitHubRepo && timelineItem =~ /git:file:commit\\b/" + } ] }, "configuration": [ diff --git a/extensions/github/src/commands.ts b/extensions/github/src/commands.ts index 805d91c7296..4e5587c09b5 100644 --- a/extensions/github/src/commands.ts +++ b/extensions/github/src/commands.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { API as GitAPI, RefType } from './typings/git'; +import { API as GitAPI, RefType, Repository } from './typings/git'; import { publishRepository } from './publish'; import { DisposableStore, getRepositoryFromUrl } from './util'; import { LinkContext, getCommitLink, getLink, getVscodeDevHost } from './links'; @@ -34,6 +34,29 @@ async function openVscodeDevLink(gitAPI: GitAPI): Promise { + // Get the unique remotes that contain the commit + const branches = await repository.getBranches({ contains: commit, remote: true }); + const remoteNames = new Set(branches.filter(b => b.type === RefType.RemoteHead && b.remote).map(b => b.remote!)); + + // GitHub remotes that contain the commit + const remotes = repository.state.remotes + .filter(r => remoteNames.has(r.name) && r.fetchUrl && getRepositoryFromUrl(r.fetchUrl)); + + if (remotes.length === 0) { + vscode.window.showInformationMessage(vscode.l10n.t('No GitHub remotes found that contain this commit.')); + return; + } + + // upstream -> origin -> first + const remote = remotes.find(r => r.name === 'upstream') + ?? remotes.find(r => r.name === 'origin') + ?? remotes[0]; + + const link = getCommitLink(remote.fetchUrl!, commit); + vscode.env.openExternal(vscode.Uri.parse(link)); +} + export function registerCommands(gitAPI: GitAPI): vscode.Disposable { const disposables = new DisposableStore(); @@ -72,26 +95,20 @@ export function registerCommands(gitAPI: GitAPI): vscode.Disposable { return; } - // Get the unique remotes that contain the commit - const branches = await apiRepository.getBranches({ contains: historyItem.id, remote: true }); - const remoteNames = new Set(branches.filter(b => b.type === RefType.RemoteHead && b.remote).map(b => b.remote!)); + await openOnGitHub(apiRepository, historyItem.id); + })); - // GitHub remotes that contain the commit - const remotes = apiRepository.state.remotes - .filter(r => remoteNames.has(r.name) && r.fetchUrl && getRepositoryFromUrl(r.fetchUrl)); - - if (remotes.length === 0) { - vscode.window.showInformationMessage(vscode.l10n.t('No GitHub remotes found that contain this commit.')); + disposables.add(vscode.commands.registerCommand('github.timeline.openOnGitHub', async (item: vscode.TimelineItem, uri: vscode.Uri) => { + if (!item.id || !uri) { return; } - // upstream -> origin -> first - const remote = remotes.find(r => r.name === 'upstream') - ?? remotes.find(r => r.name === 'origin') - ?? remotes[0]; + const apiRepository = gitAPI.getRepository(uri); + if (!apiRepository) { + return; + } - const link = getCommitLink(remote.fetchUrl!, historyItem.id); - vscode.env.openExternal(vscode.Uri.parse(link)); + await openOnGitHub(apiRepository, item.id); })); disposables.add(vscode.commands.registerCommand('github.openOnVscodeDev', async () => { diff --git a/extensions/github/tsconfig.json b/extensions/github/tsconfig.json index 6b9a6e7db0a..8435c0d09e8 100644 --- a/extensions/github/tsconfig.json +++ b/extensions/github/tsconfig.json @@ -12,6 +12,7 @@ "../../src/vscode-dts/vscode.d.ts", "../../src/vscode-dts/vscode.proposed.canonicalUriProvider.d.ts", "../../src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts", - "../../src/vscode-dts/vscode.proposed.shareProvider.d.ts" + "../../src/vscode-dts/vscode.proposed.shareProvider.d.ts", + "../../src/vscode-dts/vscode.proposed.timeline.d.ts" ] }