47

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

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

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

有两个问题:

  1. 如何知道远程跟踪的分支?它经常origin/branch但不一定是。
  2. 如何获得数字?如何知道它是否领先/落后?通过多少次提交?那么分歧分支案例呢?
4

10 回答 10

23

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

git rev-list HEAD..origin将显示相反的情况。

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

于 2010-06-03T20:08:00.567 回答
20

更新

正如 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}..向我展示“排队”的提交准备好推送。

原始答案

一般来说,似乎没有一种简单的方法可以找到跟踪分支,而无需解析比一些 shell 命令中实际可行的更多的 git config。但在许多情况下,这将有很长的路要走:

# 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. 你可以做一件有趣的事:

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

(注意$tracking_branch 和 HEAD 之间的三个点)。这将显示两个“臂”上的提交,前面有一个区别标记:“<”表示 $tracking_branch 上的提交,“>”表示 HEAD 上的提交。

于 2010-06-03T22:01:21.837 回答
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输出更稳定。

于 2010-06-04T02:59:16.107 回答
8

在现代版本的 git@{u}中,如果设置了一个,则指向当前分支的上游。

所以要计算你在远程跟踪分支后面有多少次提交:

git rev-list --count HEAD..@{u}

要查看您领先遥控器多远,只需切换顺序:

git rev-list --count @{u}..HEAD

要获得更易于阅读的摘要,您可以要求提供日志:

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

出于我自己的目的,我正在编写一个脚本@{u},如果尚未设置上游,则该脚本将替换为适当的猜测。不幸的是,此时没有@{d}代表下游(您将推送到的地方)。

于 2013-12-13T09:19:55.520 回答
7

编辑: 我原来的答案实际上不是很好,因为它依赖于用户拥有一个名为“origin”的遥控器。如果当前分支除了 origin-head 之外还有一个跟踪分支,它也会失败。这些缺陷基本上使它毫无用处。但是,@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 系统。

于 2012-11-01T06:52:02.340 回答
5

git status有一个--porcelain用于脚本解析的选项。它基于--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或更高版本中可用(尽管git status --short --branch1.7.2开始可用)。

于 2013-08-19T14:40:59.227 回答
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 
于 2012-06-04T15:23:00.397 回答
1

araqnid 答案中的最上面的代码块对我不起作用,所以自 18 个月前编写以来,git 中的某些内容可能发生了变化。如果我改变它会起作用:

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 桥的另一侧发现远程),并将它们发布在我的 git-config 存储库中 github。例如,这是我的git-compare-upstream。有关安装说明和其他方便的相关脚本,请参阅自述文件。

于 2011-11-28T10:19:52.050 回答
1

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

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

这意味着您有另一个选项可以查看配置为推送到分支的所有分支的前方/后方。

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

在“查看未推送的 Git 提交”中查看更多信息

于 2015-06-08T22:53:05.183 回答
0

对于最新版本的 git,您应该使用

git status --porcelain --branch

并检查前后:

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

--瓷器[=版本]

以易于解析的格式为脚本提供输出。这与短输出类似,但在 Git 版本之间以及无论用户配置如何都将保持稳定。详情见下文。

-b,--分支

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

于 2020-09-25T20:33:59.987 回答