“从指定的提交可以达到其提交的标记”是什么意思?

时间:2020-02-03 23:03:42

标签: git sorting tags branch git-tag

在我的一个项目中,我尝试在签出分支后或从origin/master获取最新标签。如果我运行git tag -l --sort=-creatordate --merged | head -n1git describe,则会得到相同的结果,但其结果来自过去的标签。如果我摆脱了--merged,它会在项目中显示正确的最新标签。

签出一个特定的分支会给我回购代码中正确的,最后一个已知的标签,但是如果它来自origin/masterFETCH_HEAD,它会给我一个过去的标签。

我主要是想知道--merged标志是如何工作的,因为手册页只说了Only list tags whose commits are reachable from the specified commit

1 个答案:

答案 0 :(得分:1)

这有两部分:

  • 可达性的一般概念和
  • git tag -l --merged的工作原理,它使用的是概念本身。

Reachability的属性,或者在Git的情况下,是有向图的属性。请查阅Wikipedia文章或Think Like (a) Git,以获得适当的说明。 (或者查看我的众多StackOverflow答案之一,该答案显示了如何确定哪些分支包含各种提交。)其余部分假设您已经了解了可达性。

在Git中的 tag 只是一个奇特的指针:实际上,是指向一个特定提交的箭头。但是Git中的标签还有另外一件特别的事情:它们可以指向 tag对象,而不是直接指向提交。 1 标签对象具有{{ 1}}或git tag -a的消息。然后,标记对象将保存基础提交的原始哈希ID。

这使我们想到了文档中的措辞:

手册页上只显示[git tag -m]

仅列出可从指定提交中提交的列表标记。

我们运行:

--merged

所以我们选择一个提交。那就是“指定的提交”。

git tag -l --merged <commit-specifier> 操作现在将遍历每个标签。标签要么直接指向提交,要么指向指向提交的带注释的标签对象。该提交存在于整个Git提交图中。 git tag -l适用的问题是:我们可以从指定的提交中到达带标签的提交吗?

如果我们可以到达已标记的提交,则--merged将列出标记。如果不是这样(或者我们必须跳过标记,因为它毕竟不会标记提交),则git tag -l会忽略标记。


1 实际上允许标记名称指向树或Blob对象,以及指向提交或带注释的标记对象。在这种情况下,根本没有提交,git tag -l只会忽略该标签。同样,带注释的标记对象实际上可以引用任何其他类型的对象,而不仅仅是提交对象。因此,解析标签名称的真正规则是:

  • 如果标签名称引用带注释的标签对象,请切换到该带注释的标签对象。
  • 虽然我们有带注释的标签对象,但切换到该带注释的标签目标的对象。 (Git在内部将其称为 peeling 标签,类似于逐层剥离洋葱。)
  • 停止:我们有一个对象。

我们现在知道标签所指向的对象。如果是提交,则是此git tag -l --merged列表的候选对象。如果不是,则不是。