skip to content

What do Git's histogram and patience diff algorithms do that the default does not?

level: middleimportance: nice to knowfreq 28%

answer

  1. Shortest is not always clearest
  2. Ambiguity comes from repeated lines
  3. Anchor on lines appearing once
  4. Config key lives under diff.*
  5. Presentation changes, content does not

basics

~20 s

Both anchor the diff on lines that appear rarely, so hunks line up with meaningful code instead of sliding onto common lines like closing braces. Git's default is Myers; select others with git diff --histogram, --patience, or the diff.algorithm config key.

solid answer

~50 s

Git's default diff algorithm is Myers, which finds a shortest edit script. Shortest is not always clearest: when many identical lines exist — closing braces, blank lines, boilerplate — Myers may pair the wrong ones, producing a hunk that appears to move a `}` from one function into another. **Patience** builds its alignment from lines that occur exactly once on each side, using those unique lines as anchors and recursing between them, which keeps hunks attached to distinctive content. **Histogram** is a refinement of the same idea that also accounts for how often each line occurs and is generally faster. You select them per-command with `git diff --patience` or `--histogram`, or set a default with `git config diff.algorithm histogram`. `--minimal` is a different axis: it spends more time to find a genuinely smallest diff. The choice changes only how differences are grouped and shown, never which file contents you have.

go deeper

for a junior

You are unlikely to be asked this, but recognizing that Git has selectable diff algorithms and that --histogram often makes a confusing diff readable is a good sign of curiosity.

for a middle

Explain why several shortest edit scripts can exist, and how anchoring on rarely occurring lines removes the ambiguity that produces sliding brace hunks.

for a senior

Show that you know the choice is presentational, name the diff.algorithm config key and its values, and describe when you would configure it repository-wide versus per command.

for a principal

Weigh readability defaults as a team-wide setting: consistent diff rendering makes reviews and archaeology repeatable, but it is a preference layer, never a correctness control.

## The problem an algorithm solves A diff algorithm is given two sequences of lines and must decide which lines of the old correspond to which lines of the new. Many valid answers exist. "Delete everything, add everything" is always correct and always useless; the algorithm's job is to find a correspondence that is both small and *comprehensible*. ## Myers, the default Git's default is the Myers algorithm, which computes a shortest edit script — the minimum number of line insertions and deletions turning one side into the other. It is fast, well understood, and right most of the time. Its weakness is that "shortest" says nothing about "meaningful". When a file contains many identical lines, several shortest scripts exist and the one Myers picks may align lines that have nothing to do with each other. The canonical symptom, familiar from C-like or brace-heavy languages, is a diff of an added function that looks like this: the closing brace of the *previous* function is shown as deleted, the new function body is added, and a closing brace is added at the end. Functionally that is a correct minimal edit; to a human it is nonsense, because it attributes the change to the wrong function boundary. The same slippage produces diffs where a blank line or an `end`/`}` seems to migrate across a file. ## Patience The patience algorithm attacks the ambiguity directly. Its rule: consider only lines that appear **exactly once on each side**. Those unique lines are unambiguous — if `def compute_totals(rows):` occurs once in each version, it almost certainly corresponds to itself. Patience finds the longest increasing subsequence of such unique matches, pins them as anchors, and then recurses on the regions between anchors. The consequence is that hunks tend to line up with distinctive lines — function signatures, unusual literals, comments — rather than with structural noise. Diffs read as "this function changed" instead of "a brace moved and then some lines appeared". The tradeoff is that patience can produce a *longer* edit script than Myers: it is optimizing for legibility, not minimality. ## Histogram Histogram is a development of the patience idea. Instead of using only strictly unique lines, it builds a histogram of how often each line occurs and prefers low-occurrence lines as anchors, falling back sensibly when no rare line is available. In practice it yields output very similar in quality to patience while generally running faster, which is why many people configure it as their default. ## Minimal — a different axis `--minimal` is not a peer of patience and histogram. It tells Git to spend extra computation to guarantee the smallest possible diff, tightening Myers rather than replacing its notion of a good result. Use it when you specifically care that no spurious lines appear; do not expect it to fix brace-slippage, because the smallest diff is exactly what caused that problem. ## Selecting one - Per invocation: `git diff --histogram`, `git diff --patience`, `git diff --minimal`, or `git diff --diff-algorithm=histogram`. - Persistently: `git config diff.algorithm histogram`. Accepted values are `myers`, `minimal`, `patience` and `histogram`. - The options work on every command that renders a diff — `git show`, `git log -p`, and the staged and range forms of `git diff`. ## What does not change The algorithm affects **presentation**: how the differing regions are grouped into hunks and which lines are labelled as context. It does not change the file contents, does not change what is stored in the repository, and does not change the total set of differences between two trees. Two people with different `diff.algorithm` settings looking at the same commit see the same change described differently, not different changes. ## When it is worth the keystrokes Reach for `--histogram` or `--patience` when a diff is confusing rather than large: heavily nested code, files with long runs of similar lines, generated or tabular data, and refactors that move blocks around. If you regularly review such code, configuring histogram once is a small, permanent readability win. A related option worth knowing for moved code is `--color-moved`, which colours lines that were moved rather than genuinely added or deleted; it is orthogonal to the algorithm choice and often the clearer answer when a block was relocated wholesale.

  • What is the classic symptom that the default algorithm produced a confusing diff?
    A newly added function is shown as if the previous function's closing brace were deleted and a brace added at the end, so the change appears attached to the wrong function. It is a valid minimal edit script that pairs identical brace lines arbitrarily; --histogram or --patience usually re-anchors it correctly.
  • How is --minimal different from --patience?
    --minimal tightens the search for the smallest edit script, while patience deliberately accepts a possibly larger script in exchange for anchoring hunks on unique lines. They optimize for different goals: fewest changed lines versus most comprehensible grouping.
  • Does changing diff.algorithm change what Git stores or what two trees actually differ by?
    No. It affects only how the difference is segmented into hunks and rendered. The stored objects, the file contents, and the total set of differing regions are identical; two colleagues with different settings see the same change described differently.
  • What option helps when a block of code was moved rather than rewritten?
    --color-moved renders lines that moved in a distinct colour instead of showing them as an unrelated deletion plus addition, making a relocation obvious at a glance. It is independent of the diff algorithm and can be combined with --histogram.

saying these in an interview costs you the question

  • Thinks a different algorithm changes file contents
  • Believes patience always yields a smaller diff
  • Assumes Myers is wrong rather than ambiguous
  • Confuses --minimal with patience anchoring
  • Cannot name where the default is configured

context