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

时间:2010-06-03 19:43:22

标签: git git-status

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

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

当然我可以解析git status的输出,但不建议这样做,因为这个人类可读的输出容易改变。

有两个问题:

  1. 如何知道远程跟踪分支?它通常是origin/branch但不一定是。
  2. 如何获取数字?如何知道它是先行/落后?提交了多少次?那个分歧的分支案例呢?

10 个答案:

答案 0 :(得分:22)

git rev-list origin..HEAD将显示当前分支中的提交,但不显示原始提交 - 即,您是否领先于原始提交和提交。

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

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

答案 1 :(得分:18)

<强>更新

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

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

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

原始回答

似乎没有一种简单的方法可以找到一般的跟踪分支,而不需要解析比一些shell命令更多的git配置。但对于许多情况,这将有很长的路要走:

# 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找到$ tracking_branch和HEAD之间的相对差异。你可以做一件有趣的事情:

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

(注意$ tracking_branch和HEAD之间的三个点)。这将显示两个“武器”的提交,前面有一个区别标记:“&lt;”对于$ tracking_branch和“&gt;”的提交提交HEAD。

答案 2 :(得分:11)

您可以尝试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输出更稳定。

答案 3 :(得分:7)

修改 我的原始答案实际上并不是很好,因为它依赖于用户拥有一个名为“origin”的遥控器。如果当前分支除起源头之外还有一个跟踪分支,它也会失败。这些缺陷基本上使它变得毫无用处。然而,@araqnid的答案并不是最有效的方法,他到达$tracking_branch的方式不如前进。我发现获得相同功能的最有效(最快)的方法如下:

# 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)

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

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

答案 4 :(得分:5)

git status有一个--porcelain选项,用于通过脚本进行解析。它基于--short输出 - 它们在编写时几乎完全相同(有关详细信息,请参阅git status man page的“瓷质格式”部分)。主要区别在于--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或更晚版本中可用(尽管1.7.2以来git status --short --branch已可用。)

答案 5 :(得分:5)

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

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

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

要了解您在遥控器前方的距离,只需切换顺序:

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

对于更易于理解的摘要,您可以要求输入日志:

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

出于我自己的目的,我正在开发一个脚本,如果尚未设置上游,则用适当的猜测替换@{u}。不幸的是,此时没有@{d}代表下游(你要去的地方)。

答案 6 :(得分:2)

为什么这不起作用:

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

答案 7 :(得分:1)

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桥的另一端发现遥控器),并在my git-config repository on github中发布它们。例如,这是我的git-compare-upstream。有关安装说明和其他方便的相关脚本,请参阅the README

答案 8 :(得分:1)

  

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

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

这意味着您还可以选择查看配置为推送到分支的所有分支的前/后。

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

点击“Viewing Unpushed Git Commits

了解详情

答案 9 :(得分:0)

您应该使用最新版本的git

git status --porcelain --branch

并检查前面/后面:

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

-瓷器[=版本]

以易于解析的格式为脚本提供输出。这类似于简短的输出,但是在所有Git版本中都将保持稳定,无论 用户配置。有关详情,请参见下文。

-b,--branch

即使以短格式显示分支和跟踪信息。