Skip to content

Commit bb65589

Browse files
authored
GitHub - add "Open on GitHub" action to timeline context menu (microsoft#238144)
1 parent e567381 commit bb65589

File tree

3 files changed

+53
-18
lines changed

3 files changed

+53
-18
lines changed

extensions/github/package.json

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
"contribShareMenu",
3333
"contribSourceControlHistoryItemMenu",
3434
"scmHistoryProvider",
35-
"shareProvider"
35+
"shareProvider",
36+
"timeline"
3637
],
3738
"contributes": {
3839
"commands": [
@@ -61,6 +62,11 @@
6162
"command": "github.graph.openOnGitHub",
6263
"title": "%command.openOnGitHub%",
6364
"icon": "$(github)"
65+
},
66+
{
67+
"command": "github.timeline.openOnGitHub",
68+
"title": "%command.openOnGitHub%",
69+
"icon": "$(github)"
6470
}
6571
],
6672
"continueEditSession": [
@@ -97,6 +103,10 @@
97103
{
98104
"command": "github.openOnVscodeDev",
99105
"when": "false"
106+
},
107+
{
108+
"command": "github.timeline.openOnGitHub",
109+
"when": "false"
100110
}
101111
],
102112
"file/share": [
@@ -152,6 +162,13 @@
152162
"when": "github.hasGitHubRepo",
153163
"group": "1_open@1"
154164
}
165+
],
166+
"timeline/item/context": [
167+
{
168+
"command": "github.timeline.openOnGitHub",
169+
"group": "1_actions@3",
170+
"when": "github.hasGitHubRepo && timelineItem =~ /git:file:commit\\b/"
171+
}
155172
]
156173
},
157174
"configuration": [

extensions/github/src/commands.ts

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as vscode from 'vscode';
7-
import { API as GitAPI, RefType } from './typings/git';
7+
import { API as GitAPI, RefType, Repository } from './typings/git';
88
import { publishRepository } from './publish';
99
import { DisposableStore, getRepositoryFromUrl } from './util';
1010
import { LinkContext, getCommitLink, getLink, getVscodeDevHost } from './links';
@@ -34,6 +34,29 @@ async function openVscodeDevLink(gitAPI: GitAPI): Promise<vscode.Uri | undefined
3434
}
3535
}
3636

37+
async function openOnGitHub(repository: Repository, commit: string): Promise<void> {
38+
// Get the unique remotes that contain the commit
39+
const branches = await repository.getBranches({ contains: commit, remote: true });
40+
const remoteNames = new Set(branches.filter(b => b.type === RefType.RemoteHead && b.remote).map(b => b.remote!));
41+
42+
// GitHub remotes that contain the commit
43+
const remotes = repository.state.remotes
44+
.filter(r => remoteNames.has(r.name) && r.fetchUrl && getRepositoryFromUrl(r.fetchUrl));
45+
46+
if (remotes.length === 0) {
47+
vscode.window.showInformationMessage(vscode.l10n.t('No GitHub remotes found that contain this commit.'));
48+
return;
49+
}
50+
51+
// upstream -> origin -> first
52+
const remote = remotes.find(r => r.name === 'upstream')
53+
?? remotes.find(r => r.name === 'origin')
54+
?? remotes[0];
55+
56+
const link = getCommitLink(remote.fetchUrl!, commit);
57+
vscode.env.openExternal(vscode.Uri.parse(link));
58+
}
59+
3760
export function registerCommands(gitAPI: GitAPI): vscode.Disposable {
3861
const disposables = new DisposableStore();
3962

@@ -72,26 +95,20 @@ export function registerCommands(gitAPI: GitAPI): vscode.Disposable {
7295
return;
7396
}
7497

75-
// Get the unique remotes that contain the commit
76-
const branches = await apiRepository.getBranches({ contains: historyItem.id, remote: true });
77-
const remoteNames = new Set(branches.filter(b => b.type === RefType.RemoteHead && b.remote).map(b => b.remote!));
78-
79-
// GitHub remotes that contain the commit
80-
const remotes = apiRepository.state.remotes
81-
.filter(r => remoteNames.has(r.name) && r.fetchUrl && getRepositoryFromUrl(r.fetchUrl));
98+
await openOnGitHub(apiRepository, historyItem.id);
99+
}));
82100

83-
if (remotes.length === 0) {
84-
vscode.window.showInformationMessage(vscode.l10n.t('No GitHub remotes found that contain this commit.'));
101+
disposables.add(vscode.commands.registerCommand('github.timeline.openOnGitHub', async (item: vscode.TimelineItem, uri: vscode.Uri) => {
102+
if (!item.id || !uri) {
85103
return;
86104
}
87105

88-
// upstream -> origin -> first
89-
const remote = remotes.find(r => r.name === 'upstream')
90-
?? remotes.find(r => r.name === 'origin')
91-
?? remotes[0];
106+
const apiRepository = gitAPI.getRepository(uri);
107+
if (!apiRepository) {
108+
return;
109+
}
92110

93-
const link = getCommitLink(remote.fetchUrl!, historyItem.id);
94-
vscode.env.openExternal(vscode.Uri.parse(link));
111+
await openOnGitHub(apiRepository, item.id);
95112
}));
96113

97114
disposables.add(vscode.commands.registerCommand('github.openOnVscodeDev', async () => {

extensions/github/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"../../src/vscode-dts/vscode.d.ts",
1313
"../../src/vscode-dts/vscode.proposed.canonicalUriProvider.d.ts",
1414
"../../src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts",
15-
"../../src/vscode-dts/vscode.proposed.shareProvider.d.ts"
15+
"../../src/vscode-dts/vscode.proposed.shareProvider.d.ts",
16+
"../../src/vscode-dts/vscode.proposed.timeline.d.ts"
1617
]
1718
}

0 commit comments

Comments
 (0)