iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Tags & Releases

A tag is a named pointer to a commit, used most often for releases. There are two kinds: lightweight (just a name pointing at a commit) and annotated (its own object with author, date, message, optional GPG signature). Default to annotated tags for anything you publish — they carry provenance.

Create, list, push, sign, and delete tags

EXAMPLE
# 1) Annotated tag with a message (the right default for releases)
git tag -a v1.2.3 -m 'Release 1.2.3 — bug fix for shipping calc'

# 2) Lightweight tag — quicker, no metadata. Fine for personal bookmarks.
git tag prod-2026-06-11

# 3) Tag a past commit by hash
git tag -a v1.2.2 9fceb02 -m 'Belated tag for the prior release'

# 4) Sign a tag (GPG or SSH) — verifiable provenance
git tag -s v1.2.3 -m 'Signed release 1.2.3'
git tag -v v1.2.3            # verify signature

# 5) List tags, with pattern filtering
git tag
git tag --list 'v1.*'
git tag --sort=-version:refname     # newest first, semver-aware

# 6) Push tags to the remote — they are NOT pushed by default
git push origin v1.2.3
git push origin --tags              # push every local tag
git push --follow-tags              # only push annotated tags reachable from HEAD

# 7) Delete a tag locally and on the remote
git tag -d v1.2.3
git push origin :refs/tags/v1.2.3   # legacy syntax, still works
git push origin --delete v1.2.3     # newer syntax

# 8) Move a tag to a different commit (last resort — published tags should never move)
git tag -fa v1.2.3 <newSha> -m 'Move tag; only do this BEFORE pushing'

# 9) Check out the code for a tag — detached HEAD
git checkout v1.2.3                # work in detached HEAD
git switch --detach v1.2.3         # explicit (Git 2.23+)

# 10) Pipe tags into a release notes section
git log v1.2.2..v1.2.3 --pretty=format:'* %s (%h)' --no-merges

# 11) CI flow: bump version, commit, tag, push
# scripts/release.sh (sketch)
# v="v${1:?usage: release VERSION}"
# git tag -a "$v" -m "Release $v"
# git push --follow-tags

Why it matters

Treat tags as immutable once pushed. Moving or deleting a published tag breaks every clone, every CI artifact, every reference in changelogs. The cost of moving a tag is real even when nothing visibly explodes — it silently corrupts other peoples sense of what \"v1.2.3\" means.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
git tag v1.0.0
git tag -a v1.1.0 -m 'release notes'
git push --tags
Try it Yourself »

Discussion

Loading…