Git 为什么带注释的标记对象存储标记名?

Git 为什么带注释的标记对象存储标记名?,git,git-tag,Git,Git Tag,如中所示,git注释的标记有几个属性,例如 > git cat-file -p v0.1 object 5cf4de319291579d4416da8e0eba8a2973f8b0cf type commit tag v0.1 tagger JDB <jd@domain.com> 1521058797 -0400 Version 0.1-beat 前两个属性提供标记所指向的目标对象的SHA1和类型。第三个属性给出了标记的名称v0.1 但该标记表示为文件.git/refs/

如中所示,git注释的标记有几个属性,例如

> git cat-file -p v0.1

object 5cf4de319291579d4416da8e0eba8a2973f8b0cf
type commit
tag v0.1
tagger JDB <jd@domain.com> 1521058797 -0400

Version 0.1-beat
前两个属性提供标记所指向的目标对象的SHA1和类型。第三个属性给出了标记的名称v0.1

但该标记表示为文件.git/refs/tags/v1.0。因此,我们已经有了一种从字符串v0.1映射到标记对象及其属性的方法。 为什么我们需要标记对象在其属性中也包含标记名?分支不存储它们的名称。提交对象不存储其SHA1。在某些情况下,您会引用一个标记而不是它的名称吗?

好的,在这个问题中,还包含一个关于这个问题答案的线索:指向标记的标记使用目标标记的SHA1,而不是它的名称作为引用

因此,如果创建的tag2指向tag1,则tag2指向tag1对象,而不实际显示tag1的名称。因此,如果任何git命令或UI必须取消对tag1的引用,那么如果tag2的对象不包含该信息,它将无法直接知道它所指向的标记被称为tag2


也许还有其他原因,但这是我能想到的。除了标签之外,可能还有其他东西可以通过其SHA1引用标签,因此需要引用标签对象提供引用标签的名称。

除了您自己的应答标签通过对象ID指向标签外,您可能希望标签对象存储标签名称的其他原因:

如果ref是松散的,那么正如您所说,它存储为.git/refs/tags/v0.1。但它可能是打包的。因此,如果您希望依赖refs元数据来映射标记名,那么就不那么容易了。不管怎样,手工在.git目录中混日子最好是B计划

对象散列,如果是已签名的标记,则签名不会覆盖标记的文件名。如果您希望确保commit 5cf4de319是v0.1的意思,那么您需要tag对象显式存储该事实

更新

我再次不确定这是否转化为一个实际重要的原因,但还有一件事需要考虑:


带注释的标记与从带注释的标记指向标记对象的轻量级标记之间的区别到底是什么?我得到的最佳答案是:名称不匹配。

OK。我不是指手工在.git目录中混日子。。。而是指git工具需要什么。假设他们可以有效地将标记名映射到它的对象,即使它位于压缩引用中。关于第二点,我可以看出它对已签名标记的重要性,因此名称是正在签名的内容的一部分。你是说这对未签名的标签也很重要吗?@LarsH-我想说,这对未签名的标签是否重要还不清楚。将其放在对象中使其成为标记标识的一部分。因此,事实上,你可以有两个完全相同的标签,除了它们有不同的名称,如果标签对象没有存储标签名称,你就不能。那有关系吗?我不敢说这样或那样的话。我想最后我们不得不问Linus他的原因,但是标签名是签名标签的签名身份的一部分似乎是一个很好的理由。Mark,当我问你是否说这对未签名标签也很重要时,我在想你的句子,“如果您希望保证提交5cf4de319是v0.1的意思,那么您需要标记对象来显式存储该事实。”当保证指的是诸如签名之类的健壮内容时,我可以看到标记名称必须是签名数据的一部分。但是对于未签名的标记,您已经有了标记v0.1引用commit 5cf4de3的信息,并且将标记名添加到标记对象中似乎并没有增加任何保证。除非我错过了什么?