The diff command in Linux
diff compares files line by line and prints the differences — in unified format (-u), the +/− notation that git made universal. It answers "what changed between these configs?", verifies that two directories match, and its output is literally the patch format: what diff prints, patch can apply.
How diff works
diff runs the Myers algorithm: it finds a shortest edit script — the minimum insertions and deletions transforming file A into file B — by exploring an edit graph. The hunks it prints (@@ -12,5 +12,6 @@) are that script with context, and "minimum" is why diffs read like intent rather than noise.
Unified format is an interchange standard, and its context lines are functional: patch locates each hunk by matching context, not just line numbers, so patches survive small drifts in the target file — with detected offsets and "fuzz" — or fail loudly instead of applying in the wrong place. What diff emits, patch applies, and that whole ecosystem is what git generalized.
Syntax
diff [OPTIONS] FILE1 FILE2 Common options
| Option | What it does |
|---|---|
-u | Unified format with context — the readable standard. |
-r | Recurse into directories. |
-q | Just say WHETHER files differ. |
-w / -B | Ignore whitespace / blank-line changes. |
--color | Colorized output. |
-y | Side-by-side view. |
How to use diff: examples
$ diff -u nginx.conf nginx.conf.bak What did I change? Lines with − are the first file's, + the second's.
$ diff -rq site-v1/ site-v2/ Which files differ between two trees — names only.
$ diff <(ss -tlnp) <(ssh server ss -tlnp) Process substitution: compare command outputs from two machines without temp files.
$ diff -u old.py new.py > fix.patch Produce a patch someone else can apply with patch -p0 < fix.patch.
Real-world use cases for diff
Change review before restart
Edited nginx.conf: diff -u nginx.conf.bak nginx.conf shows exactly what you changed — reviewed in ten seconds before the reload that could drop traffic. The backup-then-diff ritual is config hygiene in two commands.
Drift detection between environments
Staging works, production doesn't: diff -r --exclude=logs staging-conf/ prod-conf/ lists every divergent file. Environment drift, the eternal suspect, confirmed or acquitted in one command.
Pro tips and common mistakes
- Read hunks by their signs: − is the first file, + the second; put "old" first and diffs read as "what changed to become new".
- diff <(cmd1) <(cmd2) compares command outputs directly — process substitution, no temp files.
- Exit code 1 just means "different", not error — script accordingly (if diff -q …).
Frequently asked questions about diff
How do I read unified diff?
@@ -12,5 +12,6 @@ locates the hunk (old line 12, 5 lines; new line 12, 6 lines). − lines removed, + added, unmarked context.
Exit codes?
0 identical, 1 different, 2 error — which makes diff -q perfect inside if statements.
Word-level or side-by-side?
diff -y for columns; git diff --word-diff --no-index a b borrows git's engine for any two files.
Related commands
Print file contents, number lines, and join multiple files together.
grepFind lines matching a pattern in files or piped input — the workhorse of text search.
findLocate files anywhere in a directory tree by name, type, size, date — and act on them.