我正在寻找一个git命令来了解现有分支所关联的上游(如果有的话)。
(与“写”命令git branch --set-upstream-to=...
相关的某种“读取”命令)
原因是我使用一个连接到几个远程仓库的分支,我想在更改它之前检查这个分支是否已经与正确的上游连接。
我正在寻找一个git命令来了解现有分支所关联的上游(如果有的话)。
(与“写”命令git branch --set-upstream-to=...
相关的某种“读取”命令)
原因是我使用一个连接到几个远程仓库的分支,我想在更改它之前检查这个分支是否已经与正确的上游连接。
git rev-parse
。$ git rev-parse --abbrev-ref master@{u}
weird/master
如果没有设置上游,您将会得到:
fatal: no upstream configured for branch 'master'
(以及非零的退出码)。如果不想看到错误消息,请将stderr重定向到/dev/null
:
if master_upstream=$(git rev-parse --abbrev-ref master@{u} 2>/dev/null); then
master_has_upstream=true
else
master_has_upstream=false
fi
例如。
Anthony Sottile的回答通常可以得到正确的名称,但并非总是如此。特别是当origin
的remote.origin.fetch
设置不是标准设置时,请注意以下内容:
$ 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]
请注意,虽然远程是以名称origin
命名的,但远程跟踪分支是以weird/master
、weird/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
但是如果远程跟踪分支名称为origin/master
,.git/config
文件中的内容仍然与预期相同:
[branch "master"]
remote = origin
merge = refs/heads/master
使用:
branch="$(git branch | grep '\*' | cut -d' ' -f2-)"
这样做效果已经足够好了(虽然通常应该使用git symbolic-ref --short HEAD
来获取当前分支的名称:见下文)。
remote="$(git config "branch.${branch}.remote")"
这部分完美地工作了——它获取了远程名称。
remote_branch="$(git config "branch.${branch}.merge" | cut -d/ -f3-)"
我们犯了错误,需要使用git rev-parse
及gitrevisions语法,以确定指定分支的"上游(upstream)"。具体方式是,在分支名后附加@{u}
或@{upstream}
。通常情况下,git rev-parse
将其转换为哈希ID,但是通过使用--abbrev-ref
它将打印名称的短版本,或者通过--symbolic-full-name
打印名称的长版本:
$ git rev-parse --symbolic-full-name master@{u}
refs/remotes/weird/master
我不知道为什么一个地方用 --abbrev-ref
拼写,而另一个地方用 --symbolic-full-name
。
需要注意的是,在使用 git rev-parse
时,如果 HEAD
是分离状态,那么答案是符号 HEAD
。也就是说,在任何 Git 存储库中,即使打印符号名称,git rev-parse HEAD
始终成功。但对于 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
因此,要解决HEAD
(查找当前分支),请选择要使用的命令,根据您在“没有当前分支”情况下想要的行为。
以下是我如何以适合脚本处理的方式找到与 git status
相同的答案的方法:
$ branch="$(git branch | grep '\*' | cut -d' ' -f2-)"
$ remote="$(git config "branch.${branch}.remote")"
$ remote_branch="$(git config "branch.${branch}.merge" | cut -d/ -f3-)"
$ echo "${branch} is tracking ${remote}/${remote_branch}"
print_locking_less is tracking origin/master
.git/config
中,格式如下:[branch "print_locking_less"]
remote = origin
merge = refs/heads/master
.git/config
的信息,这也很有趣。 - herve-guerin只需使用git branch -vv
命令:
foo 03b325f Commit on untracked branch
master b7da42b [origin/master] Initial commit
上游(如果有)会以方括号的形式很好地显示出来。
摘自手册,并加重了语气:
-v
-vv
--verbose
在列表模式下,显示每个头的sha1和提交主题行,以及与上游分支(如果有)的关系。 如果给定两次,则还会打印链接工作树(如果有)的路径和 上游分支的名称(另请参见git remote show)。请注意,当前工作树的HEAD不会被打印出来(它将始终是您的当前目录)。
请注意,-vv
比--verbose
更详细,而-v
与--verbose
相同。
git status
命令的小技巧:Your branch is up-to-date with 'the_repo/the branch'
的信息,但我更希望有一种更直接的方式来知道这个信息。
origin
,因此我将使用您的语法git rev-parse --abbrev-ref 'mybranch'@{upstream}
。 - herve-guerin