Tags give permanent, human-readable names to the exact commits you shipped.
A tag is a name for a specific commit that, unlike a branch, does not move. Tags mark releases (v2.4.0), so you can always check out, diff against or rebuild exactly what shipped.
There are two kinds:
- Lightweight (
git tag v1.0): just a ref pointing at a commit, like a branch that never moves. - Annotated (
git tag -a v1.0 -m "Release 1.0"): a full object with tagger, date and message, and optionally a GPG/SSH signature (-s). Use annotated tags for releases; tools likegit describeand many release pipelines expect them.
Tags are not pushed by default. Push one with git push origin v1.0, all with git push --tags, or set push.followTags true so git push also sends annotated tags reachable from the commits you push.
Other commands:
git tag -l "v2.*": list matching tags.git show v1.0: the tag message and the commit.git tag -a v0.9 3f9a2c1 -m "...": tag an older commit.git tag -d v1.0thengit push origin --delete v1.0: delete locally and remotely.
git describe names any commit relative to the nearest annotated tag, for example v2.4.0-12-g9c1e2ab = 12 commits after v2.4.0, at commit 9c1e2ab. Many build scripts embed this as the version string.
Treat published tags as immutable. Moving a release tag after people have fetched it leads to confusing mismatches; make a new version instead.
Example
git tag -a v2.4.0 -m "Release 2.4.0"
git push origin v2.4.0
git config --global push.followTags true # push annotated tags with commits
git tag -l "v2.*" # v2.3.0 v2.4.0
git describe # v2.4.0-12-g9c1e2ab
git switch --detach v2.3.0 # look at an old release
git diff v2.3.0 v2.4.0 --statRemember
- Tags are fixed names for commits; branches move, tags don't
- Use annotated tags (-a or -s) for releases
- Tags aren't pushed by default: push them or enable push.followTags
- Don't move published tags; release a new version
Watch out for
- Tagging locally and forgetting to push the tag, so CI never sees the release.