git:以编程方式知道分支在远程分支前后的数量
我想提取在git status
之后打印的信息,如下所示:
# On branch master # Your branch is ahead of 'origin/master' by 2 commits.
当然,我可以parsinggit status
的输出,但是这并不推荐,因为这个人类可读的输出可能会改变。
有两个问题:
- 如何知道远程跟踪分支? 它往往是
origin/branch
但不一定是。 - 如何获得数字? 如何知道这是前/后? 通过多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-list
find$ 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提交 ”