A tag is a human-readable named pointer to an object. It almost always points to a commit and is used to mark releases: "this commit is version 1.0." Formally, an annotated tag can point to a blob, tree, or another tag, but in practice that is rare.
Unlike a branch, a tag does not move. Once created, it stays on the commit it pointed to at creation time, unless you delete and recreate it.
Lightweight tag
A lightweight tag is just a file, .git/refs/tags/<name>, containing the
commit SHA. No object is created in .git/objects/:
git tag v1.0
cat .git/refs/tags/v1.0
# a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
In structure it resembles a branch, but it does not advance with new commits.
Annotated tag
An annotated tag is a full object in .git/objects/ with an author, date,
message, and an optional GPG signature:
git tag -a v1.0 -m "First stable release"
git cat-file -p v1.0
# object a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
# type commit
# tag v1.0
# tagger John Smith <email@example.com> 1716817500 +0300
#
# First stable release
The file .git/refs/tags/v1.0 points to this tag object, not directly to
the commit. The tag object in turn points to the commit.
Which to use
- For releases and public markers, use annotated. They carry an author, date, and message. They can be GPG-signed. Release history is trackable.
- For temporary bookmarks ("check this commit," "stuck here, revisit later"), lightweight is fine. Created instantly, no editor opened.
Signed tags
Annotated tags can be signed with a GPG key:
git tag -s v1.0 -m "Release 1.0"
The signature is stored inside the tag object. Verify with
git tag -v v1.0. This gives cryptographic proof that the tag was created
by the person whose key is listed and has not been tampered with.
Pushing to a remote
Tags are not pushed automatically along with commits. To send them:
git push origin v1.0 # one specific tag
git push origin --tags # all local tags
git push origin --follow-tags # annotated tags tied to commits being pushed
Semver
The standard naming convention for releases is vMAJOR.MINOR.PATCH. See
semver for details.