Skip to content
LatchkeyLatchkey home

git rev-parse --show-toplevel and Friends in CI

git rev-parse is the plumbing that answers "where am I": --show-toplevel prints the repo root, --abbrev-ref HEAD the branch name, and --is-shallow-repository whether the clone is shallow.

CI scripts constantly need the repo root, the current branch, or whether the clone is shallow. git rev-parse answers all of these in a scriptable, machine-readable way, no parsing of git status output required.

What it does

git rev-parse converts arguments into the SHAs and paths git uses internally and exposes repository state via flags. It resolves a ref to a full SHA, prints the working-tree root, the .git directory, the current branch short name, and boolean state like shallow or inside-work-tree.

Common usage

Terminal
git rev-parse --show-toplevel        # absolute repo root
git rev-parse --abbrev-ref HEAD      # current branch name
git rev-parse HEAD                   # full commit SHA
git rev-parse --short HEAD           # abbreviated SHA
git rev-parse --is-shallow-repository
git rev-parse --verify --quiet refs/heads/main

Options

FlagWhat it does
--show-toplevelPrint the absolute path of the working-tree root
--git-dirPrint the path to the .git directory
--abbrev-ref <ref>Print a short ref name (HEAD -> branch name)
--short[=<n>]Abbreviate the SHA to n hex digits
--is-shallow-repositoryPrint true if the clone is shallow
--verify --quiet <ref>Validate a ref, exit nonzero if missing

In CI

On a detached HEAD (the usual state in CI), git rev-parse --abbrev-ref HEAD prints "HEAD" rather than a branch name, so read the branch from the CI environment (GITHUB_REF_NAME) instead. Use --is-shallow-repository to decide whether to --unshallow before describe or merge-base. --verify --quiet is the clean way to test if a ref exists without erroring the script.

Common errors in CI

"fatal: not a git repository (or any of the parent directories): .git" means the command ran outside the checkout, often the dubious-ownership case: add the path to safe.directory. "fatal: ambiguous argument 'HEAD'" appears in an empty repo with no commits. --abbrev-ref returning "HEAD" is not an error, it is detached HEAD.

Using this in CI

CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.

.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git rev-parse --abbrev-ref HEAD          # prints HEAD when detached

Frequently asked questions

git rev-parse --show-toplevel and Friends in CI?
CI scripts constantly need the repo root, the current branch, or whether the clone is shallow. git rev-parse answers all of these in a scriptable, machine-readable way, no parsing of git status output required.
What it does?
git rev-parse converts arguments into the SHAs and paths git uses internally and exposes repository state via flags. It resolves a ref to a full SHA, prints the working-tree root, the .git directory, the current branch short name, and boolean state like shallow or inside-work-tree.
In CI?
On a detached HEAD (the usual state in CI), git rev-parse --abbrev-ref HEAD prints "HEAD" rather than a branch name, so read the branch from the CI environment (GITHUB_REF_NAME) instead. Use --is-shallow-repository to decide whether to --unshallow before describe or merge-base.
Common errors in CI?
"fatal: not a git repository (or any of the parent directories): .git" means the command ran outside the checkout, often the dubious-ownership case: add the path to safe.directory. "fatal: ambiguous argument 'HEAD'" appears in an empty repo with no commits. --abbrev-ref returning "HEAD" is not an error, it is detached HEAD.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card