Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between an annotated and unannotated tag?

Tags:

git

git-tag

tags

If I want to tag the current commit. I know both of the following command lines work:

git tag <tagname> 

and

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

What is the difference between these commands?

like image 726
user462301 Avatar asked Jul 16 '12 23:07

user462301


People also ask

What is annotated git tag?

Annotated Tags An annotated tag creates an additional tag object in the Git repository, which allows you to store information associated with the tag itself. This may include release notes, the meta-information about the release, and optionally a signature to verify the authenticity of the commit to which it points.

What is the difference between lightweight and annotated tags?

Git supports two types of tags: lightweight and annotated. A lightweight tag is very much like a branch that doesn't change — it's just a pointer to a specific commit. Annotated tags, however, are stored as full objects in the Git database.

How do you tell if a tag is annotated?

If it's an an annotated tag, cat-file will tell you that it's a "tag". If it's a simple tag, cat-file will tell you that it's a "commit". Update: As oxymoron said in his comment, git show works too but it gives you more information than just what kind of tag it is.

How do I create an annotated tag?

To create a Git tag with a message, use the “git tag” command with the “-a” option for “annotated” and the “-m” option for message. Note : if you don't provide the “-m” option, your default text editor will open in order for you to type the tag message.


2 Answers

TL;DR

The difference between the commands is that one provides you with a tag message while the other doesn't. An annotated tag has a message that can be displayed with git-show(1), while a tag without annotations is just a named pointer to a commit.

More About Lightweight Tags

According to the documentation: "To create a lightweight tag, don’t supply any of the -a, -s, or -m options, just provide a tag name". There are also some different options to write a message on annotated tags:

  • When you use git tag <tagname>, Git will create a tag at the current revision but will not prompt you for an annotation. It will be tagged without a message (this is a lightweight tag).
  • When you use git tag -a <tagname>, Git will prompt you for an annotation unless you have also used the -m flag to provide a message.
  • When you use git tag -a -m <msg> <tagname>, Git will tag the commit and annotate it with the provided message.
  • When you use git tag -m <msg> <tagname>, Git will behave as if you passed the -a flag for annotation and use the provided message.

Basically, it just amounts to whether you want the tag to have an annotation and some other information associated with it or not.

like image 87
Todd A. Jacobs Avatar answered Sep 17 '22 15:09

Todd A. Jacobs


Push annotated tags, keep lightweight local

man git-tag says:

Annotated tags are meant for release while lightweight tags are meant for private or temporary object labels.

And certain behaviors do differentiate between them in ways that this recommendation is useful e.g.:

  • annotated tags can contain a message, creator, and date different than the commit they point to. So you could use them to describe a release without making a release commit.

    Lightweight tags don't have that extra information, and don't need it, since you are only going to use it yourself to develop.

  • git push --follow-tags will only push annotated tags
  • git describe without command line options only sees annotated tags

Internals differences

  • 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 <[email protected]> 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?

Bonuses

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