2011-12-21 82 views
18

使用git describe您可以获取自上次标记以来提交的数量。如果您只有标签和提交数量,那么显示所描述的提交的最佳方式是什么?如何使用标签以来的提交数量来显示git提交

我知道你可以使用git log tag..,并将它连接到一个脚本来进行计数,但我希望有一个类似于git show tag~n的更优雅的解决方案。

要与

$ git describe 
v1.5-39-g5ede964 

我们将使用foo_1.5.39加入更多内容,我们使用git describe创建版本号的规划,例如。我们想要做的是知道1.5.39意味着v1.5标签之后的第39次提交,找到提交,即找到g5ede964。正如在评论中指出的那样,v1.5之后的第39次提交可能不是唯一的。因此,或许一个更好的方法来问这是什么是找到所有提交X的最好方法,以便如果HEAD指向X git describe将返回 v1.5-39-*****

+2

你可以用'git show tag〜n'来显示该标签前的第n个提交。也许我误解了一些东西...... – knittl 2011-12-21 19:54:21

+0

我相信从标签向前移动是不可能的。 git中的每个提交(除了最初的一个)都至少有一个父代,所以你可以通过提交向后退出。另一方面,这个带标签的提交(与任何其他提交一样)可能是多个提交的父对象,并且它没有任何对它的子对象的引用,所以你可以移动的唯一方法是从子对象到父对象,而不是相反方向。 – 2011-12-21 20:06:13

+0

@ KL-7谢谢,这很有道理。我在关于我们想要实现的问题上添加了更多的上下文。根据你的观点,家长不参考儿童,我猜测没有办法做到这一点。在这种情况下,如果您将此作为答案添加,我会接受它。 – Joel 2011-12-22 10:40:09

回答

4

你问的数量在一般情况下是不可能的。如果您的历史记录中有任何合并,单单提交的数量无法告诉您任何事情。

例如,给定以下回购结构:

a - b - c - d - h 
    \   /
    e - f - g 

与标签穿上a,的git describe dgit describe g输出是相同的保存为SHA1:

> git describe d 
tag-3-ge8dca33 
> git describe g 
tag-3-g4fecc2e 

这就是说,如果你没有一组并行分支同时进行,那么你可能能够将一个给定的提交编号解析回单次提交,但是如果你在标签时有一个活动的分支,那么这个可能无法工作。

如果您需要可靠的版本号,您应该坚持显式标签。

+0

查看@Sam答案 – 2016-06-29 18:36:06

2

您可以:

git log --oneline tag.. | wc -l 

这会给你的提交

+1

但是我想从标签开始的第n次提交,而不是自从标签以来提交的次数。基本上是git描述的反面。 – Joel 2011-12-21 19:52:20

+3

不要使用'git log'来编写脚本,而应该使用'git rev-list'而不是 – knittl 2011-12-21 19:54:49

+1

@knittl,你能否给这个想法添加一些细节?为什么要在''log''上加上''rev-list''? 我现在处于一种情况,使用''log''编写脚本似乎是要走的路,并且希望坚持最佳实践。 – 2012-08-25 11:31:54

19

尝试

git rev-list tag..HEAD --count 

OR

git rev-list tag.. --count 

它们的意思是一样的。

10

如果您正在寻找自上次标签提交的数目,以下为我工作

git rev-list `git rev-list --tags --no-walk --max-count=1`..HEAD --count 
0

由于Kevin's answer解释,这通常是不可能的。为了解决他提到的特殊情况的问题:

也就是说,如果你没有一堆并行分支一次进行,那么你可能能够解析一个给定的提交编号回单一提交,但如果你在标签的时候有一个活动的分支,那么这可能不起作用。

您可以使用下面的命令(n是提交的自变量个数)

git rev-list tag..HEAD --reverse | awk NR==n 
0

什么是找到所有提交X最好的办法,例如,如果HEAD指着X git describe将返回v1.5-39-*****

仍然是错误的问题。正确的问题是

如何找到所有提交X例如,如果HEAD指着X普通git describe可能永远都返回v1.5-39-*****

,它不是那么容易回答这个问题。尽管如此,没有敌人的行动这个程序将列出正确的承诺,也许其中的一些其他可能性:

ancestor=v1.5 n=39 
git rev-list --all --reverse --topo-order --parents --ancestry-path ^$ancestor \ 
| awk ' function minmore(  i) { 
       for (i=2; i <= NF; ++i) 
         if (gen[$i] > gen[$1]) 
           gen[$1]=gen[$i] 
       return ++gen[$1] 
     } 
     minmore()<=n { 
       print "[[ $(git rev-list --count "ancestor".."$1") == "n" ]] &&" 
       print "   git describe --match="ancestor" "$1 } 
     ' ancestor=$ancestor n=$n \ 
# | sh # lose the first `#` here to actually run the generated checks 

的原因的不确定性和复杂性是git describe只是试图得到一个合理的基础,所以(见its docs)它将选择最近看到的最近的当前标签,并计算所描述的历史中有多少额外的提交,并以这种方式生成一个名称。例如,新标签可以更改其首选基地,以便裸露的git describe不再生成该名称;虽然SHA是不可变的,但引用可以被重写。