[英]How read the current upstream for a git branch
我正在搜索 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语法,即将@{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
在一个案例中是--abbrev-ref
在另一个案例中是--symbolic-full-name
。)
请注意,当使用git rev-parse
的HEAD
,如果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
commmand的第一个技巧:
我的分支是当前分支并且有一个上游,我得到一条像Your branch is up-to-date with 'the_repo/the branch'
,但是我们有一个更直接的方式来了解它。
这是我如何找到与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 branch -vv
:
foo 03b325f Commit on untracked branch
master b7da42b [origin/master] Initial commit
上游(如果有)很好地显示在方括号中。
手册摘录并强调:
-v
-vv
--详细
在列表模式下,显示每个头的 sha1 和提交主题行,以及与上游分支的关系(如果有)。 如果给出两次,则打印链接工作树的路径(如果有)和上游分支的名称(另请参见 git remote show )。 请注意,当前工作树的 HEAD 不会打印其路径(它将始终是您的当前目录)。
请注意, -vv
比与-v
相同的--verbose
更详细。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.