为什么我要关心轻量级标签和带注释的标签?


346

去年,我从Subversion切换到Git作为我的日常VCS,但仍在尝试掌握“ Git-think”的要点。

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

当我第一次切换到Git时,轻巧的标签似乎是切成薄片以来最好的东西。我可以指向一次提交,然后说“那是1.0”。我很难把握一个标签可能还需要更多的地方,但是我当然不能相信世界上的Git专家会更喜欢带注释的标签!那么,所有的话题都是什么呢?

(奖励积分:为什么我需要签署标签?)

编辑

我已经成功地确信带注释的标签是一件好事-了解谁标记了标签以及何时重要!作为后续,对好的标签注释有什么建议吗?git tag -am "tagging 1.0" 1.0由于前一个标签,两者都试图汇总提交日志,这感觉就像是失去了策略。


您是否为后续工作找到了很好的答案?就像是?git log --pretty=oneline master..HEAD | git tag -a -F - $BRANCH.$BUILD_NUMBER
达洛尔

总结提交日志,因为在我看来,上一个标签似乎是标记消息的绝佳策略。
rooby

仅供参考(1.)要按日期列出LIGHTWEIGHT标签,请转到此处(2.)要按日期列出ANNOTATED标签,请转到此处
Trevor Boyd Smith,

Answers:


272

带注释的标签的最大优点是您知道创建它的人。就像提交一样,有时很高兴知道是谁做的。如果您是开发人员,并且看到v1.7.4已被标记(声明为就绪),但您不确定,您该与谁谈话?名称在带注释的标签中的人!(如果您生活在一个不信任的世界中,那么这也会使人们远离标记他们不该做的事情。)如果您是消费者,那么这个名字就是权威的印记:Junio Hamano表示此版本的git特此声明已发布。

其他元数据也可能有帮助-有时很高兴知道该版本何时发布,而不仅仅是最终提交的时间。有时,该消息甚至可能会有用。也许可以帮助解释该特定标签的用途。候选版本的标签可能包含一些状态/待办事项列表。

对标签进行签名几乎与对其他任何事物进行签名一样,它为偏执狂提供了更高的安全级别。我们大多数人永远不会使用它,但是如果您真的想在将软件安装到计算机上之前对其进行验证,则可能需要使用它。

编辑:

至于在标签注释中写的内容,您是对的-并不一定总是有用。对于版本号标签,暗含的理解是它标记了该版本,如果您对其他地方的更改日志感到满意,则无需在其中放置一个。在这种情况下,最重要的实际上是标记器和日期。我唯一能想到的就是某种测试套件的认可。看一下git.git的标签:它们都只说“ Git 1.7.3 rc1”之类的东西;我们真正关心的就是他们身上的名字Junio Hamano。

但是,对于不太明显的标签,该消息可能变得更加重要。我可以设想为单个用户/客户端标记特定的专用版本,一些重要的非版本里程碑,或者(如上所述)为候选版本添加额外的信息。该消息将更加有用。


4
只是为了与SVN进行比较,因为OP来自该系统:带注释的标签元数据等效于实际的SVN更改,因此将进行标记分支,该分支在SVN中具有自己的作者和消息。而且,可能的是,对谁可以制作标签有单独的限制,与谁可以签入更改有不同的限制-如果您只是将系统用于自己的东西,则这一区别是无关紧要的。
araqnid

10
啊哈!到目前为止,我所有的Git项目都是单独的,这似乎妨碍了我的理解。我从来不需要知道谁应该为某件事负责(这总是我!),所以我没有注意到轻量级标签不会跟踪该标签程序。
本·布兰克

5
git help log现在将其总结为:“带注释的标签用于发布,而轻量级标签用于私有或临时对象标签。”
Jon Gjengset 2014年

1
@javabrett虽然这是“带注释的标签和轻量级标签之间的区别是什么”答案的一个很好的部分,但是这里的问题是为什么人们想要存储额外的信息并因此使用带注释的标签。(而且我不认为我可以认真地说“它创建了一个blob”是一个弊端-您需要执行所需的操作来存储要存储的信息,如果它是重要信息,则需要一个blob。 )
Cascabel '16

1
@Chris是的,正如回答所说,“带注释标签的最大优点是您知道创建它的人。” 您可以随时尝试尝试找出git tag -a -m 'my message' my-tag; git show my-tag
答案

64

我对此主题的看法略有不同:

  • 带注释的标签是那些打算为其他开发人员发布的标签,很可能是新版本(也应签名)。不仅要查看标记了谁的标签和标记时间,还可以查看原因(通常是变更日志)。
  • 轻量级更适合私人使用,这意味着标记特殊提交即可再次找到它们。可能是对其进行审查,将其签出以测试某些内容或其他内容。

