Git: how to use tags

Tagging is a very popular and common concept in version control systems. Tags are generally used to mark special milestones in a history of your repository like releasing a new version of your product. The common practice is to create a tag for every released version of your product so that you can easily switch back to it, see the source code or rebuild.

What is tag?

In Git tag is a named reference to a specific commit in your repository. It is very convenient because you can use user-friendly names for commits instead of remembering or writing down their SHA hashes.

At this point you may notice a similarity to branches because they are also user-friendly names for commits. The difference is that branches can change the commit they point to while tags are immutable and always point to the same commit. As a consequence it is impossible to add any new change to a tag.

Lightweight tags

Git supports few types of tags. Lightweight tags are the most basic ones because they store only hash of the commit they refer to – nothing else is stored. They can be created by switching to the commit you want to tag and then issuing git tag command with the name of the tag to create:

$ git tag v1.0

Unsigned annotated tags

Lightweight tags have several drawbacks which disqualify them in many situations. They cannot have tag message, creation date, author or optionally cryptographic signature. If you want this kind of information, you can create an unsigned annotated tag by adding -a option:

$ git tag -a v1.1

If you don’t want to be prompted for the tag message, you may provide it on the command line by adding -m option:

$ git tag -a -m 'Release version 1.1' v1.1

Here I would also like to point that if -m or -F file option is given, Git will always create annotated tag so -a may be omitted in this case.

Signed annotated tags

It is also possible to create annotated tag signed using GnuPG program by adding -s option:

$ git tag -s -m 'Release version 1.3' v1.3

You need a passphrase to unlock the secret key for
user: "Robert <>"
4096-bit RSA key, ID A231EC80, created 2014-03-09

The signed tag can be later verified whether is was created by an authorized person.

By default the signing key is chosen from GnuPG keyring using the default e-mail address but it is also possible to explicitly state the key identifier using -u option:

$ git tag -s -u A231EC80 -m 'Release version 1.4' v1.4

You need a passphrase to unlock the secret key for
user: "Robert <>"
4096-bit RSA key, ID A231EC80, created 2014-03-09

Listing tags

Once you create several tags, you may want to see the list of them:

$ git tag -l -n10
v1.1            Release version 1.1
v1.3            Release version 1.3
v1.4            Release version 1.4

The command lists all existing tags with maximum 10 lines of their tag message. If the tag is a lightweight tag, the message of the last commit is shown.

Showing tag details

To see more details about specific tag, you may use git show command:

$ git show v1.4
tag v1.4
Tagger: Robert 
Date:   Sun Mar 9 10:44:55 2014 +0100

Release version 1.4
Version: GnuPG v1


commit 8f96002526eb5e6b818d719ebe72a7db381eed39
Author: Robert 
Date:   Sun Mar 9 09:06:51 2014 +0100

    Added README

It prints tag author, creation date, message, GnuPG signature if present and the information about the referenced commit. If the tag is lightweight, the output will be limited to the information about the referenced commit.

Verifying signed tag

Additionally, if the tag is signed, the signature placed inside the tag can be verified to ensure that the tag was created by an authorized person:

$ git tag -v v1.4
object 8f96002526eb5e6b818d719ebe72a7db381eed39
type commit
tag v1.4
tagger Robert <> 1394358295 +0100

Release version 1.4
gpg: Signature made Sun Mar  9 10:44:55 2014 CET using RSA key ID A231EC80
gpg: Good signature from "Robert <>"

In this case the tag was verified successfully so we can trust it. The verification may fail for two reasons. The typical reason is that we don’t have the signer’s public key. In this case we have to first obtain his/her public key and store it into our GnuPG keyring. Then we can retry the verification. The other unlikely reason is that the tag was created by an unauthorized person in which case we cannot trust this tag at all.

Pushing tags

In most cases you would want to push the newly created tag to the remote repository to make it available to everyone in the development team. It can be done similarly to pushing the branches:

$ git push origin v1.4

Deleting tags

Generally, there is no reason to delete the tags because they are inexpensive and don’t use much resources. The only exception is when you have mistakenly created a tag pointing to the wrong commit. In this case you should delete the local tag:

$ git tag -d v1.4

and remove it from remote repository if it was already pushed:

$ git push origin :v1.4

Moreover, if you have already pushed the wrong tag to the remote repository, the corrected tag should have different name than the wrong one. Otherwise, you may end up in a situation that some team members have a new tag while the rest still have the old one.


While I tried to describe the most interesting and useful functionalities related to tagging, there are still some things which were left out. You can find more about them in git-tag manual page.

About Robert Piasecki

Husband and father, Java software developer, Linux and open-source fan.
This entry was posted in cryptography, Git, Version control and tagged , . Bookmark the permalink.

2 Responses to Git: how to use tags

  1. jon says:

    When looking at a project with lots of tags, using sort’s –version-sort (-V) comes in handy too: git tag | sort -V

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.