git tag v1.5.0 takes three seconds and produces the weaker of Git’s two tag types. For anything you will deploy, reference in a changelog, or bisect against later, take the extra flag.
Lightweight vs annotated#
A lightweight tag is just a name pointing at a commit - a branch that never moves. An annotated tag is a real Git object: it carries its own message, the tagger’s identity and the date:
git tag -a v1.5.0 -m "v1.5.0: invoice PDFs, queue retry fix"
That message is the difference. Six months from now, git show v1.5.0 on an annotated tag tells you what the release was; on a lightweight one it shows whatever commit happened to be tagged, with no context.
Tag what you deploy#
The tag should mark the commit that actually went out. On a merge-based flow that is the merge commit on main - not the last feature commit on the branch, and not “roughly that week”. Tagging anything else makes git bisect between releases and git log v1.4.0..v1.5.0 quietly wrong, and those two commands are the whole point of having tags.
Push them deliberately#
Tags do not travel with ordinary pushes:
git push origin v1.5.0
Push the one tag by name. git push --tags sends every local tag, including the throwaway markers you made for yourself - keep that one for the rare day you actually mean it.
Optional: signed tags#
git tag -s signs the tag with your key, so the release record is verifiable as yours. For a small team shipping to their own server it is usually more ceremony than threat model; for anything customers or auditors pull, it is the same calculation as signing commits - cheap with SSH keys, worth it when provenance matters.
Annotated tags plus the changelog habit are the whole release ritual: the tag marks what shipped and says it in a sentence, the log between tags writes the notes, and git bisect between two tags finds the commit that broke the build.
Share this post
Keep reading
Annotating Commits with git notes: Metadata Without Rewriting History
Some things belong on a commit but not in it: review links, benchmark results, the ticket nobody remembered to reference. git notes adds them after the fact, no rebase required.
Backing Up Your Git Server So It Actually Restores
Every clone is a partial backup - but hooks, config and server state live outside the repo. Mirror, bundle, copy off-site, and rehearse the restore.
Cherry-Picking: One Commit Without the Branch
Cherry-pick copies a single commit onto your branch and leaves the rest behind. Right for hotfixes across release branches, wrong as a sync strategy.