4
man git-tag上也提到了这一点:“带注释的标签旨在释放,而轻型标签则用于私有或临时对象标签。”:stackoverflow.com/a/35059291/895245
Ciro Santilli郝海东冠状病六四事件法轮功

28

默认情况下,Git仅将带注释的标签作为命令之类的基线git describe。将带注释的标签视为对自己和他人具有持久意义的路标,而轻量级的标签更像是书签,供您以后的自己查找。因此,带注释的标签值得作为参考,而轻量级标签则不应。

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


1
git push --follow-tags是另一个将两者区别对待的命令:stackoverflow.com/a/26438076/895245
Ciro Santilli郝海东冠状病六四事件法轮功2015年

1
感谢您的提示git describe。我在持续集成系统中使用了它,有几次版本字符串不是我期望的。
jjmontes

9

对标签签名是断言发布真实性的简便方法。

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

如果不是用于签名,那么在带注释的标签中我也看不到什么意义。


1
实际上,为此,仅签名已提交树而不是整个历史的签名可能很有用(我不在乎是否有人篡改了历史,我只想确保我拥有正确的代码)。
圣保罗Ebermann

9

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

某些Git行为确实以建议有用的方式来区分它们,例如:

  • 带注释的标签可以包含与其指向的提交不同的消息,创建者和日期。因此,您可以使用它们来描述发布,而无需提交发布。

    轻量级标签没有多余的信息,也不需要它,因为您将自己使用它来进行开发。

  • git push --follow-tags将仅推送带注释的标签
  • git describe 没有命令行选项的只能看到带注释的标签

man git-tag 说:

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

内部差异

  • 轻量标签和带注释的标签都是.git/refs/tags包含SHA-1的文件

  • 对于轻量级标签,SHA-1直接指向提交:

    git tag light
    cat .git/refs/tags/light
    

    打印与HEAD的SHA-1相同。

    因此,难怪它们不能包含任何其他元数据。

  • 带注释的标签指向对象数据库中的标签对象。

    git tag -as -m msg annot
    cat .git/refs/tags/annot
    

    包含带注释的标记对象的SHA:

    c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef
    

    然后我们可以通过以下方式获取其内容:

    git cat-file -p c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef
    

    样本输出:

    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
    

    这就是它包含额外的元数据的方式。从输出中可以看到,元数据字段为:

    有关该格式的更详细分析,请参见:git标签对象的格式是什么以及如何计算其SHA?

奖金


6

我发现轻量级标签的一个很好的用途-回顾性地在GitHub上创建一个发行版。

我们确实发布了我们的软件,并进行了必要的提交,我们只是不费心地在GitHub上维护“发布”部分。当我们稍加注意时,我们意识到我们也想添加一些以前的版本,并为其指定正确的旧发布日期。

如果我们仅在旧提交上创建带注释的标签,则GitHub将从标签对象中获取发布日期。相反,当我们为此旧提交创建一个轻量级标记时,​​发行版开始显示正确的(旧)日期。 来源@ GitHub帮助,“关于发行版”

似乎也可以为带注释的提交指定所需的日期,但对我而言似乎并不那么简单:https//www.kernel.org/pub/software/scm/git/docs/git-tag。 html#_on_backdating_tags


尽管今天我发现GitHub停止为我兑现标签日期(对于轻量级标签和带注释的标签)。它只是不考虑发布发布时的日期,而是记住我按下发布的“发布”按钮时的日期和时间。
evilkos

是的,我也偶然发现了有关GitHub和带注释的标签的混乱情况。我不明白为什么他们会这样实现
。– YakovL

1

在我的办公室中,我们将发布网页地址放在标签正文中。该发行版网页详细介绍了自上一发行版以来的所有不同新功能和修复。管理层不会在git repo中查找发生了什么更改,并且很高兴能获得该版本的简要清单。


0

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

git标签-a v1.0.0

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

git标签v1.0.0

您可以排序,列出,删除,显示和编辑旧标签。所有这些功能将帮助您识别代码的特定发行版本。我发现本文可以帮助您更好地了解标签可以做什么。


0

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

git tag v1
git tag v2
git tag v3

然后,也许以后,您要获取最后添加的轻量级标签。没有办法做到这一点。“ git describe”和“ git tag”都不会按时间顺序为您提供最后的轻量级标签。“ 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”,这实际上是最后添加的标签。


您必须使用-a进行注释。
Alex
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.