去年,我的日常风投工作从Subversion转向了Git,现在我仍在努力把握“Git思维”的精髓。

最近困扰我的一个问题是“轻量级”、带注释的标签和签名标签。在所有实际应用中,带注释的标签都优于轻量级标签,这似乎是被普遍接受的,但我发现为什么会出现这种情况的解释似乎总是归结为“因为最佳实践”或“因为它们不同”。不幸的是,如果不知道为什么这是最佳实践,或者这些差异与我的Git使用有什么关系,这些都是非常不令人满意的论点。

当我第一次切换到Git时,轻量级标签似乎是自切片面包以来最好的东西;我可以指向一个提交并说“那是1.0”。我很难理解一个标签怎么可能需要更多,但我当然不能相信Git专家们随意地喜欢带注释的标签!那么,这些喧嚣是关于什么的呢?

(附加提示:为什么我需要在标签上签名?)

EDIT

我已经成功地相信带注释的标签是一件好事——知道谁在什么时候做了标记是很重要的!作为后续,关于好的标记注释有什么建议吗?无论是git标记-am“标记1.0”1.0,还是尝试总结提交日志,因为之前的标记感觉像是丢失了策略。


当前回答

为标签签名是断言发布的真实性的一种简单方法。

这在DVCS中特别有用,因为任何人都可以克隆存储库并修改历史(例如通过git-filter-branch)。如果标记已签名,则签名将无法在git-filter-branch操作中存活,因此如果您有一种策略,即每个版本都由提交者标记并签名,那么就有可能在存储库中检测到虚假的发布标记。

如果不是为了签名,我也不会认为带注释的标记有多大意义。

其他回答

推送带注释的标签,保持轻量级的本地

Git的某些行为确实在某些方面有所区别,这个建议是有用的,例如:

带注释的标记可以包含与它们所指向的提交不同的消息、创建者和日期。因此,您可以使用它们来描述一个发布,而不进行发布提交。 轻量级标签没有这些额外的信息,也不需要它,因为您只会在开发过程中使用它。 Git push——follow-tags只会推送带注释的标签 没有命令行选项的Git描述只能看到带注释的标记

男人说:

带注释的标记用于发布,而轻量级标记用于私有或临时对象标签。

内部差异

both lightweight and annotated tags are a file under .git/refs/tags that contains a SHA-1 for lightweight tags, the SHA-1 points directly to a commit: git tag light cat .git/refs/tags/light prints the same as the HEAD's SHA-1. So no wonder they cannot contain any other metadata. annotated tags point to a tag object in the object database. git tag -as -m msg annot cat .git/refs/tags/annot contains the SHA of the annotated tag object: c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef and then we can get its content with: git cat-file -p c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef sample output: object 4284c41353e51a07e4ed4192ad2e9eaada9c059f type commit tag annot tagger Ciro Santilli <your@mail.com> 1411478848 +0200 msg -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) <YOUR PGP SIGNATURE> -----END PGP SIGNAT And this is how it contains extra metadata. As we can see from the output, the metadata fields are: the object it points to the type of object it points to. Yes, tag objects can point to any other type of object like blobs, not just commits. the name of the tag tagger identity and timestamp message. Note how the PGP signature is just appended to the message A more detailed analysis of the format is present at: What is the format of a git tag object and how to calculate its SHA?

奖金

判断一个标签是否带注释: Git cat-file -t标签 输出提交为轻量级,标签为注解。 只列出轻量级标签:如何列出所有轻量级标签?

默认情况下,Git只将带注释的标记作为Git describe等命令的基线。将带注释的标签视为对自己和他人具有持久意义的标志,而轻量级标签更像书签,供日后自己寻找。因此,带注释的标记值得作为参考,而轻量级标记则不应该。

在标签上签名是签名者身份的保证。例如,它可以让用户验证他们获得的Linux内核代码是否与Linus Torvalds实际发布的代码相同。签名也可以是签名者在提交时担保软件质量和完整性的断言。

对我来说,重要的区别是轻量级标签没有时间戳。假设你添加了几个轻量级标签:

git tag v1
git tag v2
git tag v3

然后,也许稍后,你想要最后添加轻量级标签。没有办法做到这一点。“git描述”和“git标签”都不会按时间顺序给出最后一个轻量级标签。"git tag -l"可以返回它们的全部或按lex顺序排序,但不能按日期/时间排序。"git describe——tags"将返回"v1",这肯定不是最后添加的标签。

另一方面,如果你添加带注释的标签:

git tag v1 -m v1
git tag v2 -m v1
git tag v3 -m v1

你总是可以得到每个标签的时间戳,“git describe”肯定会返回“v3”,这是最后添加的标签。

带注释的标记将额外的元数据存储为Git数据库中的完整对象,例如作者名称、发布说明、标记消息和日期。所有这些数据对于项目的公开发布都很重要。

Git标记-a v1.0.0

轻量级标记是向git存储库添加标记的最简单方法,因为它们只存储它们引用的提交的哈希值。它们可以充当提交的“书签”,因此,它们非常适合私人使用。

Git标记v1.0.0

您可以对旧标签进行排序、列出、删除、显示和编辑。所有这些函数都将帮助您识别代码的特定发布版本。我发现这篇文章可以帮助您更好地了解标签可以做什么。

为标签签名是断言发布的真实性的一种简单方法。

这在DVCS中特别有用,因为任何人都可以克隆存储库并修改历史(例如通过git-filter-branch)。如果标记已签名,则签名将无法在git-filter-branch操作中存活,因此如果您有一种策略,即每个版本都由提交者标记并签名,那么就有可能在存储库中检测到虚假的发布标记。

如果不是为了签名,我也不会认为带注释的标记有多大意义。