如何读取git分支的当前上游

her*_*rin 4 git git-branch upstream-branch

我正在搜索git命令以了解与现有分支(如果有)关联的上游。
(某种与“ write”命令相关联的“ read”命令git branch --set-upstream-to=...
,原因是我使用了一个分支,该分支与多个远程存储库连接,并且我想在更改分支之前检查该分支是否已经与右上游连接。

tor*_*rek 5

TL; DR:使用 git rev-parse

$ git rev-parse --abbrev-ref master@{u}
weird/master
Run Code Online (Sandbox Code Playgroud)

如果未设置上游,则得到:

fatal: no upstream configured for branch 'master'
Run Code Online (Sandbox Code Playgroud)

(以及非零退出代码)。/dev/null如果您不希望重定向,则将stderr重定向为丢弃该错误消息:

if master_upstream=$(git rev-parse --abbrev-ref master@{u} 2>/dev/null); then
    master_has_upstream=true
else
    master_has_upstream=false
fi
Run Code Online (Sandbox Code Playgroud)

例如。

说明

Anthony Sottile的答案 通常会为您提供正确的名称,但并非总是如此。尤其要注意当remote.origin.fetch设置origin不是标准时会发生什么:

$ git init
Initialized empty Git repository in .../tmp/tt/.git/
$ git remote add origin git://github.com/git/git
$ git config remote.origin.fetch '+refs/heads/*:refs/remotes/weird/*'
$ git fetch
remote: Counting objects: 231294, done.
remote: Compressing objects: 100% (663/663), done.
remote: Total 231294 (delta 0), reused 662 (delta 0), pack-reused 230631
Receiving objects: 100% (231294/231294), 93.03 MiB | 3.54 MiB/s, done.
Resolving deltas: 100% (170261/170261), done.
From git://github.com/git/git
 * [new branch]          maint      -> weird/maint
 * [new branch]          master     -> weird/master
 * [new branch]          next       -> weird/next
 * [new branch]          pu         -> weird/pu
 * [new branch]          todo       -> weird/todo
 * [new tag]             v2.14.2    -> v2.14.2
[lots more tags snipped]
Run Code Online (Sandbox Code Playgroud)

请注意,虽然将remote命名为origin,但将将remote-tracking 分支命名为weird/masterweird/next依此类推。它实际上有效:

$ git checkout master
Branch master set up to track remote branch master from origin.
Already on 'master'
$ git status
On branch master
Your branch is up-to-date with 'weird/master'.

nothing to commit, working tree clean
Run Code Online (Sandbox Code Playgroud)

但是,.git/config如果远程跟踪分支名称是origin/master

[branch "master"]
    remote = origin
    merge = refs/heads/master
Run Code Online (Sandbox Code Playgroud)

使用方法:

 branch="$(git branch | grep '\*' | cut -d' ' -f2-)"
Run Code Online (Sandbox Code Playgroud)

效果很好(尽管应该经常使用它git symbolic-ref --short HEAD来获取当前的分支名称:请参见下文)。

remote="$(git config "branch.${branch}.remote")"
Run Code Online (Sandbox Code Playgroud)

这部分工作得很好-它获得了遥控器的名称。

remote_branch="$(git config "branch.${branch}.merge" | cut -d/ -f3-)"
Run Code Online (Sandbox Code Playgroud)

这是我们出问题的地方。我们需要git rev-parse为“指定分支的上游” 使用gitrevisions语法,该语法将追加@{u}或添加@{upstream}到分支名称中。通常,git rev-parse将其转换为哈希ID,但使用时--abbrev-ref,将显示名称的简短版本;使用时,将显示名称的简短--symbolic-full-name版本:

$ git rev-parse --symbolic-full-name master@{u}
refs/remotes/weird/master
Run Code Online (Sandbox Code Playgroud)

(我不知道为什么--abbrev-ref在一种情况下又--symbolic-full-name在另一种情况下将其拼写。)

请注意,在git rev-parseon上使用时HEAD,如果HEAD分离,答案为符号HEAD。也就是说git rev-parse HEAD,即使在打印符号名称时,在任何Git存储库中,总会成功。这是正确的git symbolic-ref,但:

$ git checkout --detach
HEAD is now at ea220ee40... The eleventh batch for 2.15
$ git rev-parse --abbrev-ref HEAD
HEAD
$ git rev-parse --symbolic-full-name HEAD
HEAD
$ git symbolic-ref HEAD
fatal: ref HEAD is not a symbolic ref
Run Code Online (Sandbox Code Playgroud)

因此,要解决该问题HEAD(查找当前分支),请在“无当前分支”情况下根据所需的行为选择要使用的命令。