370

去年,我从 Subversion 切换到 Git 作为我的日常 VCS,并且仍在努力掌握“Git-think”的细节。

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

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

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

编辑

我已经成功地确信带注释的标签是一件好事——知道谁标记了,什么时候标记很重要!作为后续,关于好的标签注释有什么建议吗?两者都git tag -am "tagging 1.0" 1.0尝试总结提交日志,因为上一个标签感觉就像失去了策略。

4

9 回答 9

293

带注释标签的最大优点是您知道是谁创建了它。就像提交一样,有时很高兴知道是谁做的。如果您是开发人员并且您看到 v1.7.4 已被标记(宣布准备就绪)并且您不太确定,您与谁交谈?名字在注释标签中的人!(如果您生活在一个不信任的世界中,这也可以防止人们对他们不应该标记的东西进行标记。)如果您是消费者,那么这个名字就是权威的印记:这是 Junio Hamano 说的这个版本的 git 特此释放。

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

签署标签很像签署其他任何东西 - 它为偏执狂提供了更高级别的安全性。我们中的大多数人永远不会使用它,但如果您真的想在将该软件安装到您的计算机之前验证所有内容,您可能需要它。

编辑:

至于在标签注释中写什么,你是对的——说起来并不总是很有用。对于版本号标签,它隐含地理解为它标记了该版本,如果您对其他地方的变更日志感到满意,则无需将其放在那里。在这种情况下,实际上最重要的是标记器和日期。我能想到的唯一另一件事是测试套件的某种认可印章。看看 git.git 的标签:他们都只是说“Git 1.7.3 rc1”;我们真正关心的是Junio Hamano的名字。

然而,对于不太明显命名的标签,消息可能变得更加重要。我可以设想为单个用户/客户端、一些重要的非版本里程碑或(如上所述)带有额外信息的发布候选标记一个特定的特殊用途版本。那么这个消息就更有用了。

于 2011-02-11T16:59:39.497 回答
70

我个人对该主题的看法略有不同:

  • 带注释的标签是那些打算为其他开发人员发布的标签,很可能是新版本(也应该签名)。不仅要查看标记的人以及标记的时间,还要查看标记的原因(通常是更改日志)。
  • 轻量级更适合私人使用,这意味着标记特殊提交以便能够再次找到它们。可能是审查它们,检查它们以测试某些东西或其他什么。
于 2011-02-11T21:47:39.283 回答
29

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

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

于 2011-02-11T16:56:43.760 回答
14

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

某些 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 tag 对象的格式是什么以及如何计算其 SHA?

奖金

于 2016-01-28T10:47:12.027 回答
10

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

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

如果不是用于签名,我也不会在带注释的标签中看到太多意义。

于 2011-02-11T17:22:10.163 回答
6

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

我们确实发布了我们的软件并且我们有必要的提交,我们只是懒得维护 GitHub 上的“发布”部分。当我们对此稍加注意时,我们意识到我们也希望添加一些以前的版本,并为它们提供正确的旧发布日期。

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

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

于 2016-10-28T08:38:16.653 回答
1

在我的办公室,我们将发布网页地址放在标签正文中。发布网页详细介绍了自上次发布以来所有不同的新功能和修复。管理层不会在 git 存储库中查找发生的更改,并且很高兴拥有该版本中内容的简明列表。

于 2014-10-24T17:34:14.520 回答
0

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

git tag -a v1.0.0

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

git 标签 v1.0.0

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

于 2018-06-13T07:27:05.060 回答
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”,这实际上是最后添加的标签。

于 2019-03-13T15:39:28.437 回答