去年,我的日常风投工作从Subversion转向了Git,现在我仍在努力把握“Git思维”的精髓。
最近困扰我的一个问题是“轻量级”、带注释的标签和签名标签。在所有实际应用中,带注释的标签都优于轻量级标签,这似乎是被普遍接受的,但我发现为什么会出现这种情况的解释似乎总是归结为“因为最佳实践”或“因为它们不同”。不幸的是,如果不知道为什么这是最佳实践,或者这些差异与我的Git使用有什么关系,这些都是非常不令人满意的论点。
当我第一次切换到Git时,轻量级标签似乎是自切片面包以来最好的东西;我可以指向一个提交并说“那是1.0”。我很难理解一个标签怎么可能需要更多,但我当然不能相信Git专家们随意地喜欢带注释的标签!那么,这些喧嚣是关于什么的呢?
(附加提示:为什么我需要在标签上签名?)
EDIT
我已经成功地相信带注释的标签是一件好事——知道谁在什么时候做了标记是很重要的!作为后续,关于好的标记注释有什么建议吗?无论是git标记-am“标记1.0”1.0,还是尝试总结提交日志,因为之前的标记感觉像是丢失了策略。
我发现了轻量级标签的一个很好的用途——在GitHub上创建一个版本。
我们确实发布了我们的软件,我们有必要的提交,我们只是没有费心去维护GitHub上的“发布”部分。当我们注意到这一点时,我们意识到我们也想添加一些以前的版本,并为它们提供正确的旧发布日期。
如果我们只是在旧提交上创建一个带注释的标记,GitHub将从标记对象中获取发布日期。相反,当我们为这个旧的提交创建了一个轻量级标记时,发布版开始显示正确的(旧的)日期。
来源@ GitHub帮助,“关于发布”
似乎也可以为带注释的提交指定你想要的日期,但在我看来并不那么简单:
https://www.kernel.org/pub/software/scm/git/docs/git-tag.html#_on_backdating_tags
推送带注释的标签,保持轻量级的本地
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标签
输出提交为轻量级,标签为注解。
只列出轻量级标签:如何列出所有轻量级标签?
我发现了轻量级标签的一个很好的用途——在GitHub上创建一个版本。
我们确实发布了我们的软件,我们有必要的提交,我们只是没有费心去维护GitHub上的“发布”部分。当我们注意到这一点时,我们意识到我们也想添加一些以前的版本,并为它们提供正确的旧发布日期。
如果我们只是在旧提交上创建一个带注释的标记,GitHub将从标记对象中获取发布日期。相反,当我们为这个旧的提交创建了一个轻量级标记时,发布版开始显示正确的(旧的)日期。
来源@ GitHub帮助,“关于发布”
似乎也可以为带注释的提交指定你想要的日期,但在我看来并不那么简单:
https://www.kernel.org/pub/software/scm/git/docs/git-tag.html#_on_backdating_tags