"tags whose commits are reachable from the specified commit" 是什么意思?

What does "tags whose commits are reachable from the specified commit" mean?

在我的一个项目中,我试图在签出分支后或从 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

这有两个部分:

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

Reachability is a property of a graph, or in Git's case, a directed graph. Consult either the Wikipedia article, or Think Like (a) Git,以获得正确的解释。 (或者查看我的许多 Whosebug 答案之一,其中展示了如何确定哪些分支 包含 各种提交。)其余部分假定您已经了解可达性。

A tag,在 Git 中,只是一个奇特的指针:实际上,一个箭头指向一个特定的提交。但是 Git 中的标签还有一个特别之处:它们可以指向一个 标签对象 ,而不是直接指向一个提交。1 标记对象具有 git tag -a 的注释或 git tag -m 的消息。然后标记对象保存底层提交的原始哈希 ID。

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

the manual pages just says [--merged]

Only list tags whose commits are reachable from the specified commit.

我们运行:

git tag -l --merged <commit-specifier>

所以我们选择一个提交。那就是 "specified commit".

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

如果我们可以到达标记的提交,git tag -l 列出标记。如果不是(或者如果我们必须跳过标签,因为它毕竟不标记提交),git tag -l 省略标签。


1标签名实际上可以指向树或blob对象,也可以指向提交或带注释的标签对象。在这种情况下根本没有提交,git tag -l --merged 将忽略该标记。此外,带注释的标记对象实际上可以引用任何其他类型的对象,而不仅仅是提交对象。所以解析标签名的真正规则是:

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

我们现在知道标签所指的对象了。如果它是一个提交,它就是这个 --merged 清单的候选者。如果不是,那就不是。