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
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
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
# 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
# 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
Sort by creation date (newest first)
Sort by when the tag was created
# 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
# 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
# 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
# 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
# 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
#!/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 |
|---|---|
| All tags, alphabetical order |
| Tags matching glob pattern |
| All tags in correct semantic version order |
| All tags, newest version first |
| All tags, most recently created first |
| All tags with first line of message |
| All tags with up to 5 lines of message |
| Tags pointing to the current commit |
| Version string relative to nearest tag |
| Tags with their raw SHA values |
Common errors
Error: -l with no pattern acts differently in older Git
# 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
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)