9
votes
Do signed or annotated git tags have any special advantage over lightweight tags?
I'd been using the normal git tag -m <something>
command over the years to create tags and releases for even my open source side projects. But today I learned that such tags (unsigned or non-annotated) are supposed to be used only for private or temporary use. And we are supposed to run the following instead so that the tags get both annotated and signed:
git tag -m "v1.0" -a "v1.0"
The -a
tag can be used to add useful notes to the commit apparently. But apart from that, do you see any special advantages, especially when pushing code to Github? Is Github going to treat annotated code/releases/tags somewhat differently in any situation? I'm asking from a more pragmatic or utilitarian perspective.
Using '-m' does make an annotated tag.
To answer your question, a lightweight tag is simply a named commit, that's it. They aren't signed, have no additional information beyond simply a name/commit sha tuple. They can't be signed which is why you can't rely on them and should only be used locally, like making a tag on your branch for when it was working before you go doing a bunch of changes.
Annotated tags are signed objects, they contain an author, date,commit sha, message, additional information you provide and can be signed. So they can be trusted.
As far as I know, what GitHub calls tags are annotated tags and doesn't do anything with lightweight tags.
Thanks. I have already enabled gpg signing in my git global config so that commits get automatically signed. It's just the tag annotations part I was unaware of. So if -m switch will also create a signed tag, what for is the -a switch for? Do we need it for creating releases on github?
I think another advantage of annotated tags is that you can push them along with commits like this:
Without annotations, you will need two commands, one for commits and other for tags:
-a is the tag name
-m is the tag message
If you use -m without the -a, it is both the name and message.
As mentioned already, the 2 benefits I'm aware of are adding a message, and being able to push the tags to a remote repo. I regularly use:
And to list them back:
The
sort -V
is so that v0.10 comes after v0.9.On GitHub specifically tags don't seem to matter much, since they have this GitHub-specific feature called Releases which kind of supersedes Git tags. Still IMO feels cleaner to keep using Git tags appropriately, even if also using GitHub Releases.
It's also possible to make a GitHub action that creates a Release whenever you tag a commit in a certain way.
When you try to create a "Release", they are actually created out of tags only. It will give you a list of tags you have pushed. If you choose "v0.9.0", a corresponding release of that name is created and made available under releases tab. I think there is some redundancy here as they could have simply made the tags available for download as *.zip or *.tgz instead of a whole new releases process?
Tags (and branches, and arbitrary commits) are downloadable as zip or tar.
The main thing about the releases process is you can upload additional artifacts like binaries and assets, and you can include a description with release notes etc. I suppose you can add a message to a tag, but I don't believe there's any way to attach assets to a tag otherwise.
There's also the helpful
/latest
release which GitHub manages for you, rather than managing alatest
tag yourself.Example archive links
Tags:
https://github.com/psf/black/archive/refs/tags/24.4.2.zip
https://github.com/psf/black/archive/refs/tags/24.4.2.tar.gz
Branches:
https://github.com/psf/black/archive/refs/heads/main.zip
https://github.com/psf/black/archive/refs/heads/main.tar.gz
Commits:
https://github.com/psf/black/archive/3702ba224ecffbcec30af640c149f231d90aebdb.zip
https://github.com/psf/black/archive/3702ba224ecffbcec30af640c149f231d90aebdb.tar.gz
Releases:
https://github.com/psf/black/releases/tag/24.4.2
https://github.com/psf/black/releases/latest
Note the two "source code" links refer to the same
archive/refs/tags
urls, and they manually uploaded binaries as assets.Compare to
python/cpython
which does not use releases, only tags.https://github.com/python/cpython/releases/tag/v3.12.4
Got it. This is especially helpful for software projects that generate binaries like EXE or Java class files. Those can't be pushed along with tags or even maintained in the VCS.
It's also helpful for pinning versions in build systems.
For C++ projects I'll use CMake
FetchContent
orExternalProject
with a SHA archive link. Much faster downloads on large dependencies than checking out the entire repository, or trying to download archives in some other way.Zig's package manager is meant to be decentralized, so requires all dependencies to be an archive download link. It has pros and cons. Using tag or SHA archive links is great for this.
You can also push lightweight tags:
https://git-scm.com/book/en/v2/Git-Basics-Tagging
Sure, git will allow you to push but github.com might give it step motherly treatment. You might face problems with creating releases from those tags for instance (especially if they are not signed).