The problem range-diff solves
Suppose a contributor pushes v1 of a patch series, then v2 after review feedback. As a reviewer, you want to see what changed between the versions, not the cumulative diff. git range-diff shows exactly that: the diff between two ranges of commits.
The basic invocation
git range-diff main..v1 main..v2
This compares the commits in main..v1 with those in main..v2, pairing them by similarity, and shows what changed.
Reading the output
Each line corresponds to a pair of commits:
1: abc1234 = 1: def5678 Add login form
2: 234abcd ! 2: 9876fed Validate email format
@@ src/login.js
- if (!email.includes("@")) {
+ if (!EMAIL_REGEX.test(email)) {
3: <new> > 3: 111aaaa Add unit tests for validator
=commits are identical.!commits have the same intent but differ in content - shown with a sub-diff.>commits exist only on the right (added).<commits exist only on the left (removed).
Pairing logic
Range-diff uses commit metadata (subject, author, content fingerprint) to pair commits across the ranges. Reordering commits within a range is detected and shown.
Reviewing forced-pushed PRs
The killer use case: a contributor force-pushes after addressing review comments. GitHub now shows range-diff inline; on the CLI:
git fetch origin pr/123:pr-123-old # save old version
# ...wait for force push...
git fetch origin pr/123
git range-diff main..pr-123-old main..origin/pr/123
You see only the changes the author made in response to feedback - not the entire feature again.
Range-diff during rebase
After interactive rebase, verify the rewrite preserved intent:
git rebase -i HEAD~5
# ...rewrite...
git range-diff ORIG_HEAD HEAD
If only message reword was intended, the diffs should be empty for content. If you accidentally lost a hunk, range-diff will show it.
Range-diff for releases
Comparing two release branches:
git range-diff origin/release-1.4 origin/release-1.5
Useful when verifying that a backport applied identically across release lines.
Tuning the comparison
# Adjust pairing sensitivity
git range-diff --creation-factor=80 base..v1 base..v2
# Show only summaries
git range-diff --no-patch base..v1 base..v2
Format-patch integration
For email-based patch workflows (Linux kernel, Git itself), format-patch can embed range-diff in the cover letter:
git format-patch --range-diff=v1 --cover-letter -3
Reviewers see "what changed since v1" inline.
Common pitfalls
- Commits with very different content but the same subject can pair surprisingly.
- Range-diff is a comparison, not a merge tool - it does not produce a unified diff you can apply.
- Long ranges produce verbose output; combine with
--no-patchfor overview.
Once range-diff is in your toolkit, reviewing iterative PRs becomes radically faster. Instead of re-reading the whole diff, you read just the delta.