如何在git中查看本地分支相对于另一个本地分支多/少了多少次提交?

17
如果我正在一个功能分支上工作,我想知道这个分支相对于主分支是落后还是超前了多少次提交。我找不到能够完成这个操作的命令。
2个回答

24

列出和计数提交: git rev-list

一种快速的方法是执行类似于git status中"upstream"的操作。具体来说,git status 只会计算当前分支上没有在上游分支中的修订版本数量。例如,考虑分支foo有一个上游分支origin/foo,并假设您已经进行了三次本地提交,然后使用git fetch带入了一个上游提交:

              L - L - L   <-- foo
            /
... - C - C
            \
              U           <-- origin/foo

这里的C代表普通提交,L代表本地提交,U代表上游提交。如果你在分支foo上运行git status,你会看到 "ahead 3, behind 1"。

以下是git如何得出这些数字:

  1. git rev-list foo --not origin/foo:这将生成一个列表,其中包含在foo上但不在origin/foo上的所有提交。也就是说,从origin/foo(即提交U)开始,划掉提交和所有之前可达的提交:这是U和所有的C提交。然后,从foo开始查找所有可达的提交,而这些提交尚未被划掉:这仅是三个L提交。

  2. 添加--count参数到git rev-list的参数中,以使其输出计数而不是原始提交ID SHA-1值。

  3. 对于git rev-list origin/foo --not foo,重复上述步骤:这是从origin/foo可达但从foo不可达的所有提交,例如此示例中只有提交U。(同样,添加--count以仅获得计数,而不是实际的提交ID。)

请注意,foo --not origin/foogitrevisions语法中也可以写成origin/foo..foo。(在git status的情况下,它始终查看当前分支 - 这个分支通过HEAD命名 - 以及其上游。您可以使用@{upstream}语法来获取上游的名称,或缩短为@{u};如果完全没有列出名称,则默认使用HEAD。因此,要重新实现git status,您可以只查看git rev-list --count ..@{u}git rev-list --count @{u}..。)

在本地分支上使用rev-list与使用git cherry

因此,如果您想计算从分支feature可达但从分支master不可达的提交数量,您可以使用相同的方法,但使用名称featuremastergit rev-list语法master..feature命名从feature可达但不从master可达的所有提交,而--count会得到计数:

git rev-list --count master..feature
如果您从一个分支挑选了一些提交到另一个分支,使它们具有不同的提交ID但相同的差异,则这将“重复计算”。例如,假设feature有五个提交,而master没有,但随后您(或其他人)决定将这五个提交中的一个挑选到master中,那么现在可能是这样的:
              D - E - F - G - H   <-- feature
            /
... - C - C
            \
              F'                  <-- master

其中F'基本上只是提交F的副本。如果您要求git rev-list计算不在master上的feature提交次数,那么您将得到5;但如果您要求git cherry查找不在master上的feature提交,它将从列表中消除提交F,因为它会看到F'F的副本。因此,如果您计算git cherry列出的提交次数,则会得到4而不是5。


那么你会说挑选过的清单(cherry-pick)比修订列表更好(或更准确)吗? - Red2678
@Red2678:如果你想要那个数字,那就更好;如果你想要另一个数字,那就更糟。也就是说,你想要计算“提交次数”,还是“具有不同补丁ID的提交次数”? - torek
@torrek 我看到你的意思了 ;) 我猜这确实取决于情况。如果在该环境中挑选代码是常见做法,那么您肯定要确保计算它们。话虽如此,如果您不知道某人是否在提交时挑选了代码,那么使用 cherry 将会更加“准确”。 - Red2678

12

使用 git cherry 命令查找存在于一个分支中而不存在于另一个分支中的提交记录。

git cherry -v master feature
它将列出功能分支中存在但在主分支中不存在的所有提交。

同样,

git cherry -v feature master 

会列出主分支中存在但特性分支中不存在的所有提交。

您还可以提供第三个参数,以选择起始点。

git cherry -v feature master 1b219e

更新:

您可以创建一个别名来将这两个内容合并。

[alias]
    mydiff = !sh -c 'echo "Commits in $2 not in $1" && git cherry -v $1 $2 && echo "Commits in $1 not in $2" && git cherry -v $2 $1' -

使用,

git mydiff master feature

1
好的,谢谢。有没有一种方法可以同时得到一个计数,即有多少个在前面,有多少个在后面? - timetofly
你可以创建一个别名。 - pratZ
请注意,git cherry实际上比git status的方法更高级,因为它比较差异,我将在另一个答案中写出。 - torek
1
@Blossoming_Flower 我知道这个帖子发得有点晚,但我自己也需要,所以我将上面的别名与管道结合起来,然后将其传递给 wc -l,它会计算输出的行数。我的别名设置如下:[alias] cdiffcount = !sh -c 'echo "Commits in $2 not in $1: " && git cherry $1 $2 | wc -l && echo "Commits in $1 not in $2: " && git cherry $2 $1 | wc -l' - - Michael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接