Git Course 0%

git tag

Intermediate Git CLI Careful ≈ 5 min

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

Terminal
$ git tag -a v1.3.0 -m "Release 1.3.0: Windows FAQ and licence wording"
$ git tag
v1.2.0
v1.3.0
Terminal
$ git tag -n
v1.2.0          
v1.3.0          Release 1.3.0: Windows FAQ and licence wording

The blank message beside v1.2.0 is the tell-tale of a lightweight tag: there is no message because there is no tag object.

Terminal
$ git show v1.3.0 --stat
tag 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:

Terminal
$ git push origin v1.3.0
To https://gitlab.com/you/trailguide.git
 * [new tag]         v1.3.0 -> v1.3.0
Terminal
$ git push --tags
To https://gitlab.com/you/trailguide.git
 * [new tag]         v1.1.0 -> v1.1.0
 * [new tag]         v1.2.0 -> v1.2.0

Deleting in both places:

Terminal
$ git tag -d v1.1.0
Deleted tag 'v1.1.0' (was 683cb88)
Terminal
$ git push origin --delete v1.1.0
To https://gitlab.com/you/trailguide.git
 - [deleted]         v1.1.0

And the refusal when a name is taken:

Terminal
$ git tag v1.3.0
fatal: tag 'v1.3.0' already exists

Expected 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 push to 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 describe failing 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 LogNew Tag…. The Push dialog has a Push Tags checkbox.

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.

Key terms

Tag Release Version Commit