@@ -3,6 +3,29 @@ import * as path from 'path'
33import { log } from './log'
44import { 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 */
3457async 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 */
5889async 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