Git标签,为什么远程仓库中会有重复的标签?

26
30bd19ef190cf664356c715b56044ce739f07468        refs/tags/Prod_Release_2.3
4ae15ee04c2c41bfc7945e66f4effc746d52baec        refs/tags/Prod_Release_2.3^{}
以上是从 git ls-remote --tags 命令列出我中央仓库(裸)中的标签输出。
对于 Prod_Release_2.3,我只期望有 1 个标签,但我不知道这个 Prod_Release_2.3^{} 是从哪里来的。
在 centralrepo1 中,Prod_Release_2.3 的 id 与 centralrepo2 中的 Prod_Release_2.3^{} 的 id 相同,反之亦然。
在我的本地仓库中只有一个标签 Prod_Release_2.3
是否有问题?还是这是按设计操作?
中央仓库托管在 Ubuntu 上,我在开发机上使用 msysgit。
2个回答

33

在Git中,有两种标签类型:“轻量级”和“附注性”标签。

轻量级标签简单地是指向其他对象的refs/tags/命名空间中的引用。使用git tag <tagname> [object]而不带-a, -m, -F, -s, 或-u选项即可创建它们。

附注性标签实际上是Git中一种独立的对象(一个标签对象),它指向其他对象。标签对象存储提交者信息、作者信息、一条信息(类似于提交对象),并且它们指向任何单个其他对象(与提交对象不同,提交对象指向恰好一个树对象和零个或多个其他提交对象)。

当你拥有一个附注性标签时,通常也有一个指向它的引用。从技术上讲,此引用本身就是一个“轻量级”标签,但我们通常不将它们分别描述。

通常,这两种标签都指向提交,但它们可以指向任何类型的 Git 对象(标签、提交、树或 blob)。git.git 仓库 拥有一个指向包含维护者 GPG 公钥的 blob 的 refs/tags/junio-gpg-pub。此外,torvalds/linux-2.6.git 拥有一个指向树的 refs/tags/v2.6.11。虽然指向非提交对象的标签在技术上是允许的,但它们可能会破坏或混淆一些工具,因此应尽可能避免使用。
语法^{} 后缀(在 gitrevisions(7) 中有描述)是标签解除引用语法(有时称为 "peeled tag" 语法)。对于标签对象,它将计算出标签对象指向的第一个非标签对象(它将递归地 deference 标签对象链直到找到非标签对象)。对于非标签对象,它与没有^{} 后缀的含义相同。
在您的中央仓库中,refs/tags/Prod_Release_2.3 引用指向名为 30bd19ef190cf664356c715b56044ce739f07468 的标签对象。那个标签对象最终指向另一个名为4ae15ee04c2c41bfc7945e66f4effc746d52baec的非标签对象(可能是一个提交)。

因此,refs/tags/Prod_Release_2.3^{}解析为4ae15ee04c2c41bfc7945e66f4effc746d52baec

1
简而言之,每次推送的 annotated tag 都会创建一个初始标签引用和第二个引用,该引用使用 ^{} 语法指向第一个引用。轻量级标签仅创建单个引用。 - bryanbraun
1
@bryanbraun:whatever^{}名称不存在作为ref(在refs/命名空间下的条目); ^{}只是一个后缀,可以附加到任何修订名称(ref名称,(缩写)object哈希或其他计算修订名称等)以“剥离”tag objects,直到找到非标签object。假设已经推送了被标记的commitC,那么推送新的注释标记将推送一个tag object(指向C)和一个新的ref(指向新的tag object),而轻量级标记仅会推送新的ref(指向C)。 - Chris Johnsen
1
虽然ls-remote显示这些^{}refs,但它们实际上并不存在作为refs;您可以通过(例如)将git show-ref --tags(实际标签refs)的输出与git ls-remote --tags .(“wire protocol”报告的内容)进行比较来验证这一点。由于技术原因,“peeled tags”包含在“wire protocol”中,但它们并不存在作为实际的refs。但是,您可以将^{}视为“引用”(因为它是命名特定对象的一种方式),只要您不使用该术语来表示“/refs”命名空间下的条目。 - Chris Johnsen
你可以有两个具有相同名称和描述的标签指向同一个提交吗? - Ogen

6

那不是一个标签,而是指向标签所指向的提交的指针。你可以在git show-ref手册页面中阅读更多信息。


看起来你的标签命名不规范,就像在命令行上输入它一样。 - Adam Dymitruk
@adymitruk:在我的git.git存储库中,git ls-remote --tags origin会打印每个标签的标签和指向的提交(因为它们都是真正的标签对象)。 - Cascabel
1
另一个学习的好地方是来自Git社区书籍的Git对象模型 - 描述了标签对象以及其他对象。 - Cascabel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接