Skip to content
Latchkey

git ls-remote --heads/--tags: Query a Remote in CI

git ls-remote --heads origin <name> lists matching branch refs on the remote without cloning, the cheap way for CI to test whether a branch or tag exists upstream.

Before a job clones or pushes, it often needs to know what refs the remote actually has. ls-remote answers that over the network without a working tree, and --symref reveals the remote default branch.

What it does

git ls-remote contacts a remote and prints its advertised refs and SHAs. --heads and --tags filter to branches or tags. A trailing pattern narrows further. --symref additionally shows what symbolic refs like HEAD point to, which tells you the default branch without cloning.

Common usage

Terminal
git ls-remote --heads origin
# does a branch exist upstream? (empty output = no)
git ls-remote --heads origin release-1.0
# the remote default branch
git ls-remote --symref origin HEAD
# the SHA of a tag on the remote
git ls-remote --tags origin v1.4.0

Options

FlagWhat it does
--headsList only branch refs
--tagsList only tag refs
--symrefAlso show symbolic refs (e.g. HEAD -> main)
--refsFilter out peeled tag (^{}) entries
--exit-codeExit 2 if no matching refs are found
<remote> <pattern>Limit to refs matching the pattern

In CI

ls-remote needs credentials for private repos just like clone; failures here are usually auth, not missing refs. Use --exit-code so a script can branch on "ref absent" cleanly instead of parsing empty output. --symref origin HEAD is the portable way to discover main vs master before checkout.

Common errors in CI

"fatal: Could not read from remote repository." with "Permission denied (publickey)" or HTTPS auth prompts means credentials are missing/wrong, not that the ref is absent. "remote: Repository not found" on a private repo is usually an auth problem masquerading as 404. Empty output is the normal "no such ref" result.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →