在我的一个项目中,我尝试在签出分支后或从origin/master
中获取最新标签。如果运行git tag -l --sort=-creatordate --merged | head -n1
或git describe
,我将得到相同的结果,但其结果是来自过去的标记。如果我删除了--merged
,它会在项目中显示正确的最新标签。
[签出特定分支后,我会在存储库中返回正确的,最后一个已知的标签,但是如果它来自origin/master
或FETCH_HEAD
,则它会给我过去的标签。
我主要是想知道--merged
标志的工作原理,因为手册页只是说Only list tags whose commits are reachable from the specified commit
。
有两个部分:
git tag -l --merged
的工作方式,使用概念本身。graph
tag
只是一个奇特的指针:实际上是指向一个特定提交的箭头。但是Git中的标签还有另外一件特别的事情:它们可以指向tag object,而不是直接指向提交。1标签对象具有git tag -a
的注释或git tag -m
的消息]。然后,标记对象保存基础提交的原始哈希ID。这使我们了解文档中的措辞:手册页上只说[--merged
]仅列出其提交可从指定提交到达的标签。我们运行:
git tag -l --merged <commit-specifier>
所以我们选择一个提交。那就是“指定的提交”。
git tag -l
操作现在将遍历每个标签。标签要么直接指向提交,要么指向指向提交的带注释的标签对象。该提交存在于整个Git提交图中。 --merged
适用的问题是:
我们可以从指定的提交到达带标签的提交吗?
如果我们可以
到达加标签的提交,则git tag -l
列出标签。如果不是这样(或者我们必须跳过该标记,因为它毕竟不会标记提交),则git tag -l
会忽略该标记。1
标记名实际上被允许指向树或blob对象,以及指向提交或注释的标记对象。在这种情况下,根本没有提交,git tag -l --merged
只会忽略该标签。同样,带注释的标签对象实际上可以引用任何其他类型的对象,而不仅仅是提交对象。因此,解析标签名称的真正规则是:--merged
列表的候选者。如果不是,则不是。