Git diff algorithms compared: myers, minimal, patience, histogram

4 min read

Ever looked at a git diff and asked, “why did it pair those lines?” Git supports four different diff algorithms, and the choice trades off “minimum edit distance” against “humans understand it.” This article walks through each, with examples of where they diverge and guidance on which to enable globally.

The four algorithms

git diff --diff-algorithm=myers     # default
git diff --diff-algorithm=minimal
git diff --diff-algorithm=patience
git diff --diff-algorithm=histogram
AlgorithmOutput styleSpeedBest for
myersgreedy first matchfastgeneral-purpose, default
minimaltrue minimum edit distanceslow (O(ND²)-ish)short, exact diffs
patienceblock diff anchored on unique linesmediumfunction reordering
histogramoptimized patiencefastlarge diffs, recommended

myers: the default

Eugene Myers’ 1986 algorithm — dynamic programming, greedily minimizes the sum of additions and deletions.

  • Oldest and simplest implementation.
  • Usually produces an “obvious” diff.
  • Misaligns when there are multiple similar lines.

Example:

- void func_a() {
- }
- void func_b() {
- }
+ void func_c() {
+ }
+ void func_a() {
+ }
+ void func_b() {
+ }

The actual edit was “insert func_c at the top, leave the rest alone.” But Myers does line-by-line matching greedily and ends up showing everything as changed.

minimal: true minimum edit distance

Drops the greedy heuristic and finds the provably minimum number of additions/deletions. Higher complexity.

git diff --diff-algorithm=minimal

Useful for short pieces of code where exactness matters. Too slow for large repos in everyday use.

patience: function-reordering aware

Bram Cohen (BitTorrent) invented Patience Diff.

Algorithm:

  1. Find lines that occur exactly once on each side (unique lines).
  2. Use them as anchors, pairing the matching ones across the two sides.
  3. Recursively diff the regions between anchors.

“Unique lines” in code are usually function-definition lines, non-blank separators, import statements — natural anchor points.

In the function-reorder example:

func_c definition line: present once on the right, absent on left → not anchor
func_a definition line: present once each side → anchor
func_b definition line: present once each side → anchor

Anchored on func_a and func_b, only func_c’s definition shows up as a true addition.

Weaknesses:

  • Files where most lines are duplicates (config repetition) gain nothing — falls back to ordinary diff.
  • Slightly higher computational cost than myers in some cases.

histogram: faster patience

Same idea as patience but uses a frequency histogram to find unique-line anchors quickly. Implemented as xdiff/xhistogram.c in Git.

git diff --diff-algorithm=histogram

Git’s documentation describes histogram as ”producing more readable diffs for large diffs, function moves, and refactors than myers.” In practice it’s faster than patience, comparable to myers on speed, and produces more human-friendly output.

Which to use

Per-invocation

# function moves and large refactors
git diff --diff-algorithm=histogram HEAD~5 HEAD

# strict short comparison
git diff --diff-algorithm=minimal a.txt b.txt

Persistent setting

# project-wide
git config diff.algorithm histogram

# globally
git config --global diff.algorithm histogram

Applies to git log -p, git show, git rebase --interactive, etc.

Example: function reorder

Concrete case where myers and histogram diverge. Reordering helperA and helperB:

Before:

function helperA() {
	return 1;
}

function helperB() {
	return 2;
}

function main() {
	helperA();
}

After:

function helperB() {
	return 2;
}

function helperA() {
	return 1;
}

function main() {
	helperA();
}

Typical myers output:

- function helperA() {
-     return 1;
- }
-
  function helperB() {
      return 2;
  }
+
+ function helperA() {
+     return 1;
+ }

  function main() {
      helperA();
  }

Histogram output:

+ function helperB() {
+     return 2;
+ }
+
  function helperA() {
      return 1;
  }
-
- function helperB() {
-     return 2;
- }

  function main() {
      helperA();
  }

Both correctly describe the change, but histogram’s output more closely matches the mental model “helperB moved up.”

Adjacent: --word-diff and --color-moved

Not algorithms per se, but useful companions:

--word-diff

git diff --word-diff

Shows differences at word granularity rather than line. Better for prose (CHANGELOG, README, Markdown).

--color-moved

git diff --color-moved=zebra

Lines that moved without changing are colored differently (blue) from true additions (green) and deletions (red). Excellent for refactor review.

--color-moved is independent of the algorithm choice. The combination histogram + --color-moved=zebra produces highly readable output:

git diff --diff-algorithm=histogram --color-moved=zebra HEAD~5 HEAD

GitHub / GitLab behavior

The web UIs use their own diff configurations:

  • GitHub: myers-based internally (with some histogram for specific cases).
  • GitLab: histogram.

When the GitHub Files-changed view shows an “unintuitive” diff, running git diff --diff-algorithm=histogram locally often produces a more sensible view.

Summary

Git defaults to myers, but the histogram algorithm is consistently better at function reorders and refactors. Setting git config --global diff.algorithm histogram applies the change across git log -p, git show, git rebase, with no downside. Patience can be replaced by histogram; minimal is reserved for short, strict comparisons. That’s the 2026 best-practice mapping.

For comparing arbitrary text without a Git repository, the text diff tool covers the standard cases.