git-name-rev
Find symbolic names for given commits
TLDR
Show the name for HEAD
Show only the name
Enumerate all matching ref names
Use only tags to name the commit
Exit with a non-zero status code instead of printing undefined for unknown commits
Show names for multiple commits
Restrict names to branch refs
Read commit IDs from stdin
SYNOPSIS
git name-rev [--options] <committish>...
PARAMETERS
<committish>...
One or more commit-ish objects (e.g., commit hash, branch name, tag name) for which to find symbolic names.
--tags
Only consider tags when trying to find a symbolic name for the revision. This can narrow down the search and provide more specific tag-based names.
--refs
Only consider all refs (branches, remote-tracking branches, tags) when trying to find a symbolic name. This is generally the default behavior if neither --tags nor --all is specified.
--no-undefined
Do not output 'undefined' when a name cannot be found for a given revision. Instead, the command will simply output the raw commit hash.
--always
Show 'undefined' if no name is found (this is the default behavior when --no-undefined is not used).
--abbrev[=n]
When no suitable symbolic name can be found, abbreviate the commit hash to n digits instead of its full length. If n is omitted, use the default abbreviation length.
--exclude=pattern
Do not consider any refs that match the given shell pattern when searching for a symbolic name.
DESCRIPTION
The git-name-rev command helps translate raw Git commit hashes into human-readable, symbolic names. Given one or more commit-ish arguments (like a full SHA-1 hash, a short hash, or a branch name), it attempts to find the most appropriate symbolic name that refers to that commit. This typically involves finding the closest reachable tag, branch, or remote-tracking branch, and then indicating the distance from that reference (e.g.,
main~3 or v1.0.0-3-g123abc).
This command is invaluable for making Git output more understandable, especially when dealing with commit IDs that are hard to remember or interpret. It's frequently used in scripts, debugging, and interactive sessions to provide context to specific points in a repository's history, making it easier to navigate and discuss.
By default, it tries to find the shortest possible name. If an exact match is not found, it finds the closest ancestor or descendant that has a name and calculates the distance, providing a concise and meaningful reference.
CAVEATS
git-name-rev can be computationally intensive, especially in repositories with very deep histories or a large number of references, as it may need to traverse significant portions of the commit graph. The 'best' name it finds is determined by internal heuristics (e.g., preferring shorter names, exact matches, and current refs), which might not always align with a user's intuitive understanding for complex scenarios. It's primarily designed for human readability and may not be suitable for programmatic parsing where precise, machine-readable revision specifications are required.
OUTPUT FORMAT
The output of git-name-rev for each given commit-ish is typically on a single line, formatted as:
<commit-id> SP (<name>)
where <commit-id> is the full 40-character SHA-1 hash of the commit, SP is a space, and <name> is the symbolic name found for the commit. If no name is found and --no-undefined is not used, <name> will be 'undefined'.
NAMING STRATEGY
git-name-rev employs a strategy to find the 'best' symbolic name. It prioritizes exact matches (where a ref points directly to the commit). If no exact match exists, it then traverses the history to find the closest ancestor or descendant that has a name, indicating the distance using suffixes like ~N (for ancestors) or ^N (for Nth parent if multiple parents exist, though ~N is more common for general ancestry). It generally prefers the shortest and most direct path to a named reference.
HISTORY
git-name-rev is a foundational utility within Git, designed from early on to enhance the user experience by making repository history more accessible and understandable. While specific major development milestones aren't widely documented, its role has consistently been to bridge the gap between raw, cryptographic commit identifiers and meaningful, human-comprehensible labels. It evolved as part of Git's robust set of tools for navigating and and visualizing complex commit graphs, becoming indispensable for both interactive use and scripting efforts to contextualize revisions.
SEE ALSO
git-rev-parse(1), git-rev-list(1), git-for-each-ref(1)