Just as a kind of mini cheat sheet for using git tags. Jörg Mittag had some great additions that weren’t in the original post which warrant a new post.
Git has three different type of tags:
- Lightweight tags
- Annotated tags
- Signed tags
Let’s start with lightweight tags.
Lightweight tags
In the previous cheat sheet only the lightweight local tags were discussed. A lightweight tag is nothing more than a reference to a particular revision or SHA1 object name in the repository. This kind of tag is quick and easy and very usable for local development to mark places in your commit history.
Creating a lightweight tag is easy:
git tag tag_name
Viewing available tags is done with -l:
git tag -l
Annotated tags
Annotated tags are almost like lightweight tags, the big difference is that they contain a message. Normally this message indicated why this tag is interesting. Use the -a option to create an annotated tag.
git tag -a tag_name
Since a message is required for annotated tags, you will be prompted with an editor to enter a message, or you can use the -m option to specify one directly.
git tag -a -m "Tagging release 1.0" v1.0
To view annotated tags you can use the same -l option as before, but you have to instruct git to show the annotation messages as well:
git tag -l -n1
This will not only show the messages for the annotated tags, it will also show the commit message of the revisions tagged with lightweight tags as well. Quite useful!
Signed tags
Signed tags take annotated tags a step further, they include an OpenPG signature to provide trust. While gits SHA1 tags provide integrity for the repository, the OpenPG signature makes sure that a trustworthy person created the tag.
To create a signed tag you’ll need to have GPG or some other OpenPG tool setup and use the -s option to sign the tag:
git tag -s -m "Tagging release 2.0" v2.0
The -s options implies the -a option, so here too a message is required.
To verify a signed tag you can run the following:
git tag -v v2.0
Deleting tags
There are times when you want to remove tags as well. This quite easy:
git tag -d tag_name
To remove a tag on a remote repository, you should do a special push:
git push origin :refs/tags/tag_name
Pushing tags
Jörg Mittag claims that annotated and signed tags are pushed and fetched automatically. I have never seen a tag of any kind being pushed automatically, so I hope Jörg can clarify this further.
To push your tags to a remote repository, use the following command to push all tags:
git push origin --tags
Happy tagging!

I think I got a little bit confused wrt the pushing and pulling stuff. I wrote my comment basically from memory. After your reply to my comment I started to research it, and now I’m completely lost :-)
Basically, tags are just refs (like branches), which live in .git/refs/tags (as opposed to branches which live in .git/refs/heads). If you have a push/pull refspec that includes refs/tags/* (or just refs/*), then new and/or deleted tags will be pushed/pulled just like new/deleted branches. (The whole refspec stuff is still more than a little unclear to me.) According to the git-pull manpage, tags that point to objects that are reachable from the heads that you are pulling, are automatically fetched, this can be overriden with the –tags (fetch *all* tags, not just the ones that are reachable) and –no-tags (do not fetch *any* tags) options. The reason why this is all so complicated is that all tags share a global namespace (unlike branches, whose names are namespaced by the remote they belong to). So, automatic following of tags only makes sense *within* a closed network of developers that have agreed on naming standards for tags. I believe that there are a few heuristics built into Git as to when a transaction crosses such network boundaries (e.g. when you clone a repository or add it as a remote, it is considered to be part of your network, but if you just do a one-shot git pull, giving it a full URI to pull from, then it’s not. But, I am not sure about that.)
BTW: a quick interesting tidbit: if you look at the tag refs in .git/refs/tags, you can see the difference between lightweight tags and annotated tags: lightweight tags point to *commit* objects, annotated tags point to *tag* objects (which in turn contain a reference to the commit object). IOW, lightweight tags aren’t objects of their own, whereas annotated tags *are* proper Git objects, which means they are part of the repository, they have a SHA1 and so on. (This also means that you can modify a lightweight tag, but not an annotated tag, because then its SHA1 would change.)
Thanks for this, most useful. Once change I had to make when pushing tags to Github is to omit the ‘origin’, e.g.:git push –tagsEverything else works as advertised :)
[...] http://ariejan.net/2009/09/05/git-tag-mini-cheat-sheet-revisited/?doing_wp_cron http://polywww.in2p3.fr/~gaycken/Calice/Software/my_git_workflow.html [...]
You can view an Spanish translation at http://www.jcastaneyra.com/2009/11/05/etiquetando-codigo-en-gittagging-code-in-git/
Thanks to José.