Core answer: A diff shows the minimal line-level changes between two texts: − lines removed, + lines added, unchanged lines as context. Unified diff format (diff -u) with 3 lines of context is the standard; git calls it a "patch". Two files differing in one line show ~7 lines of output (hunk header + context + the change). Diffs work line-by-line, so reflowed paragraphs look fully rewritten — normalize formatting before diffing prose.

Reading a unified diff

@@ -3,7 +3,7 @@ means: from old file line 3, show 7 lines; new file line 3, 7 lines. Lines prefixed " " are context, "−" old-only, "+" new-only. One hunk per changed region; distant changes get separate hunks.

The algorithms under the hood

  • Myers algorithm (git default): finds the shortest edit script — minimal insertions/deletions. O(ND) time, which is why huge files diff slowly.
  • Histogram/patience (git options): better on code with repeated lines (braces); often produces more intuitive hunks.
  • Word/char diff: same algorithms on word or character tokens — what "git diff --word-diff" and online text-compare tools use.

Worked examples

Example 1 — Code review. A PR showing +127 −3 with 120 lines being an auto-formatter: ask to split format-only changes from logic changes, or review with "hide whitespace" (GitHub's w=1).

Example 2 — Config drift. Production nginx.conf vs repo version: diff reveals a manually added client_max_body_size 50m that never made it to git — the classic snowflake-server catch.

Example 3 — Contract comparison. Two versions of a contract, word-diffed: one changed "shall" to "may" — a single word worth millions; character-level diff catches what eyes skim past.

Example 4 — Merge conflicts. Conflict markers <<<<<<< / ======= / >>>>>>> show YOUR side vs THEIR side of the same lines; resolve by editing to the intended final state, then deleting all markers.

Common mistakes and myths

  1. Diffing minified/generated files — bundle.js diffs are noise; add generated files to .gitignore or mark them linguist-generated.
  2. Whitespace wars — mixed tabs/spaces or CRLF/LF make every line "changed"; standardize via .gitattributes + editorconfig before mass commits.
  3. Trusting line-diff for prose — one reflowed paragraph diffs as 100% changed; use word-diff for documents.
  4. Assuming diff = semantic — two programs with identical diffs can behave differently (moved code across scopes); diff shows text, not meaning.
  5. Binary blindness — diff can't show image/XLSX changes; use specialized tools (image diff overlays, spreadsheet comparators) or accept "files differ".