git:以编程方式知道分支在远程分支前后的数量

我想提取在git status之后打印的信息,如下所示:

 # On branch master # Your branch is ahead of 'origin/master' by 2 commits. 

当然,我可以parsinggit status的输出,但是这并不推荐,因为这个人类可读的输出可能会改变。

有两个问题:

  1. 如何知道远程跟踪分支? 它往往是origin/branch但不一定是。
  2. 如何获得数字? 如何知道这是前/后? 通过多less次提交? 那么分歧的情况呢?

更新

正如amalloy所指出的那样,最近的git版本通过为跟踪分支提供“branchname @ {upstream}”(或“branchname @ {u}”或“@ {u}”)支持为给定分支查找匹配的跟踪分支的头)。 这有效地取代了下面的脚本。 你可以做:

 git rev-list @{u}.. git rev-list --left-right --boundary @{u}... gitk @{u}... 

等等。例如,我有git q别名git log --pretty='...' @{u}..显示我“排队”提交准备推送。

原来的答案

一般来说,似乎没有一种简单的方法来查找跟踪分支,而不用parsing更多的gitconfiguration,而不是在几个shell命令中实际使用的。 但是在很多情况下,这将会有很长的路要走:

 # 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 

另一个更蛮力的方法是:

 git rev-list HEAD --not --remotes 

jamessan的答案解释了如何使用git rev-listfind$ tracking_branch和HEAD之间的相对差异。 你可以做一件有趣的事情:

 git rev-list --left-right $tracking_branch...HEAD 

(注意$ tracking_branch和HEAD之间的三个点)。 这将显示在前面有一个区别标记的“武器”的提交:对于$ tracking_branch提交的“<”和对于在HEAD上的提交的“>”。

git rev-list origin..HEAD将显示您当前分支中的提交,但不是原点 – 即,您是否在原点之前以及提交哪个提交。

git rev-list HEAD..origin会显示相反的结果。

如果两个命令都显示提交,那么你有分支。

你可以试试git branch -v -v 。 用-v标志给出两次,它输出上游分支的名称。 示例输出:

 * devel 7a5ff2c [origin/devel: ahead 1] smaller file status overlay icons master 37ca389 [origin/master] initial project check-in. 

我认为这个格式比git status输出更稳定。

编辑:我原来的答案其实不是很好,因为它依靠用户有一个远程调用“起源”。 如果当前分支除了始发头之外还有一个追踪分支,它也失败了。 这些缺陷基本上使它无用。 然而,@araqnid的回答并不是最有效的方法,他到达$tracking_branch方式不如海峡两岸。 我发现获得相同function的最有效(最快)的方法如下:

 # 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 

原来的答案:(低,但为清晰起见)

也许我能find的最简单的方法(受@insidepower的启发)

 # count the number of logs behind=$(git log --oneline HEAD..origin | wc -l) ahead=$( git log --oneline origin..HEAD | wc -l) 

我以前一直在使用@araqnid的方法,但现在我想我会把我的一些脚本移到这个方法,因为它更简单。 这应该适用于任何Unix系统。

在现代版本的git中, @{u}指向当前分支的上游(如果已经设置)。

所以要计算远程跟踪分支后面的提交数量:

 git rev-list HEAD..@{u} | wc -l 

而要查看远在遥远的地方,只需切换顺序:

 git rev-list @{u}..HEAD | wc -l 

要获得更具人性化的摘要,您可以请求一个日志:

 git log --pretty=oneline @{u}..HEAD 

出于我自己的目的,我正在研究一个脚本,如果尚未设置上游,那么将以适当的猜测replace@{u} 。 不幸的是,目前没有@{d}来代表下游(你将推到哪里)。

git status有一个--porcelain选项,用于脚本parsing。 它基于--short输出 – 在编写时几乎是相同的(详细信息请参阅git status手册页的“Porcelain Format”一节)。 主要区别在于 – --short有颜色输出。

默认情况下,不显示分支信息,但是如果添加--branch选项,则会得到如下输出:

 git status --short --branch ## master...origin/master [ahead 1] ?? untrackedfile.txt ... 

如果你是最新的(获取后),支线将只是:

 ## master 

如果你在前面:

 ## master...origin/master [ahead 1] 

如果你在后面:

 ## master...origin/master [behind 58] 

对于两者:

 ## master...origin/master [ahead 1, behind 58] 

请注意, git status --porcelain --branch仅在1.7.10.3或更高版本中可用(尽pipegit status --short --branch自1.7.2开始可用)。

在araqnid的答案中的代码的顶部块不适合我,所以也许在git已经改变了18个月前写了。 它可以工作,如果我改变:

 tracking_branch=refs/remotes/$remote/$remote_branch 

 tracking_branch=$remote/$remote_branch 

但是,在跟踪本地分支时仍然存在问题,在这种情况下,您必须修剪远程部分(变成'。'):

 tracking_branch=${tracking_branch#./} 

然后你可以通过编程的方式获得后面和前面的修改次数,如下所示:

 set -- `git rev-list --left-right --count $tracking_branch...HEAD` behind="$1" ahead="$2" 

我已经编写了脚本来完成所有这些(还有更多 – 例如,他们也可以尝试在git-svn桥的另一侧发现远程控制台),并将它们发布到github上的git-config存储库中 。 例如,这是我的git-compare-upstream 。 有关安装说明和其他方便的相关脚本,请参见自述文件。

为什么不能这样工作:

 #!/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 

如何知道远程跟踪分支? 它往往是origin/branch但不一定是。

Git 2.5+引入了一个新的快捷方式,引用您正在推送的分支。 @{push} :这将是在这里感兴趣的远程跟踪分支。

这意味着您有另一个选项可以查看所有configuration为推送到分支的分支。

 git for-each-ref --format="%(push:track)" refs/heads 

请参阅“ 查看未压缩的Git提交 ”