git-describe
Describe a git commit using the closest tag
TLDR
Create a unique name for the current commit (the name contains the most recent annotated tag, the number of additional commits, and the abbreviated commit hash)
Create a name with 4 digits for the abbreviated commit hash
Generate a name with the tag reference path
Describe a Git tag
Create a name for the last commit of a given branch
SYNOPSIS
git describe [--all] [--tags] [--contains] [--abbrev=n] [--dirty[=mark]] [--broken] [--match=pattern...] [--debug] [--long] [--exact-match] [--candidates=n] [--always] [commit-ish...] [--] [path...]
PARAMETERS
--all
Use any reference in .git/refs (tags, heads, remotes).
--tags
Use only tags (default behavior).
--contains
Find the oldest tag containing the commit (forward search).
--abbrev=n
Minimum hexdigits for abbreviated object name (default 7).
--dirty[=mark]
Append mark (default '-') if working tree is dirty.
--broken
Describe broken state (e.g., rebase in progress).
--match=pattern...
Only consider tags matching glob pattern(s).
--debug
Enable debug output showing candidate tags.
--long
Always show tag + distance + abbrev, even for exact tag matches.
--exact-match
Fail if commit is not exactly a tag (exit code 128).
--candidates=n
Consider up to n candidate tags (default 10).
--always
Show abbreviated SHA even if tag found.
DESCRIPTION
git describe generates a human-readable identifier for a Git commit by finding the most recent tag reachable from it, appending the number of commits since that tag, and an abbreviated object name.
It traverses the ancestry of the given commit (or HEAD by default) backward until it finds a tag. The output format is typically tagname-distance-gabbrevsha, e.g., v2.1.0-5-gfab3da4.
This is invaluable for build systems, packaging, and release management, providing short, sortable, unique names without full SHA-1. If the exact commit is tagged, it outputs just the tag name (unless --long or --always is used).
Tags must be annotated or lightweight; it prefers annotated. Without tags, it falls back to abbreviated SHA with --always. Supports dirty working trees via --dirty. Customizable with patterns, refs, and more for precise control.
CAVEATS
Output unstable if new tags added/removed between runs; use --match for reproducibility. Requires tags exist; empty repo yields abbreviated SHA with --always. Not for cryptographic security.
EXAMPLES
git describe
v1.0.0-3-gfab3da4 (3 commits past v1.0.0).
git describe --tags --abbrev=0
v1.0.0-3 (no SHA).
OUTPUT PARSING
Split by '-' then 'g': tag, distance, SHA. Use in scripts: $(git describe --tags --dirty --always).
HISTORY
Introduced in Git 1.0.11 (May 2006) by Linus Torvalds. Evolved with options like --dirty (1.5.5, 2007), --contains (1.6.3, 2009). Widely adopted in build tools (CMake, Meson) for semantic versioning.
SEE ALSO
git-tag(1), git-log(1), git-rev-parse(1), git-rev-list(1)


