Skip to content
This repository was archived by the owner on Mar 10, 2022. It is now read-only.

Commit 628c810

Browse files
feat: implement a better way to resolve remote and upstream branch (#122)
Co-authored-by: Nick Snyder <[email protected]>
1 parent f0a37fa commit 628c810

File tree

1 file changed

+40
-5
lines changed

1 file changed

+40
-5
lines changed

src/git.ts

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,29 @@ import * as path from 'path'
33
import { log } from './log'
44
import { getRemoteUrlReplacements } from './config'
55

6+
/**
7+
* Returns [remote, upstream branch].
8+
* Empty remote is returned if the upstream branch points to a local branch.
9+
* Empty upstream branch is returned if there is no upstream branch.
10+
*/
11+
async function gitRemoteBranch(repoDirectory: string): Promise<[string, string]> {
12+
try {
13+
const { stdout } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD@{upstream}'], { cwd: repoDirectory })
14+
const remoteAndBranch = stdout.split('/')
15+
if (remoteAndBranch.length === 2) {
16+
const [remote, branch] = remoteAndBranch
17+
return [remote, branch]
18+
}
19+
if (remoteAndBranch.length === 1) {
20+
// The upstream branch points to a local branch.
21+
return ['', remoteAndBranch[0]]
22+
}
23+
return ['', '']
24+
} catch {
25+
return ['', '']
26+
}
27+
}
28+
629
/**
730
* Returns the names of all git remotes, e.g. ["origin", "foobar"]
831
*/
@@ -29,9 +52,16 @@ async function gitRemoteURL(repoDirectory: string, remoteName: string): Promise<
2952
}
3053

3154
/**
32-
* Returns the remote URL of the first Git remote found.
55+
* Returns the remote URL.
3356
*/
3457
async function gitDefaultRemoteURL(repoDirectory: string): Promise<string> {
58+
const [remote] = await gitRemoteBranch(repoDirectory)
59+
if (remote !== '') {
60+
return gitRemoteURL(repoDirectory, remote)
61+
}
62+
63+
// If we cannot find the remote name deterministically, we use the first
64+
// Git remote found.
3565
const remotes = await gitRemotes(repoDirectory)
3666
if (remotes.length === 0) {
3767
throw new Error('no configured git remotes')
@@ -52,12 +82,17 @@ async function gitRootDirectory(repoDirectory: string): Promise<string> {
5282
}
5383

5484
/**
55-
* Returns either the current branch name of the repository OR in all
56-
* other cases (e.g. detached HEAD state), it returns "HEAD".
85+
* Returns either the current remote branch name of the repository OR in all
86+
* other cases (e.g. detached HEAD state, upstream branch points to a local
87+
* branch), it returns "HEAD".
5788
*/
5889
async function gitBranch(repoDirectory: string): Promise<string> {
59-
const { stdout } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: repoDirectory })
60-
return stdout
90+
const [origin, branch] = await gitRemoteBranch(repoDirectory)
91+
if (origin !== '') {
92+
// The remote branch exists.
93+
return branch
94+
}
95+
return 'HEAD'
6196
}
6297

6398
/**

0 commit comments

Comments
 (0)