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>] [--long] [--dirty[=<mark>]] [--broken[=<mark>]] [--match <pattern>] [--exclude <pattern>] [--always] [--first-parent] [--exact-match] [--candidates=<n>] [--debug] [<commit-ish>...]
PARAMETERS
--all
Show heads/ or tags/ prefixes in the output, indicating if the closest reference was a branch or a tag.
--tags
Consider any tag in refs/tags, not just annotated tags, when searching for the nearest tag.
--contains
Instead of finding a tag that is an ancestor of the commit, find a tag that contains the given commit (i.e., is a descendant of the tag).
--abbrev=<n>
Use a different length for the abbreviated commit object name. A value of 0 suppresses the abbreviated hash entirely.
--long
Always show the long format (<tag>-<num>-g<hex>), even if the commit is exactly on a tag.
--dirty[=<mark>]
Append -dirty (or a custom <mark>) to the output if the working tree has uncommitted changes.
--broken[=<mark>]
Append -broken (or a custom <mark>) if the working tree has issues (e.g., untracked files preventing a clean state or merge conflicts).
--match <pattern>
Only consider tags matching the given glob pattern when searching for a tag.
--exclude <pattern>
Do not consider tags matching the given glob pattern.
--always
Fall back to the raw commit hash if no suitable tag can be found reachable from the commit.
--first-parent
Only follow the first parent commit when traversing the history, ignoring merges from other branches.
--exact-match
Only output a description if the commit is exactly a tag; otherwise, exit with an error.
<commit-ish>...
One or more commit objects to describe. If omitted, it defaults to HEAD (the current commit).
DESCRIPTION
git-describe
finds the most recent tag that is reachable from a given commit (or HEAD by default). It then outputs a string representing that commit in a human-readable way, typically in the format: <tag>[-<num>-g<hex>]. <tag> is the most recent annotated tag ancestor. <num> is the number of commits since that tag. <hex> is the abbreviated commit object name. This command is invaluable for automatically generating version strings for software builds, allowing developers and users to quickly identify the exact source code revision used for a particular build, even if it's not a direct tag. It helps in debugging and tracking releases without relying solely on raw commit hashes.
CAVEATS
git-describe
relies on the presence of tags in your repository's history. If no tags are found reachable from the target commit, the command will either fail or, with the --always option, fall back to showing the raw commit hash. Its output format can be complex, and its behavior can vary depending on whether annotated or lightweight tags are used, and the specific history structure. Results might not be intuitive if the commit history is heavily rebased or has multiple divergent branches with tags.
DEFAULT OUTPUT FORMAT
By default, git-describe
produces a string like <tag>[-<num>-g<hex>]. <tag> is the closest tag. If the commit is exactly on a tag, only <tag> is shown (unless --long is used). If the commit is not on a tag, <num> indicates how many commits away it is, and <hex> is a short hash of the commit, prefixed with 'g' for "git".
COMMON USE CASES
This command is widely used in automated build scripts (e.g., Makefiles, CI/CD pipelines) to embed version information directly into compiled binaries or release artifacts. It helps in quick identification of the exact source code state for debugging, customer support, or release management. For instance, a build version might be displayed as v2.1.0-42-gabcdef12.
HISTORY
The git-describe
command has been a core utility in Git since its early development. Its primary purpose was to provide a mechanism for software projects to automatically generate meaningful version strings from their Git repositories, particularly useful for builds and releases. This approach helps in uniquely identifying builds without manual version updates, aligning with Git's distributed nature where not all commits are necessarily "releases" but still need identifiable names.
SEE ALSO
git-tag(1): Create, list, delete or verify a tag object signed with GPG., git-log(1): Show commit logs., git-rev-parse(1): Pick out and massage parameters., git-show-ref(1): List references in a local repository.