GitListing & Searching Tags

Listing and Filtering Tags

As a repository matures, it accumulates dozens or hundreds of tags. Git provides powerful listing and filtering options so you can quickly find the tag you need, sort releases semantically, display messages, and generate human-readable version strings from the tag history. This page covers every listing command from the basics to advanced sorting and git describe.

List all tags

Basic tag listing

Bash
git tag
# v0.1.0
# v0.2.0
# v1.0.0
# v1.1.0
# v2.0.0-beta.1
# v2.0.0

# Equivalent long form:
git tag --list
Default sort order is alphabetical (lexicographic)
By default, `git tag` sorts alphabetically. This causes issues with version numbers: `v10.0.0` would appear before `v2.0.0` in lexicographic order. Use `--sort=version:refname` to get correct semantic ordering.
Filter tags with a wildcard pattern

The -l flag (short for --list) accepts shell glob patterns, letting you narrow down to specific version families.

Wildcard filtering with -l

Bash
# All tags matching v1.*
git tag -l "v1.*"
# v1.0.0
# v1.1.0
# v1.2.3

# All tags matching v2.0.*
git tag -l "v2.0.*"
# v2.0.0-beta.1
# v2.0.0-rc.1
# v2.0.0

# All pre-release tags (containing a dash)
git tag -l "*-*"
# v2.0.0-beta.1
# v2.0.0-rc.1

# Monorepo: all tags for the "api" package
git tag -l "api@*"
# api@1.0.0
# api@1.1.0
# api@2.0.0
Sort tags semantically (version order)

Semantic sort treats the tag name as a version number, so v2.0.0 correctly comes after v10.0.0 does not precede v2.0.0.

Semantic version sort

Bash
# Without sort — lexicographic (wrong for versions):
git tag
# v1.0.0
# v10.0.0   ← appears before v2!
# v2.0.0
# v9.5.1

# Correct semantic sort:
git tag --sort=version:refname
# v1.0.0
# v2.0.0
# v9.5.1
# v10.0.0   ← correctly last

# Reverse semantic sort (newest release first):
git tag --sort=-version:refname
# v10.0.0
# v9.5.1
# v2.0.0
# v1.0.0
Make semantic sort the default
Add this to your global Git config so all `git tag` invocations always use semantic sort: `git config --global tag.sort version:refname`
Sort by creation date (newest first)

Sort by when the tag was created

Bash
# Newest annotated tags first (uses tagger date for annotated,
# committer date for lightweight):
git tag --sort=-creatordate
# v2.0.0          ← created most recently
# v2.0.0-rc.1
# v1.1.0
# v1.0.0          ← created earliest

# Oldest first:
git tag --sort=creatordate
# v1.0.0
# v1.1.0
# v2.0.0-rc.1
# v2.0.0
Show tag messages with -n

The -n<num> flag (note: no space between -n and the number) appends the first num lines of each tag's message. For lightweight tags there is no message, so only the commit subject line appears.

Display tag messages alongside tag names

Bash
# Show 1 line of message per tag (default when -n is given alone):
git tag -n
# v1.0.0          Release 1.0.0
# v1.1.0          Release 1.1.0 - added dark mode
# v2.0.0-beta.1   Beta 1 of version 2.0.0

# Show up to 5 lines per tag:
git tag -n5
# v1.0.0          Release 1.0.0
#
#                 Highlights:
#                 - Complete authentication
#                 - Dashboard with charts
# v1.1.0          Release 1.1.0 - added dark mode

# Combine with sort and filter:
git tag -l "v1.*" --sort=version:refname -n1
# v1.0.0          Release 1.0.0
# v1.1.0          Release 1.1.0 - added dark mode
List tags with the commits they point to

Show tag names alongside commit hashes

Bash
# Show tag → commit hash
git show-ref --tags
# 3f8a2c9d... refs/tags/v1.0.0
# 7e4f1a2c... refs/tags/v1.1.0
# 9a8b7c6d... refs/tags/v2.0.0

# For annotated tags: dereference to the commit (not tag object)
git show-ref --tags --dereference
# 3f8a2c9d... refs/tags/v1.0.0
# a4b9c3e2... refs/tags/v1.0.0^{}   ← the actual commit
# 7e4f1a2c... refs/tags/v1.1.0
# b5c0d4f3... refs/tags/v1.1.0^{}
Find which tag a commit belongs to

Reverse lookup: commit to tag

Bash
# Which tags point to HEAD?
git tag --points-at HEAD
# v2.0.0

# Which tags point to a specific commit?
git tag --points-at 7e4f1a2
# v1.1.0

# Does a specific commit have any tag?
git describe --tags --exact-match 7e4f1a2
# v1.1.0
# (exits with error code if commit has no exact tag)
git describe — tag-based version strings

git describe is a command that produces a human-readable version string based on the nearest tag in the commit history. It is extremely useful in build systems and CI/CD pipelines because it uniquely identifies any commit relative to the closest release tag.

git describe output format

Bash
# When HEAD is exactly on a tag:
git describe --tags HEAD
# v1.0.0

# When HEAD is 3 commits ahead of v1.0.0:
git describe --tags HEAD
# v1.0.0-3-gabc1234
#    ^     ^    ^
#    |     |    Short SHA of HEAD (prefixed with 'g' for 'git')
#    |     Number of commits since the tag
#    Most recent tag reachable from HEAD

# --abbrev controls the SHA length:
git describe --tags --abbrev=8
# v1.0.0-3-gabc12345

# Always use annotated tags (default behavior):
git describe HEAD
# v1.0.0-3-gabc1234

# Include lightweight tags with --tags:
git describe --tags HEAD

Practical git describe in a build script

Bash
#!/bin/bash
VERSION=$(git describe --tags --always --dirty)
# Examples:
#   v1.0.0           (clean, on a tag)
#   v1.0.0-3-gabc123 (3 commits after v1.0.0, clean)
#   v1.0.0-3-gabc123-dirty (uncommitted changes present)

echo "Building version: $VERSION"
# Inject into a version file, Docker image tag, npm version, etc.
Summary of listing options

Command

What it shows

git tag

All tags, alphabetical order

git tag -l "v1.*"

Tags matching glob pattern

git tag --sort=version:refname

All tags in correct semantic version order

git tag --sort=-version:refname

All tags, newest version first

git tag --sort=-creatordate

All tags, most recently created first

git tag -n

All tags with first line of message

git tag -n5

All tags with up to 5 lines of message

git tag --points-at HEAD

Tags pointing to the current commit

git describe --tags

Version string relative to nearest tag

git show-ref --tags

Tags with their raw SHA values

Common errors

Error: -l with no pattern acts differently in older Git

Bash
# In Git < 2.7.0, 'git tag' alone listed all tags but
# 'git tag -l' without a pattern listed nothing.
# In modern Git (2.7+), both list all tags.

# Safe cross-version way to list all:
git tag --list
# (always works)

git describe: no tags found error

Bash
git describe --tags
# fatal: No names found, cannot describe anything.

# Fix: create at least one tag in the repository
git tag -a v0.1.0 -m "Initial release"

# Or use --always to fall back to a commit SHA:
git describe --tags --always
# abc1234   (just the abbreviated SHA when no tag is reachable)