繁体   English   中英

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

[英]How read the current upstream for a git branch

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

TL; DR:使用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的回答 通常会给你正确的名字,但并不总是如此。 特别是,观察当originremote.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/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

但是如果远程跟踪分支名称是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-parseHEAD ,如果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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM