How to read a diff
A diff lists the edits that turn one text into another. Once you know the four symbols, every diff and patch file reads the same way.
The idea
A diff doesn't store two versions of a file. It stores the edits that turn the original into the changed version: which lines were removed, which were added, and a little surrounding context so the edits can be located. Diff tools compute the shortest sensible set of edits, usually line by line.
Unified diff format
This is the format produced by git diff and diff -u, and the format of .patch files:
--- a/pricing.py
+++ b/pricing.py
@@ -1,5 +1,5 @@
def total(items, tax_rate=0.08):
subtotal = 0
for item in items:
- subtotal += item["price"] * item["qty"]
+ subtotal += item["price"] * item["quantity"]
return round(subtotal * (1 + tax_rate), 2)
---and+++name the original and changed files. Git prefixes them witha/andb/.@@ -1,5 +1,5 @@is a hunk header: this block covers 5 lines starting at line 1 in the original, and 5 lines starting at line 1 in the changed file. When lines are added or removed, the two counts differ.- Lines starting with a space are context: unchanged, shown to locate the change. Three lines of context on each side is the default.
- Lines starting with
-were removed; lines starting with+were added. A modified line appears as a removal followed by an addition.
Some tools add text after the second @@, such as the name of the function the hunk is in. That's only a hint for readers.
Side-by-side view
Side-by-side puts the original on the left and the changed version on the right, aligning unchanged lines. Removed lines appear only on the left (usually red), added lines only on the right (green), and modified lines on both sides with the changed words highlighted. It's easier to read than unified format for code you're reviewing, because each version stays intact.
Word-level and character-level highlights
A line-based diff only says that a line changed. Good diff viewers run a second, finer comparison inside each changed line to highlight the exact words or characters, so changing qty to quantity lights up one word instead of the whole line. In prose, word-level is usually clearest; for code and data, character-level catches single-character edits like 0.08 → 0.09.
Moved lines
Classic diff formats have no notion of a move: a function moved to the end of a file shows up as a block removed in one place and the same block added in another. Diffspot detects these and marks them as moved, so you can tell a reorganization from a rewrite.
Why a diff can look wrong
- Whitespace. Reindenting a block or changing tabs to spaces changes every line. Ignore whitespace to see only the real edits.
- Line endings. A file saved with Windows line endings (CRLF) differs from the same file with Unix endings (LF) on every line in some tools. Diffspot treats them as equal.
- Alignment. When many similar lines exist (closing braces, blank lines), different algorithms pair them differently. The histogram and patience algorithms anchor on distinctive lines and usually match human intuition better than the classic Myers algorithm.
Applying a patch
A unified diff can be applied to the original file to produce the changed one: git apply changes.patch in a Git repository, or patch -p1 < changes.patch elsewhere. In Diffspot, choose Export → Download .patch to get a patch from any comparison.