git describe 在同一个提交上使用两个标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8089002/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 06:09:28  来源:igfitidea点击:

git describe with two tags on the same commit

git

提问by Bill Door

We occasionally have two tags on the same commit. When we use git describe for that commit, git describe always returns the first tag. My reading of the git-describe man page seems to indicate that the second tag should be returned (which makes more sense).

我们偶尔会在同一个提交上有两个标签。当我们对该提交使用 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.
  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.

Is there a way to have git describereturn the second tag?

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

回答by Adrian Cornish

Have you tried any of the options to git describe?

您是否尝试过 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.

回答by qneill

From all I can tell, 'git describe' cannot disambiguate lightweight tags and so prints the first one it encounters. This snippet assumes tags follow a pattern sortable by 'sort -R' and will return the 'latest' tag on a given SHA:

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

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

回答by jgmjgm

Git's behaviour in this case is bizarre and confusing.

在这种情况下,Git 的行为既奇怪又令人困惑。

When I make two tags to the same commit, I notice that in .git/refs/tagsthat each of the tags has it's own commit so it's theoretically possible to checkout an exact tag in a unambiguous fashion.

当我为同一个提交制作两个标签时,我注意到.git/refs/tags每个标签都有自己的提交,因此理论上可以以明确的方式签出一个确切的标签。

In practice that's not so.

在实践中并非如此。

Lets say I have commit ABCD. I make two tags to it (annotated), v1.0 and v2.0.

假设我已经提交了 ABCD。我给它做了两个标签(带注释),v1.0 和 v2.0。

I then have something like this..

然后我有这样的事情..

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

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

When I checkout a branch such as master or hotfix, I notice that git simply stores in .git/HEADthe ref to the branch so all is good, it's not ambiguous but a specific branch.

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

When I checkout the commit directly, it will be inherently ambiguous. HEAD will contain simply the hash of the commit, ABCD.

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

When you checkout a tag such as v1.0 or v2.0, HEAD will not contain the tag ref or tag commit but instead the commit id, as if you checked out the commit directly!

当您检出 v1.0 或 v2.0 等标签时,HEAD 将不包含标签引用或标签提交,而是包含提交 ID,就像您直接检出提交一样!

Where this becomes confusing is that if you checkout a branch such as master, then check out a tag, git status and describe will show the right tag, the one that you checked out, even though it's ambiguous!

令人困惑的地方在于,如果您检出一个分支,例如 master,然后检出一个标签,git status 和 describe 将显示正确的标签,即您检出的标签,即使它不明确!

If you then however checkout another tag pointing to the same, it'll show the original tag. Switching from branch to tag, remembers the tag, switching from tag to tag doesn't.

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

I don't know if this is a bug or how git is even doing it (I'm guessing it repeats (.git/logs/HEAD) but given the behaviour appears arbitrary I'd hazard a guess that if you simply want to use a command to get at what the user has selected from the top down be it a tag, branch or commit then I don't think that's reliably supported.

我不知道这是否是一个错误,或者 git 是如何做到的(我猜它会重复(.git/logs/HEAD)但鉴于行为似乎是任意的,我会冒险猜测如果你只是想使用命令来获取用户自上而下选择的内容,无论是标签、分支还是提交,我认为这不是可靠支持的。

If you're trying to use a command to get at the version automatically then you're going to need to either have the user manually enter the tag or have some procedure in place to eliminate collisions.

如果您尝试使用命令自动获取版本,那么您将需要让用户手动输入标签或制定一些程序来消除冲突。

Lightweight tags (not annotated, don't have a commit themselves, are just a pointer straight to a commit) behave in the same strange manner. Given it's able to preserve exactly where the user checked out in one case but fails in the other, I'd propose that it's a bug and should be reported.

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

The use case for this is that the user only checks out one thing, even though that identifier might point to something with many other identifiers. For convenience, you want to get the identifier the user put in to use as an identifier for example for a build. Git's ability to remember that identifier is inexplicably inconsistent.

这个用例是用户只检查一件事,即使该标识符可能指向具有许多其他标识符的东西。为方便起见,您希望获取用户输入的标识符以用作例如构建的标识符。Git 记住标识符的能力莫名其妙地不一致。

In this case your scripts will need to attempt to derive a single best identifier but if the identifier is ambiguous it should produce an error. You cannot rely on things such as git status or describe as sometimes they'll not produce what was last checked out as seen when switching from tag to tag rather than branch to tag.

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

This can be seen in .git/logs/HEADwhich appears to contain branch to tag reports but once you're on a tag doesn't log anything.

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

Describe appears to always return the most recent annotated (non-lightweight) tag. If you're mixing tag types, you should not assume consistent behaviour. Light weight tags appear to use the most recent version as well (presumably based on the file's time stamp rather than commit time) but aren't searched without --allor --tags. Even with --all, annotated tags appear to take precedence over more recent lightweight tags.

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

The only convenient way to get all identifiers for the current tag that I can find is to run git show-ref with dereference and to grep for your current commit. This won't include timestamps for sorting.

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

回答by eephillip

I had two tagging conventions on the same commit and wanted to keep the git describefeatures such as dirty, sha, and commit counts past tag etc. So in git version 2.24.1since I had a unique differentiating string in one tag vs the other I just used the match operator. You can also use exclude

我在同一个提交上有两个标记约定,并希望保留git describe诸如dirty、sha 和 commit counts past tag 等功能。因此,git version 2.24.1由于我在一个标签与另一个标签中有一个独特的区分字符串,因此我只使用了匹配运算符。您也可以使用排除

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

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