注释标签和非注释标签的区别是什么?

533

如果我想给当前提交打标签,我知道以下两个命令行都可以:

git tag <tagname>

并且

git tag -a <tagname> -m '<message>'

这些命令有什么区别?


2
@Thilo 这不是完全重复。所提到的问题是关于何时进行注释,而不是相关标志。 - Todd A. Jacobs
2
这在Git的文档中解释得非常清楚:http://git-scm.com/book/en/Git-Basics-Tagging - Samy Dindane
1
简述:未注释的提交;已注释的提交,作者,日期,(可选)注释。 - Antony Hatchkins
4个回答

410

简短总结

这两个命令的区别在于一个提供了标签信息,而另一个没有。带注释的标签具有可以通过git-show(1)显示的消息,而没有注释的标签只是指向提交的命名指针。

更多关于轻量级标签的内容

根据 文档: "要创建轻量级标签,请不要提供任何-a、-s或-m选项,只需提供标签名称"。还有一些不同的选项来在带注释的标签上编写消息:

  • 当你使用 git tag <tagname> 命令时,Git会在当前修订版本处创建一个标签,但不会提示你添加注释。它将以没有消息的方式打上标签(这是一个轻量级标签)。
  • 当你使用 git tag -a <tagname> 命令时,Git会提示你添加注释,除非你也使用了 -m 标记提供消息。
  • 当你使用 git tag -a -m <msg> <tagname> 命令时,Git将对提交进行标记,并用提供的消息进行注释。
  • 当你使用 git tag -m <msg> <tagname> 命令时,Git将表现得好像你传递了 -a 标志用于注释,并使用提供的消息。

基本上,这只是关于标签是否具有注释和其他相关信息的问题。


8
“annotation”和“commit message”这两个标签有区别吗? - Steve Bennett
4
是的,标签注释不是提交信息。你不能使用git-log(1)查看它;你需要使用git-show(1)。 - Todd A. Jacobs
185
“带注释”和“轻量级”标签的区别不仅在于消息。你可以有一个没有消息的“带注释”标签(git tag -a <tag> -m ''),但是一个“带注释”的标签始终具有标记者(作者)和日期信息。 - Piotr Findeisen
71
另一个需要注意的重要事情是,当使用“git push --follow-tags”将标签推送到远程仓库时,只有带注释的标签才会被推送。 - Sander Toonen
9
补充@Xatoo的评论,git push origin --tags命令会同时推送两种类型的标签,即注释标签和轻量标签。 - Wesley Gonçalves
显示剩余7条评论

325

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

man git-tag 说:

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

某些行为确实以这种方式区分它们,因此这个建议是有用的,例如:

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

    轻量级标签没有额外的信息,并且也不需要它们,因为您只会自己使用它们进行开发。

  • git push --follow-tags 只会推送带注释的标签
  • git describe 在没有命令行选项的情况下只会查看带注释的标签

内部区别

  • 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:

    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?

奖金

  • Determine if a tag is annotated:

    git cat-file -t tag
    

    Outputs

    • commit for lightweight, since there is no tag object, it points directly to the commit
    • tag for annotated, since there is a tag object in that case
  • List only lightweight tags: How can I list all lightweight tags?


64

这里非常清楚地解释了巨大的区别 这里

基本上,轻量级标签只是指向特定提交的指针。 没有保存进一步的信息; 另一方面,注释标签常规对象,它们有一个作者和日期,并且可以被引用,因为它们有自己的SHA密钥。

如果知道什么时候标记是相关的,则使用注释标签。 如果您只想标记开发中的特定点,无论谁何时执行该操作,那么轻量级标签就足够了。

通常你会选择注释标签,但这真的取决于项目的Git主人。


0
另一个区别是当使用“git tag -a foo”命令失败时,因为已经存在一个标签“foo/bar”,可以在这里解释中找到更多信息。
从Git 2.42(2023年第三季度)开始,当“git tagman命令执行失败时,会保留“$GIT_DIR/TAG_EDITMSG”文件,以便用户可以恢复他们输入的内容。 对于轻量级标签,该git标签消息文件将不存在。
查看提交 08c12ec提交 669c11d提交 719515f(2023年5月16日)由Kristoffer Haugsbakk(LemmingAvalanche
(由Junio C Hamano -- gitster --合并于提交 6d2a88c,2023年6月13日)

tag:在事务失败的情况下保留消息文件

签名作者:Kristoffer Haugsbakk

用户在编写标签消息后,事务可能会失败。
特别是,如果存在一个标签foo/bar并且git tag -a foo(man)被执行,则该命令只有在尝试写入refs/tags/foo之后才会失败,而此时文件已被取消链接。

稍微延长消息文件的保留时间,以防止致命错误发生之前取消链接。

还有:

doc:标签:文档 TAG_EDITMSG

建议者:Junio C Hamano
签署者:Kristoffer Haugsbakk

Document TAG_EDITMSG which we have told the user about on unsuccessful command invocations since commit 3927bbe ("tag: delete TAG_EDITMSG only on successful tag", 2008-12-06, Git v1.6.1-rc2 -- merge).

Introduce this documentation since we are going to add tests for the lifetime of this file in the case of command failure and success.

Use the documentation for COMMIT_EDITMSG from git-commit.txt as a template since these two files share the same purpose.1

† 1: from commit 3927bbe:

“ This matches the behavior of COMMIT_EDITMSG, which stays around
  in case of error.

git tag现在在其man page中包括:

FILES

$GIT_DIR/TAG_EDITMSG

该文件包含正在进行的带注释标签的消息。如果git tag在创建带注释标签之前由于错误而退出,则用户在编辑器会话中提供的标签消息将可在此文件中找到,但可能会被下一次git tag调用覆盖。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接