Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit adb243b

Browse files
authored
fix: correctly obtain Git remote and parse it (#38)
* fix(vscode-github): correctly obtain Git remote and parse it * fix(vscode-github): refactoring * fix: github urls could contain colon valid github urls could as well contain a colon to separate path (e.g. git@github.com:knisterpeter/vscode-github.git)
1 parent 19274a4 commit adb243b

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

src/git.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,35 @@
11
import * as execa from 'execa';
22

3+
import { parse } from 'url';
4+
5+
/**
6+
* Look in .git/config for a remote origin and parses it to get username and repository.
7+
*
8+
* @param {string} cwd The directory to find the .git/config file in.
9+
* @return {Promise<string[]>} A tuple of username and repository (e.g. KnisterPeter/vscode-github)
10+
* @throws Throws if the could not be parsed as a github url
11+
*/
312
export async function getGitHubOwnerAndRepository(cwd: string): Promise<string[]> {
4-
return execa('git', ['config', '--get-regexp', 'remote\\.origin\\.url'], {cwd})
5-
.then(result => {
6-
const match = result.stdout.match(
7-
/^remote\.origin\.url (?:git@github\.com:|https:\/\/github.com\/)(.*?)\/(.*?)(?:.git)?$/);
8-
if (!match) {
9-
throw new Error('Not a github project?');
10-
}
11-
return [match[1], match[2]];
12-
});
13+
// as we expect this function to throw on non-Github repos we can chain
14+
// whatever calls and they will thrown on non-correct remotes
15+
const remote = (await execa('git', 'config --local --get remote.origin.url'.split(' '), {cwd})).stdout.trim();
16+
if (!remote.length) {
17+
throw new Error('Git remote is empty!');
18+
}
19+
20+
// git protocol remotes, may be git@github:username/repo.git
21+
// or git://github/user/repo.git, GITHUB domain name is not case-sensetive
22+
if (remote.startsWith('git')) {
23+
return remote.match(/^git(?:@|\:\/\/)github.com[\/:](.*?)\/(.*?)(?:.git)?$/i)!.slice(1, 3);
24+
}
25+
26+
// it must be http or https based remote
27+
const { hostname, pathname } = parse(remote);
28+
// github.com domain name is not case-sensetive
29+
if (!pathname || !hostname || !/^github\.com$/i.test(hostname)) {
30+
throw new Error('Not a Github remote!');
31+
}
32+
return pathname.match(/\/(.*?)\/(.*?)(?:.git)?$/)!.slice(1, 3);
1333
}
1434

1535
export async function getCurrentBranch(cwd: string): Promise<string|undefined> {

0 commit comments

Comments
 (0)