You may know of the existence of tags from GitHub’s interface, but, like me until yesterday, what you may not know is how to create tags from command-line Git, the different types and what they are used for.

Licensing note

This post is a slightly modified version of the Git tags section in Pro Git, which I would highly recommend reading. The Git tags section in Pro Git is licensed under the Creative Commons Attribution Non Commercial Share Alike 3.0 license, as is this post.

What are tags?

Tags are used as markers for important points in your codebase. They’re often used to indicate release points (e.g. v0.1, v0.2, etc.).

There are two types of tags: annotated and lightweight. Lightweight tags are pointers to a particular commit. Annotated tags, on the other hand, are stored as full objects in Git’s database. They contain information such as a tagged name, email, date, tagging message and more. This might sound confusing, but this should become clearer after seeing some examples.

It’s recommended to use annotated tags over lightweight tags so that you can benefit from having the additional information. Lightweight tags are better suited for when you want a temporary tag or don’t care about the extra information you get with annotated tags.

Creating annotated tags

Pass in the -a option to git tag to make an annotated tag:

$ git tag -a v2.0 -m 'version 2.0'
$ git tag
v1.0
v1.1
v2.0

The -m option is used to specify an inline tagging message (similar to git commit). If you don’t pass in -m, Git will open your default editor for you to type in a message.

To see the tag information with the commit, you can run git show:

$ git show v2.0
tag v2.0
Tagger: Karan Kumar <my_email_address@gmail.com>
Date:   Sun Apr 12 11:19:21 2020 +0100

version 2.0

commit 30e840bf81ce1977e5101fee6e9f7d139f00431b (HEAD -> master, tag: v2.0, tag: v1.4)
Author: Karan Kumar <my_email_address@gmail.com>
Date:   Tue Apr 7 20:20:50 2020 +0100

    mit?

diff --git a/LICENSE b/LICENSE
index d689295..3b775fa 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1 +1,2 @@
 License stuff
+MIT?

Lightweight tags

Lightweight tags only store the commit checksum. To create one, don’t pass in the -a, -s or -m options:

$ git tag v1.3-lw
$ git tag
v0.1
v1.3-lw
v1.4
v2.0

If you run git show, you will see the difference between lightweight and annotated tags – lightweight tags don’t have the extra tag information.

$ git show -v1.3-lw
commit 30e840bf81ce1977e5101fee6e9f7d139f00431b (HEAD -> master, tag: v2.0, tag: v1.4, tag: v1.3-lw)
Author: Karan Kumar <my_email_addressgmail.com>
Date:   Tue Apr 7 20:20:50 2020 +0100

    mit?

diff --git a/LICENSE b/LICENSE
index d689295..3b775fa 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1 +1,2 @@
 License stuff
+MIT?

Tagging retrospectively

Git lets you tag old commits, too. Imagine if your commit history looks like the following:

$ git log --pretty=oneline
30e840bf81ce1977e5101fee6e9f7d139f00431b (HEAD -> master, tag: v2.0, tag: v1.4, tag: v1.3-lw) mit?
3a93e675501bd6dd05aeebdc4a1c0557b7c5fc72 first commit

Now, let’s say you wanted to tag the “first commit” commit with the tag v1.0. To do so, you pass in the commit checksum or a part of it at the end of the git tag command:

$ git tag -a v1.0 3a93e6

Tags on remote

Running git push does not, by default, push tags to a remote server. They have to be manually pushed after you make them. The command for doing this is similar to pushing a branch: git push origin [tag_name].

$ git push origin 2.0

Conveniently, you can pass in --tags to push all local tags that are not currently on the remote server.

$ git push origin --tags

When someone else clones or pulls from your repository, they will also now get your tags.

Show tags

To show what tags you currently have (shown in alphabetical order), run git tag:

$ git tag
v0.1
v0.2 

It’s worth noting that if you have just made a repository, there are no default tags. You’ll have to make your own first before any can be shown.

Search for tags

You can search for tags that match a specific pattern:

$ git tag -l 'v1.5.0*'
v1.5.0
v1.5.0-rc0
v1.5.0-rc1
v1.5.1

Further reading

If you’re interested in finding out more, I’d wholeheartedly recommend Pro Git.

Featured image:

Featured image: Brett Jordan