Oct. 16, 2008, 10:16 p.m.

Git Tag Does the Wrong Thing by Default

I'm writing this because I don't think anyone is actually aware of it, but I keep seeing it show up in various projects.

When you have done all the cool work you want to do and get ready to tag it, you may think the right thing to do is this:

# THIS IS WRONG!
git tag 1.0

...but that does not create a tag. A tag is a special kind of object. It has a date, tagger (author) its own ID, and optionally a GPG signature. The default mechanism above creates something called a "lightweight" tag. A lightweight tag is a ref pointer that is more like a branch than a tag. If you've used mercurial before, you can liken this to hg tag -l to create a "local" tag.

The right way to create a tag is to make either an annotated (-a) or signed(-s) tag:

# This is the right way!
tag -a 1.0

A signed tag works the same way, but cryptographically signs the tag with your private GPG key.

# This is also the right way!
tag -s 1.0

Why does this matter, you ask? Because a real tag also works with things like git describe -- which is very useful when you're rolling releases.

You can see the difference here:

dustinmb:/tmp/project 549% git init
Initialized empty Git repository in /private/tmp/project/.git/
dustinmb:/tmp/project 550% touch afile
dustinmb:/tmp/project 551% git add afile 
dustinmb:/tmp/project 552% git commit -m 'added afile'
Created initial commit d1e6305: added afile
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 afile
dustinmb:/tmp/project 553% git describe 
fatal: cannot describe 'd1e6305e4d8e00cf5f6f9cd5143ab96fb3451f0d'
dustinmb:/tmp/project 554% git tag 1.0
dustinmb:/tmp/project 555% git describe 
fatal: cannot describe 'd1e6305e4d8e00cf5f6f9cd5143ab96fb3451f0d'
dustinmb:/tmp/project 556% git tag -am 'Rolled the annotated version' 1.0-a
dustinmb:/tmp/project 557% git describe 
1.0-a
dustinmb:/tmp/project 558% git show 1.0-a
tag 1.0-a
Tagger: Dustin Sallings <dustin@spy.net>
Date:   Thu Oct 16 22:26:28 2008 -0700

Rolled the annotated version
commit d1e6305e4d8e00cf5f6f9cd5143ab96fb3451f0d
Author: Dustin Sallings <dustin@spy.net>
Date:   Thu Oct 16 22:25:46 2008 -0700

    added afile

diff --git a/afile b/afile
new file mode 100644
index 0000000..e69de29
dustinmb:/tmp/project 559% git tag -sm 'Rolled the signed version.' 1.0-s

You need a passphrase to unlock the secret key for
user: "Dustin Sallings (primary) <dustin@spy.net>"
1024-bit DSA key, ID 43E59D54, created 2003-01-18

dustinmb:/tmp/project 560% git show 1.0-s
tag 1.0-s
Tagger: Dustin Sallings <dustin@spy.net>
Date:   Thu Oct 16 22:27:12 2008 -0700

Rolled the signed version.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Darwin)

iEYEABECAAYFAkj4IjAACgkQeWDnv0PlnVTS7gCggImUJawC+cNEppCQ9bTtw+MZ
Nq4An2Vr7gbUAUDEQY97P1hwKK8cehfW
=Al8E
-----END PGP SIGNATURE-----
commit d1e6305e4d8e00cf5f6f9cd5143ab96fb3451f0d
Author: Dustin Sallings <dustin@spy.net>
Date:   Thu Oct 16 22:25:46 2008 -0700

    added afile

diff --git a/afile b/afile
new file mode 100644
index 0000000..e69de29
dustinmb:/tmp/project 561% git for-each-ref 
d1e6305e4d8e00cf5f6f9cd5143ab96fb3451f0d commit refs/heads/master
d1e6305e4d8e00cf5f6f9cd5143ab96fb3451f0d commit refs/tags/1.0
2b521732e0717c9f3f27330133be95284a059252 tag    refs/tags/1.0-a
13cf45a9eca3d3b4b3d1405588f9d6e551515a89 tag    refs/tags/1.0-s

You can pretty clearly see the difference here. One is not a tag, and the other two are. The two that are will work happily with describe and just overall make more sense.

So please, use -a with your tags and make describe and related tools happy.

blog comments powered by Disqus