git for-each-ref: Usage, Options & Common CI Errors
git for-each-ref lists branches, tags, and other refs in exactly the format you specify.
When a pipeline needs the latest tag, all branches sorted by date, or refs pointing at a commit, for-each-ref gives stable, parseable output that beats scraping git branch or git tag.
What it does
git for-each-ref walks references matching a pattern and prints each using a custom --format with placeholders like %(refname), %(objectname), and %(creatordate), optionally sorted and filtered.
Common usage
git for-each-ref --format='%(refname:short)' refs/heads/
git for-each-ref --sort=-creatordate --format='%(refname:short)' refs/tags/
git for-each-ref --points-at HEAD
git for-each-ref --count=1 --sort=-v:refname 'refs/tags/v*'Options
| Flag | What it does |
|---|---|
| --format=<fmt> | Custom output with %(field) placeholders |
| --sort=<key> | Sort by a field (prefix - to reverse) |
| --points-at <obj> | Only refs pointing at an object |
| --count=<n> | Limit to the first n refs |
| --merged / --no-merged <ref> | Filter by merge state |
Common errors in CI
An empty result usually means the ref pattern did not match (refs/tags/ vs refs/tags/*) or that a shallow/single-branch clone never fetched the refs. Quote glob patterns so the shell does not expand them, and fetch tags (fetch-depth: 0) when you expect them.