git在同一次提交中使用两个标记进行描述

时间:2011-11-11 02:31:17

标签: git

我们偶尔在同一次提交中有两个标签。当我们为该提交使用git describe时,git describe总是返回第一个标记。我对git-describe手册页的阅读似乎表明应该返回第二个标签(这更有意义)。

  SEARCH STRATEGY
     For each committish supplied, git describe will first look for a tag which tags
     exactly that commit. Annotated tags will always be preferred over lightweight tags, 
     and tags with newer dates will always be preferred over tags with older dates. 
     If an exact match is found, its name will be output and searching will stop.

有没有办法让git describe返回第二个标签?

5 个答案:

答案 0 :(得分:4)

您是否尝试过任何git describe选项?

   --all
       Instead of using only the annotated tags, use any ref found in .git/refs/. This option enables
       matching any known branch, remote-tracking branch, or lightweight tag.

   --tags
       Instead of using only the annotated tags, use any tag found in .git/refs/tags. This option
       enables matching a lightweight (non-annotated) tag.

答案 1 :(得分:1)

我在同一提交上有两个标记约定,并希望保留git describe功能(例如脏,sha和提交计数超过标记等)。 因此,在git version 2.24.1中,由于我在一个标签和另一个标签中有一个唯一的区分字符串,因此我只使用了match运算符。您还可以使用排除

git describe --tags --match '*xXx*'

答案 2 :(得分:0)

据我所知,'git describe'不能消除轻量级标签的歧义,因此可以打印遇到的第一个标签。此代码段假定标签遵循可通过'sort -R'排序的模式,并将在给定的SHA上返回'latest'标签:

git tag --contains SHA | sort -R | tail -1

答案 3 :(得分:0)

在这种情况下,Git的行为异常且令人困惑。

当我对相同的提交执行两个标签时,我注意到在.git/refs/tags中,每个标签都有自己的提交,因此从理论上讲可以以明确的方式签出确切的标签。

实际上并非如此。

让我们说我已经提交了ABCD。我为其添加了两个标签(带注释):v1.0和v2.0。

然后我有类似的东西。

master -> ABCD hotfix -> ABCD v1.0 (3423) -> ABCD v1.0 (4234) -> ABCD

当我检出分支(例如master或hotfix)时,我注意到git只是将对分支的引用存储在.git/HEAD中,所以一切都很好,它不是模棱两可,而是特定的分支。

当我直接签出提交时,它本质上是模棱两可的。 HEAD将仅包含提交的哈希ABCD

当签出v1.0或v2.0之类的标签时,HEAD将不包含标签ref或tag commit,而是包含提交ID,就好像您直接签出提交一样!

令人困惑的是,如果签出一个分支(例如master),然后签出一个标签,则git status和describe将显示正确的标签,即签出的标签,即使它是模棱两可的!

但是,如果您随后签出另一个指向该标签的标签,它将显示原始标签。从分支切换到标签,记住该标签,而不能从标签切换到标签。

我不知道这是一个错误还是git的运行方式(我猜它是重复的(.git / logs / HEAD),但鉴于行为似乎是任意的,我可能会冒险猜测,如果您只是想使用命令从上至下获取用户已选择的内容,无论是标签,分支还是提交,那么我认为它不受可靠支持。

如果您尝试使用命令自动获取版本,则需要让用户手动输入标签或采取一些措施来消除冲突。

轻量级标签(未注释,本身没有提交,只是直接指向提交的指针)以相同的奇怪方式运行。鉴于它能够准确保留用户在一种情况下签出的位置,但在另一种情况下失败的位置,我建议这是一个错误,应予以报告。

用例是用户仅签出一件事,即使该标识符可能指向带有许多其他标识符的事物。为了方便起见,您想要获取用户输入的标识符以用作例如构建的标识符。 Git记住标识符的能力莫名其妙地不一致。

在这种情况下,您的脚本将需要尝试派生单个最佳标识符,但是如果标识符不明确,则会产生错误。您不能依靠git status之类的内容或进行描述,因为有时它们不会产生从标签到标签而不是分支到标签的切换时最后一次检出的结果。

这可以在.git/logs/HEAD中看到,该文件似乎包含用于标记报告的分支,但是一旦您位于标记上,就不会记录任何内容。

描述似乎总是返回最新的带注释(非轻量级)标记。如果要混合标签类型,则不应假定行为一致。轻量级标签似乎也使用最新版本(大概基于文件的时间戳而不是提交时间),但是没有--all--tags时不会搜索。即使使用--all,带注释的标签似乎也比最近的轻量级标签优先。

获取我可以找到的当前标签的所有标识符的唯一便捷方法是运行git show-ref并取消引用,并为当前提交使用grep。这将不包括用于排序的时间戳。

答案 4 :(得分:0)

两种方法,取决于您的需要。

方法1

git tag -l | sort -V | tail -1

如果您要检查特定格式,例如语义版本

git tag -l | grep "v[0-9]*.[0-9]*.[0-9]*$" | sort -V | tail -1

方法2

git tag --sort=committerdate | tail -1

如果您要检查特定格式,例如语义版本

git tag --sort=committerdate | grep "v[0-9]*.[0-9]*.[0-9]*$" | tail -1