git tag
Intermediate Git CLI Careful
Summary: git tag <name> gives a commit a permanent name. Unlike a branch, a tag never moves, which is what makes it right for marking releases.
Careful — creating and listing are harmless. Moving or deleting a tag that has been pushed breaks everyone who already fetched it, so treat a published tag as permanent.
What it does
Writes a file under .git/refs/tags/. A lightweight tag is just a name pointing at a commit; an annotated tag (-a) is a small object of its own carrying a tagger, a date and a message, and it is the right choice for releases.
Tags are not pushed by git push alone: they must be pushed explicitly.
Why it exists
Branches move as work continues, so they cannot mark "this exact state was version 1.3.0". Tags can, and platforms build their release pages on them.
When to use it
- Marking a release, usually with the version number:
v1.3.0. - Marking any commit you will want to refer to later: an audit point, the state at a migration.
- Starting a hotfix from the released state:
git switch -c hotfix/23 v1.2.0(lesson 6.2).
When not to use it
- As a moving marker for "latest"; that is what a branch is.
- To mark work in progress; tags are for states worth naming forever.
Syntax
| Form | Meaning |
|---|---|
git tag |
List tags |
git tag -n |
List with the annotation message |
git tag <name> |
Lightweight tag at the current commit |
git tag -a <name> -m "<message>" |
Annotated tag, with tagger and message |
git tag <name> <commit> |
Tag an older commit |
git show <tag> |
The tag's message and the commit it names |
git push origin <tag> |
Push one tag |
git push --tags |
Push all local tags |
git tag -d <name> |
Delete locally |
git push origin --delete <name> |
Delete on the remote |
git describe --tags |
Name the current commit relative to the nearest tag |
Examples
$ git tag -a v1.3.0 -m "Release 1.3.0: Windows FAQ and licence wording"
$ git tagv1.2.0
v1.3.0$ git tag -nv1.2.0
v1.3.0 Release 1.3.0: Windows FAQ and licence wordingThe blank message beside v1.2.0 is the tell-tale of a lightweight tag: there is no message because there is no tag object.
$ git show v1.3.0 --stattag v1.3.0
Tagger: You <you@example.com>
Date: Fri Sep 4 09:00:00 2026 +0200
Release 1.3.0: Windows FAQ and licence wording
commit 70bbe7653e3b3d9f35c1e5fdd6c5a7b963c1b328
Author: Ben <ben@northwind-trails.example>
Date: Thu Sep 3 09:00:00 2026 +0200
docs: clarify the licence answer (#15)Pushing, which is a separate step:
$ git push origin v1.3.0To https://gitlab.com/you/trailguide.git
* [new tag] v1.3.0 -> v1.3.0$ git push --tagsTo https://gitlab.com/you/trailguide.git
* [new tag] v1.1.0 -> v1.1.0
* [new tag] v1.2.0 -> v1.2.0Deleting in both places:
$ git tag -d v1.1.0Deleted tag 'v1.1.0' (was 683cb88)$ git push origin --delete v1.1.0To https://gitlab.com/you/trailguide.git
- [deleted] v1.1.0
And the refusal when a name is taken:
$ git tag v1.3.0fatal: tag 'v1.3.0' already existsExpected result
A file under .git/refs/tags/, and after a push the tag appears on the platform's tags and releases pages. Checking out a tag puts you in detached HEAD, which is expected: a tag names a commit, not a branch.
Common mistakes
- Expecting
git pushto include tags. It does not; push the tag explicitly or use--tags. - A lightweight tag for a release. No message, no tagger, no date of its own. Use
-a. - Moving a published tag with
-f. Everyone who fetched it keeps the old one, and the two disagree silently. Create a new version instead. - Committing while on a checked-out tag. You are in detached HEAD;
git switch -c <name>first (lesson 2.5). git describefailing with "No names found" in a repository that has no tags yet.
How to undo or recover
- Not yet pushed:
git tag -d <name>and create it again. - Already pushed: delete in both places if it is genuinely wrong and nobody has used it, and tell the team. Otherwise leave it and tag a new version; permanence is the feature.
In VS Code
Command Palette → Git: Create Tag and Git: Delete Tag; pushing tags is offered by Git: Push (Follow Tags) or from the terminal.
In IntelliJ IDEA
Git → New Tag… on the current commit, or right-click a commit in the Log → New Tag…. The Push dialog has a Push Tags checkbox.
Related commands
git push publishes tags · git switch creates a branch from one · git log with --decorate shows them · git show displays one.
Lessons that use this command
Tags, releases, semantic versioning · Branch types and naming · HEAD, refs, origin, upstream.