Back
GitoryxGitoryx

Git Tag: Mark Releases and Milestones in Your History

Git tags let you permanently mark specific commits: typically releases or milestones. This tutorial covers creating lightweight and annotated tags, listing and pushing them, and the most common mistake developers make: forgetting that git push doesn't send tags automatically.

Beginner8 min readUpdated

On this page

What is a Git tag?

A Git tag is a named pointer to a specific commit that never moves. Tags come in two types: lightweight (just a pointer, no extra metadata) and annotated (stores a message, author, and date, recommended for releases). Tags must be pushed to a remote separately from commits.

The short version

  1. 1List existing tags: git tag
  2. 2Create an annotated tag: git tag -a v1.0.0 -m 'Release 1.0.0'
  3. 3Push a tag to remote: git push origin v1.0.0
  4. 4View tag details: git show v1.0.0
  5. 5Delete a tag locally: git tag -d v1.0.0
  6. 6Delete a tag on remote: git push origin --delete v1.0.0

Why it matters

You shipped a stable release but a week later you can't find the exact commit it was built from. Or you tagged a release locally and your teammates can't see it because you never pushed the tag. Sound familiar?

Tags are the standard way to mark release points (v1.0.0, v2.3.1) in your Git history. Unlike branches, they don't move. A tag permanently points to one commit, making it the reliable anchor for changelogs, rollbacks, and CI deployments.

Where it usually goes wrong

  • Creating a tag locally but forgetting that git push does not push tags automatically
  • Using lightweight tags for releases instead of annotated tags, which carry no author, date, or message
  • Tagging the wrong commit because you didn't check git log first
  • Deleting a tag that was already pushed without removing it from the remote too

Git tag, step by step

  1. Step 1: List all existing tags

    Before creating a tag, check what tags already exist in the repository. Use -l with a glob pattern to filter by prefix.

    Terminal
    # List all tagsgit tag# Filter by pattern (e.g. v1.*)git tag -l "v1.*"# Show tags in chronological ordergit log --tags --simplify-by-decoration --oneline

    Tip: Tags are listed alphabetically by default, which breaks for versions like v1.9.0 vs v1.10.0. Use git tag -l --sort=-version:refname for correct semantic version ordering.

  2. Step 2: Create a lightweight tag

    A lightweight tag is simply a name pointing to a commit, with no message, no author, and no date. Useful for temporary local bookmarks, but not recommended for public releases.

    Terminal
    # Tag the current commit (HEAD)git tag v1.0.0# Tag a specific commitgit tag v1.0.0 9b1e4fa

    Careful: Lightweight tags carry no metadata. Tools like GitHub Releases, CI pipelines, and changelog generators rely on annotated tag objects. Use annotated tags for anything public.

  3. Step 3: Create an annotated tag (recommended for releases)

    An annotated tag stores a message, the tagger's name and email, and a timestamp, making it a full Git object. Use -a for annotated and -m for an inline message.

    Terminal
    # Annotated tag on HEADgit tag -a v1.0.0 -m "Release version 1.0.0"# Annotated tag on a specific commitgit tag -a v1.0.0 -m "Release version 1.0.0" 9b1e4fa# View the tag details (message, tagger, date)git show v1.0.0

    Tip: Follow semantic versioning: vMAJOR.MINOR.PATCH. Breaking changes → major, new features → minor, bug fixes → patch.

  4. Step 4: Push tags to remote

    git push does not push tags. You must push them explicitly, either one at a time or all at once with --tags.

    Terminal
    # Push a single taggit push origin v1.0.0# Push all local tags not yet on the remotegit push origin --tags

    Careful: git push --tags pushes every local tag including lightweight ones. To push only annotated tags alongside your latest commit, use git push --follow-tags.

    In Gitoryx: Tags appear as labels directly on commits in the Gitoryx commit graph: no need to run git log --decorateHow it works
  5. Step 5: Checkout a tag

    Checking out a tag puts you in 'detached HEAD' state, meaning you're viewing the repository exactly as it was at that tagged commit. Any commits made here won't belong to a branch.

    Terminal
    git checkout v1.0.0# HEAD is now at 9b1e4fa... (detached)# To make changes based on a tag, create a branch from it:git checkout -b hotfix/v1.0.1 v1.0.0

    Tip: If you need to make a hotfix on a tagged release, always create a new branch from the tag rather than committing in detached HEAD.

  6. Step 6: Delete a tag

    Deleting a local tag does not remove it from the remote. You must delete it in both places separately.

    Terminal
    # Delete a local taggit tag -d v1.0.0# Delete the tag on the remotegit push origin --delete v1.0.0

    Careful: Deleting a tag that others may have already pulled causes confusion. Communicate the deletion to your team before removing a public tag from the remote.

Mistakes to avoid with git tag

Forgetting to push tags
git push only pushes commits and branch refs: tags are entirely separate. A tag that exists only locally is invisible to teammates, CI pipelines, and GitHub Releases.
Fix: After creating a tag, always run git push origin <tagname> or git push origin --tags to make it available on the remote.
Using lightweight tags for releases
Lightweight tags store no metadata. Tools like GitHub Releases, semantic-release, and changelog generators rely on annotated tag objects to generate release notes.
Fix: Use git tag -a <name> -m '<message>' for any tag intended as a public release. Reserve lightweight tags for private local bookmarks.
Tagging the wrong commit
It's easy to tag HEAD without realising it's not the right commit, especially after a recent pull.
Fix: Run git log --oneline -5 before tagging to confirm HEAD is correct. When in doubt, tag a specific SHA: git tag -a v1.0.0 -m 'msg' <sha>.

Git tag in Gitoryx

Gitoryx displays all tags inline on the commit graph: you can see at a glance which commits are tagged, create or delete tags with a right-click, and push them to remote in one click.

  • Tags appear as labels directly on commits in the Gitoryx commit graph: no need to run git log --decorate
  • Right-click any commit to create or delete a tag without copying a SHA
  • Push tags to remote in one click from the tag context menu
  • Gitoryx distinguishes annotated and lightweight tags visually in the graph

Free plan · no account required · macOS, Windows and Linux

Git tag: frequently asked questions

What is the difference between a lightweight and annotated tag?
A lightweight tag is just a named pointer to a commit with no extra data. An annotated tag is a full Git object that stores a message, the tagger's name and email, and a timestamp. Annotated tags are recommended for releases because they carry metadata and are treated as proper release objects by most tools.
Why can't my teammates see my tag?
git push does not push tags automatically. Run git push origin <tagname> to push a specific tag, or git push origin --tags to push all local tags to the remote.
How do I tag a previous commit, not HEAD?
Pass the commit SHA as the last argument: git tag -a v1.0.0 -m 'message' <sha>. Find the SHA with git log --oneline.
Can I move a tag to a different commit?
Yes, but it requires force: git tag -f v1.0.0 <new-sha>. If the tag was already pushed, also force-push it: git push origin -f v1.0.0. Only do this before others have pulled the tag.
How do I list tags sorted by semantic version?
Use git tag -l --sort=-version:refname to list tags in descending semantic version order. This is more reliable than alphabetical sort for versions like v1.10.0 vs v1.9.0.
All Git tutorials →
Gitoryx

Stop fighting Git. Start shipping.

Download the fast, native Git client that developers actually enjoy using.

v1.1.0 · macOS 12+ (Apple Silicon or Intel) · Windows 10+ · Linux x86_64