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

> git rev-parse resolves repo paths, refs, and state flags that CI scripts depend on: --show-toplevel, --abbrev-ref, --is-shallow-repository. Reference and errors.

Source: https://latchkey.dev/learn/command-reference/git-rev-parse-show-toplevel  
Updated: 2026-06-30

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

| Flag | What it does |
| --- | --- |
| --show-toplevel | Print the absolute path of the working-tree root |
| --git-dir | Print 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-repository | Print 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
```

> `git rev-parse --abbrev-ref HEAD` returns the literal string `HEAD` on a detached checkout rather than a branch name. On GitHub Actions read `github.ref_name` instead; the git command cannot know what it was checked out for.

## FAQ

### 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.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
