LinuxCommandLibrary

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)

$ git describe
copy

Create a name with 4 digits for the abbreviated commit hash
$ git describe --abbrev=[4]
copy

Generate a name with the tag reference path
$ git describe --all
copy

Describe a Git tag
$ git describe [v1.0.0]
copy

Create a name for the last commit of a given branch
$ git describe [branch_name]
copy

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

Copied to clipboard