git rev-parse is Git's dictionary. It understands every form of
commit and ref notation, and converts them to a single canonical SHA.
Basic form
git rev-parse HEAD
# a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
git rev-parse main
# 7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d
If the name is ambiguous, it returns an error. If the name does not exist, the exit code is non-zero.
Ref syntax
| Notation | Meaning |
|---|---|
HEAD | where HEAD currently points |
main | the tip of branch main |
v1.0 | the commit the tag points to |
HEAD~3 | three commits back along the first parent |
HEAD^ | first parent (same as HEAD~1) |
HEAD^2 | second parent (for merge commits) |
HEAD@{yesterday} | where HEAD was yesterday (via reflog) |
:/fix typo | the most recent commit whose message contains "fix typo" |
<tag>^{commit} | the commit that an annotated tag points to |
HEAD:src/main.rs | the blob of this file from the current commit |
Utility modes
Beyond translating names to SHAs, rev-parse has several practical modes:
git rev-parse --show-toplevel
# /home/user/project <- repository root
git rev-parse --git-dir
# /home/user/project/.git <- where .git/ lives
git rev-parse --abbrev-ref HEAD
# main <- current branch name
git rev-parse --short HEAD
# a1b2c3d <- short unique SHA
git rev-parse --is-inside-work-tree
# true <- are we inside a repository?
--show-toplevel is especially useful in scripts and git hooks: it
returns the repository root from any subdirectory.
In scripts
Capture the current commit SHA:
CURRENT=$(git rev-parse HEAD)
Check that you are inside a repository:
if git rev-parse --git-dir > /dev/null 2>&1; then
echo "this is a git repo"
fi
Get the current branch name (without refs/heads/):
BRANCH=$(git rev-parse --abbrev-ref HEAD)
These are standard patterns in bash scripts that work with Git.
Pitfalls
HEAD^andHEAD~1are the same thing. ButHEAD^2is not the same asHEAD~2: the first is the second parent of a merge commit; the second is two commits back along the first parent.git rev-parse <tag>on an annotated tag returns the SHA of the tag object, not the commit. If you need the commit, use<tag>^{commit}.- On an empty repository,
git rev-parse HEADreturns an error because HEAD does not point to anything yet.