git rev-list --count: Usage, Options & Common CI Errors
By Daniel Zoghalchali·Latchkey
git rev-list --count prints how many commits a range contains.
Need to know how many commits a branch is ahead, or how many landed since a tag? rev-list --count gives a single number that is easy to compare in CI conditions.
What it does
git rev-list --count walks the requested revision range and prints only the count of matching commits, instead of listing their SHAs.
Common usage
Terminal
git rev-list --count HEAD
git rev-list --count main..feature # commits ahead of main
git rev-list --count --left-right main...feature
git rev-list --count v1.0.0..HEAD # commits since a tag
Options
Flag
What it does
--count
Print the number, not the list
<a>..<b>
Commits in b not in a
<a>...<b>
Symmetric difference
--left-right
With ..., split counts per side
--no-merges
Exclude merge commits
Common errors in CI
A two-dot range (main..feature) needs both refs present; on a shallow clone the merge base may be missing and the count is wrong or errors. Use fetch-depth: 0. Note .. (asymmetric) and ... (symmetric) differ - mixing them up gives surprising ahead/behind numbers.
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@v4with:fetch-depth:0 # history, tags, and git describe all need this- run:|git rev-parse --is-shallow-repository # expect falsegit rev-parse --abbrev-ref HEAD # prints HEAD when detached
Frequently asked questions
git rev-list --count: Usage, Options & Common CI Errors?
Need to know how many commits a branch is ahead, or how many landed since a tag? rev-list --count gives a single number that is easy to compare in CI conditions.
What it does?
git rev-list --count walks the requested revision range and prints only the count of matching commits, instead of listing their SHAs.
Common errors in CI?
A two-dot range (main..feature) needs both refs present; on a shallow clone the merge base may be missing and the count is wrong or errors. Use fetch-depth: 0. Note .. (asymmetric) and ... (symmetric) differ - mixing them up gives surprising ahead/behind numbers.