git range-diff shows how a series of commits changed between two iterations - a diff of diffs.
range-diff is invaluable after a rebase or force-push: it tells you what actually changed between the old and new series.
What it does
git range-diff matches up commits from two ranges and shows how each changed, making it easy to review what a rebase or amended series altered beyond just moving the base.
fatal: need two commit ranges - range-diff requires two ranges (or the base/old/new triple). Mis-specifying ranges yields confusing "all commits new" output; ensure both ranges share a base, and that full history is present (not a shallow clone).
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 range-diff: Usage, Options & Common CI Errors?
range-diff is invaluable after a rebase or force-push: it tells you what actually changed between the old and new series.
What it does?
git range-diff matches up commits from two ranges and shows how each changed, making it easy to review what a rebase or amended series altered beyond just moving the base.
Common errors in CI?
fatal: need two commit ranges - range-diff requires two ranges (or the base/old/new triple). Mis-specifying ranges yields confusing "all commits new" output; ensure both ranges share a base, and that full history is present (not a shallow clone).