git: programmatically know by how much the branch is ahead/behind a remote branch
我想提取在
1 2 | # On branch master # Your branch is ahead of 'origin/master' by 2 commits. |
当然,我可以解析
有两个问题:
如果两个命令都显示提交,那么您就有了不同的分支。
更新
正如Amalloy所指出的,Git的最新版本支持通过给"branchname@upstream"(或"branchname@u",或"@u"(用于head的跟踪分支)查找给定分支的匹配跟踪分支。这实际上取代了下面的脚本。你可以做到:
1 2 3 | git rev-list @{u}.. git rev-list --left-right --boundary @{u}... gitk @{u}... |
例如,我将
原始答案
一般来说,要找到跟踪分支似乎不是一个简单的方法,不需要解析比几个shell命令实际更多的git-config。但在许多情况下,这将有很长的路要走:
1 2 3 4 5 6 7 8 9 10 11 | # work out the current branch name currentbranch=$(expr $(git symbolic-ref HEAD) : 'refs/heads/\(.*\)') [ -n"$currentbranch" ] || die"You don't seem to be on a branch" # look up this branch in the configuration remote=$(git config branch.$currentbranch.remote) remote_ref=$(git config branch.$currentbranch.merge) # convert the remote ref into the tracking ref... this is a hack remote_branch=$(expr $remote_ref : 'refs/heads/\(.*\)') tracking_branch=refs/remotes/$remote/$remote_branch # now $tracking_branch should be the local ref tracking HEAD git rev-list $tracking_branch..HEAD |
另一种更野蛮的方法:
1 | git rev-list HEAD --not --remotes |
Jamessan的回答解释了如何使用
1 | git rev-list --left-right $tracking_branch...HEAD |
(注意$tracking_branch和head之间有三个点)。这将显示两个"手臂"上的承诺,前面有一个区别标记:"<"表示在$tracking_分支上的承诺,">"表示在头部的承诺。
你可以试试
1 2 | * devel 7a5ff2c [origin/devel: ahead 1] smaller file status overlay icons master 37ca389 [origin/master] initial project check-in. |
我认为这种格式比
编辑:我的原始答案实际上不是很好,因为它依赖于用户有一个称为"来源"的远程设备。如果当前分支除了原点之外还有一个跟踪分支,那么它也会失败。这些缺陷基本上使它无用。然而,@araqnid的回答并不是最有效的方法,他到达
1 2 3 4 5 6 7 | # get the tracking-branch name tracking_branch=$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)) # creates global variables $1 and $2 based on left vs. right tracking # inspired by @adam_spiers set -- $(git rev-list --left-right --count $tracking_branch...HEAD) behind=$1 ahead=$2 |
原始答案:(次,但为了清楚起见)
也许是我能找到的最简单的方法(灵感来自@insidepower)
1 2 3 | # count the number of logs behind=$(git log --oneline HEAD..origin | wc -l) ahead=$( git log --oneline origin..HEAD | wc -l) |
我以前使用过@araqnid的方法,但现在我想我将把一些脚本移到这个方法,因为它要简单得多。这应该适用于任何UNIX系统。
在Git的现代版本中,如果设置了一个分支,那么
因此,要计算远程跟踪分支后面有多少提交:
1 | git rev-list HEAD..@{u} | wc -l |
要查看遥控器的领先程度,只需切换顺序:
1 | git rev-list @{u}..HEAD | wc -l |
要获得更易于阅读的摘要,您可以要求输入日志:
1 | git log --pretty=oneline @{u}..HEAD |
为了我自己的目的,我正在编写一个脚本,如果没有设置上游,它将用适当的猜测来替换
默认情况下,不显示分支信息,但如果添加
1 2 3 4 | git status --short --branch ## master...origin/master [ahead 1] ?? untrackedfile.txt ... |
如果您是最新的(在提取之后),分支行将只是:
1 | ## master |
如果你在前面:
1 | ## master...origin/master [ahead 1] |
如果你落后了:
1 | ## master...origin/master [behind 58] |
两者兼而有之:
1 | ## master...origin/master [ahead 1, behind 58] |
注意,
为什么这样不行:
1 2 3 4 5 6 7 8 | #!/bin/sh git diff origin/master..HEAD --quiet --exit-code RETVAL=$? if [ $RETVAL -gt 0 ]; then echo"You need to git push!" else echo"No git push necessary!" fi |
How to know the remote tracked branch? It is often
origin/branch but need not be.
Git2.5+引入了一个新的快捷方式,它引用了您要推到的分支。
这意味着对于配置为推送到分支的所有分支,您还有另一个选项来查看前面/后面。
1 | git for-each-ref --format="%(push:track)" refs/heads |
在"查看未提交的git提交"中查看更多信息
Araqnid的答案中最重要的部分代码对我来说不起作用,所以也许自18个月前Git编写以来,它的某些内容已经发生了变化。如果我改变了,它就会工作:
1 | tracking_branch=refs/remotes/$remote/$remote_branch |
到
1 | tracking_branch=$remote/$remote_branch |
但是,在跟踪本地分支时仍然存在一个问题,在这种情况下,您必须修剪远程部分(它变为"."):
1 | tracking_branch=${tracking_branch#./} |
然后,您可以通过编程方式获得前后的修订数量,如下所示:
1 2 3 | set -- `git rev-list --left-right --count $tracking_branch...HEAD` behind="$1" ahead="$2" |
我已经编写了一些脚本来完成所有这些工作(而且更多,例如,他们还可以尝试在Git SVN网桥的另一侧发现远程设备),并将它们发布到GitHub上的Git配置存储库中。例如,这里是我的Git比较上游。有关安装说明和其他方便的相关脚本,请参阅自述文件。