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.
Concepts behind diff: Exit code