Command Reference

git tag Tutorial

Introduces git tag for release points, explains lightweight versus annotated tags, and covers basic tag publishing.

Who This Is For
  • Developers who already know basic commit and branch actions
  • Readers who want to understand command boundaries and risk
Prerequisites
  • A basic mental model of worktree, index, and commits
  • Comfort reading `git status` and a small commit graph
Common Risks
  • Using local cleanup commands on already shared history
  • Continuing to rewrite before confirming a recovery path

The short version

git tag gives a stable name to a specific commit, most often for releases.

Common forms

git tag v1.0.0
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin --tags

What problem this command solves in a workflow

git tag operates at the reference layer, binding a stable name to a specific commit. Unlike branches, tags typically never move once created, so it solves the problem of "giving a permanent name to a point in history" rather than managing day-to-day development workflow.

Typical use cases

  • Tag release versions (e.g., v1.0.0) so the team and CI/CD systems have a clear release anchor point.
  • Use annotated tags (-a) to record the tagger and a message, which suits formal release processes.
  • Lightweight tags are handy for local, temporary markers that you do not need to push to the team.

Diagram view

Where tags sit in the reference systemTags are references pointing at commits. Once created they typically do not move, in contrast to branch references.
Input
Target commitTag name(Annotated: author/message)
Output
New ref under refs/tags/(Annotated: a standalone tag object)
Tags are not pushed automatically; you need `git push origin <tag>` or `git push origin --tags` explicitly.

Signed tag workflow (GPG)

Signed tags provide cryptographic proof of who created the tag and that it hasn't been tampered with.

Setup

First, generate or import a GPG key, then tell Git which key to use:

# Generate a new GPG key (if you don't have one)
gpg --full-generate-key

# List your keys and find the key ID
gpg --list-secret-keys --keyid-format=long

# Configure Git to use this key
git config --global user.signingkey <KEY-ID>

Creating and verifying signed tags

# Create a signed tag (-s implies annotated)
git tag -s v2.0.0 -m "Release v2.0.0"

# Verify a signed tag
git tag -v v2.0.0

Verification shows the GPG signature status and the tag message. A "Good signature" confirms the tag is authentic.

Tag push strategies

Tags are not pushed automatically with git push. You must push them explicitly:

# Push a specific tag
git push origin v1.0.0

# Push all local tags at once
git push origin --tags

# Push only tags reachable from a specific branch
git push origin --follow-tags

Recommendation: Use --follow-tags (with push.followTags true in config) to push only annotated tags that are on the current branch. This avoids accidentally pushing experimental lightweight tags.

Lightweight vs annotated tags

FeatureLightweight TagAnnotated Tag
Created withgit tag v1.0git tag -a v1.0 -m "message"
Git objectReference onlyFull tag object
MetadataNoneTagger, date, message
Can be signedNoYes (-s flag)
Best forLocal markers, quick referencesReleases, public version points
Shown in git logAs commit hashAs tag object with message
Pushed by defaultNoNo (requires explicit push)

Rule of thumb: Use annotated tags for anything you share with the team. Use lightweight tags only for private, temporary markers.

Tag naming conventions

Consistent tag names make automation and collaboration easier:

  • SemVer: v1.2.3 — the most common convention. The v prefix is widely adopted by CI/CD tools.
  • Date-based: 2024-01-15-release — useful for time-driven release schedules.
  • Pre-release: v1.0.0-alpha.1, v1.0.0-beta.2, v1.0.0-rc.1 — following SemVer pre-release identifiers.
  • Avoid spaces and special characters — use hyphens and dots only.

Configure push.followTags to automatically push annotated tags:

git config --global push.followTags true

Deleting tags

Local deletion

git tag -d v1.0.0

Remote deletion

# Using --delete
git push origin --delete v1.0.0

# Or push nothing to the remote tag ref
git push origin :refs/tags/v1.0.0

Delete all local tags and re-fetch from remote

git tag -l | xargs git tag -d
git fetch --tags

Caution: Deleting a published tag that others have already fetched can cause confusion. If you must correct a tag, communicate the change to your team.

Special cases and boundaries

  • When a tag name and a branch name conflict in the same namespace, ambiguity arises, so naming should be distinctive.
  • Tags are created locally by default and are not automatically synced to the remote with git push.
  • A lightweight tag is just a reference pointer, while an annotated tag is a full object with metadata — prefer annotated tags for releases.
  • Renaming a commit that already has a tag requires -f to force-overwrite, but use caution to avoid misleading collaborators.