# git show-ref --verify: Test a Ref Exists in CI

> git show-ref lists refs and --verify checks that a specific ref exists, the scriptable way CI tests for a branch or tag. Reference for flags and exit codes.

Source: https://latchkey.dev/learn/command-reference/git-show-ref-verify  
Updated: 2026-06-30

git show-ref --verify --quiet refs/heads/<branch> exits 0 if that exact ref exists and nonzero otherwise, the reliable way to test for a branch or tag in a script.

Scripts often need to know whether a branch or tag exists before acting. git show-ref --verify gives a clean exit code on a fully qualified ref, avoiding the ambiguity of partial name matching.

## What it does

git show-ref lists refs and their SHAs from refs/. With a pattern it lists matching refs; with --verify it requires an exact, fully qualified ref path and exits nonzero if it is absent. --quiet suppresses output so only the exit code matters. --heads and --tags filter to those namespaces.

## Common usage

```Terminal
# does a local branch exist?
git show-ref --verify --quiet refs/heads/release && echo yes
# does a tag exist?
git show-ref --verify --quiet refs/tags/v1.4.0
# list all branch refs with SHAs
git show-ref --heads
# get the SHA of a specific tag
git show-ref --tags refs/tags/v1.4.0
```

## Options

| Flag | What it does |
| --- | --- |
| --verify | Require an exact, fully qualified ref; nonzero if missing |
| --quiet | Print nothing; rely on the exit code |
| --heads | Limit to branch refs (refs/heads/) |
| --tags | Limit to tag refs (refs/tags/) |
| --hash[=<n>] | Print only the SHA (abbreviated to n) |
| -d / --dereference | Also show the SHA an annotated tag points to |

## In CI

Use the fully qualified path with --verify (refs/heads/x, refs/tags/x); a bare name fails. To check a remote-tracking branch fetched into the clone, verify refs/remotes/origin/<branch>. On a shallow single-branch clone, other branches and tags are simply absent, so show-ref legitimately reports them missing.

## Common errors in CI

"fatal: 'main' - not a valid ref" from --verify means you passed a short name instead of refs/heads/main. A nonzero exit with --quiet is the intended "not found" signal, not a crash. If a tag you expect is missing, the clone likely did not fetch tags; git fetch --tags.

## 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 show-ref --verify: Test a Ref Exists in CI?

Scripts often need to know whether a branch or tag exists before acting. git show-ref --verify gives a clean exit code on a fully qualified ref, avoiding the ambiguity of partial name matching.

### What it does?

git show-ref lists refs and their SHAs from refs/. With a pattern it lists matching refs; with --verify it requires an exact, fully qualified ref path and exits nonzero if it is absent. --quiet suppresses output so only the exit code matters. --heads and --tags filter to those namespaces.

### In CI?

Use the fully qualified path with --verify (refs/heads/x, refs/tags/x); a bare name fails. To check a remote-tracking branch fetched into the clone, verify refs/remotes/origin/<branch>. On a shallow single-branch clone, other branches and tags are simply absent, so show-ref legitimately reports them missing.

### Common errors in CI?

"fatal: 'main' - not a valid ref" from --verify means you passed a short name instead of refs/heads/main. A nonzero exit with --quiet is the intended "not found" signal, not a crash. If a tag you expect is missing, the clone likely did not fetch tags; git fetch --tags.

---

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
