Home / Alt manpages / git-range-diff(1)

  • git-range-diff(1)
  • User command
  • linux

Compare Rebases and Patch Series with git range-diff

You will finish with a repeatable way to compare an older and newer version of a Git patch series, spot reordered, added, removed and edited commits, and inspect the patch that changed. The examples use Git 2.43.0 from the installed git-man package.

Allow about fifteen minutes. You need a Git repository containing both versions of the series, or a remote-tracking branch and a reflog entry for the earlier version. The command only compares commits: it does not rebase, merge, reset or modify the repository. No elevated privileges are needed.

1. Check the installed command

Confirm the version and the command's spelling before copying a longer example:

$ git --version
git version 2.43.0
$ git range-diff -h

The command is git range-diff, with a space. Its normal input is two ranges. In the two-range form, the first range is treated as the older version and the second as the newer version.

Checkpoint

You should have the expected Git binary and a repository in which the revisions named in the next steps resolve.

2. Compare two versions of a branch

The most useful case is a topic branch that was rebased. The upstream branch is the current base, HEAD@{1} is the previous local position, and HEAD is the current position:

$ git range-diff @{u} @{1} HEAD

This three-revision form means "compare the commits after this base in revision one with the commits after the same base in revision two". The base does not have to be the exact branch point. It can be a common commit that makes both ranges meaningful.

For two explicitly named ranges, use the double-dot notation twice:

$ git range-diff OLD_BASE..old-topic NEW_BASE..new-topic

Replace every uppercase placeholder with a revision that exists in your repository. Check the names without changing anything:

$ git rev-parse --verify OLD_BASE
$ git rev-parse --verify old-topic
$ git rev-parse --verify NEW_BASE
$ git rev-parse --verify new-topic

A failed verification is a revision or spelling problem. Do not "fix" it by guessing a nearby branch. Find the intended base first.

3. Read the matching markers

Each output row places an old commit on the left and a new commit on the right. The marker between them tells you what Git found:

-:  -------- > 1:  0ddba11 Add a new check
1:  c0debee = 2:  cab005e Keep the parser change
2:  f00dbal ! 3:  decafe1 Tighten the error text
3:  bedead  < -------- -:  Remove the obsolete test
  • = means the corresponding patches match closely.
  • ! means both commits correspond, but their author information, message or patch differs. The following indented diff shows the difference between those patches.
  • > marks a commit present only in the second, newer range.
  • < marks a commit present only in the first, older range.

The rows are shown in the order of the second range. An unmatched commit is inserted after its ancestors have been shown. This is a comparison of patch identity, not a claim that commit object IDs should remain stable after a rebase.

When the output is a terminal, Git uses colour to distinguish additions, deletions, matches and changed patches. If a pager opens, read it with the usual pager controls, then press q to return to the shell.

4. Inspect an edited patch

For a ! row, look below the row for the diff of the two patches. The outer markers describe how the patch changed, while the inner diff shows the old and new patch content. This makes a reworded commit message or a small fix visible without comparing the entire branch manually.

To make copied output easier to read in a log or issue, disable terminal colour:

$ git range-diff --no-color OLD_BASE..old-topic NEW_BASE..new-topic

Use the option that disables dual colouring only when the nested colouring is getting in the way. By default, range-diff retains the original diff colours and adds outer red and green markers for the diff of diffs. In a plain text capture, the colour-disabled form shown above is usually the clearer choice.

5. Limit the comparison to a path

If a large series touches several areas, add -- followed by one or more paths:

$ git range-diff OLD_BASE..old-topic NEW_BASE..new-topic -- src/parser.c tests/parser

The ranges are then limited to those paths. This can make a review easier to focus, but it can also hide changes elsewhere in the commits. Run the unfiltered comparison before declaring two series equivalent.

6. Handle poor or surprising matches

Git pairs commits by comparing their author information, commit messages and patches. It solves a cost-based assignment across both ranges, so the visual position of a commit is not the matching rule. A large rewrite can therefore appear as a deletion plus an addition.

The default creation factor is 60 percent. If a substantial edit is reported as a complete rewrite, try a larger value:

$ git range-diff --creation-factor=80 OLD_BASE..old-topic NEW_BASE..new-topic

If unrelated commits are being paired, try a smaller value. Treat the result as review evidence, not an automated decision. Always open the relevant commits with git show before accepting a surprising match.

Large ranges can take noticeable time because Git compares many pairs of patches and solves an assignment problem. Narrow the ranges or compare a relevant path when investigating a focused change.

7. Keep the output out of scripts

Range-diff output is human-readable porcelain. Its layout and wording can change between Git versions, and it is not intended to be machine-readable. Do not parse its rows in a deployment check or use them as a stable interchange format. For automation, choose a command and format designed for that purpose, such as a suitable git log format, and test that interface against the Git versions you support.

Options such as --stat are accepted as regular diff options, but the installed manual warns that some combinations can produce output that is not useful in range-diff's context. Keep the default view for review unless you have checked the result for your particular repository.

Done means

  • You verified the installed Git version and the revisions used as range boundaries.
  • You compared an older range with a newer range in the correct order.
  • You can distinguish matching, changed, added and removed commits.
  • You inspected any surprising pairing with git show.
  • You used the colour-disabled form for plain text capture and kept range-diff output out of scripts.
  • No repository history or working-tree state was changed by the comparison.