diff
Compare files line by line and show differences
By CMD Script Team · 4 min read · Last updated
diff [OPTIONS] FILE1 FILE2Options
| Flag | Description |
|---|---|
-u | Produce unified diff output (compact context format used for patches) |
-r | Recursively compare corresponding files in two directories |
-c | Produce context diff output (older format, more verbose than unified) |
-q | Report only whether files differ, without showing the differences |
-i | Ignore case differences when comparing lines |
-w | Ignore all whitespace when comparing lines |
-N | Treat absent files as empty when diffing directories (with -r) |
Distribution compatibility
- Ubuntu
- Debian
- Fedora
- Arch
- macOS
What it does
diff compares two files (or, with -r, two directory trees) line by line and reports
the differences needed to turn the first into the second. Its output can be a raw,
terse listing of changed line ranges, or — far more commonly — a unified diff (-u)
showing a few lines of surrounding context with +/- markers. Unified diffs are the
standard input format for patch and the format git itself uses when showing changes.
Beginner examples
diff file1.txt file2.txt— show differences in default (terse) formatdiff -u file1.txt file2.txt— show differences in unified (patch-style) formatdiff -q file1.txt file2.txt— just report whether the files differ, no detailsdiff -i file1.txt file2.txt— compare while ignoring case
diff -u server.conf.bak server.conf
Advanced examples
- Compare two entire directory trees recursively:
diff -r site-old/ site-new/ - Generate a patch file that
patchcan later apply:diff -u orig.c fixed.c > fixed.patch - Ignore whitespace-only changes when reviewing a reformatted file:
diff -w before.py after.py - Compare directories while treating missing files as empty (helps see additions cleanly):
diff -rN dir1/ dir2/ - Show only which files differ across two directory trees without full detail:
diff -rq build-old/ build-new/
diff -u <(sort file1.txt) <(sort file2.txt)
Common mistakes
- Reading raw (non-unified)
diffoutput and finding it cryptic — thea/c/dnotation is much harder to parse than unified format; use-ualmost always. - Comparing files that are logically the same but formatted differently (line endings,
trailing whitespace) and getting a huge, noisy diff — use
-wor-bto filter that out. - Forgetting
-rwhen trying to diff two directories, which causesdiffto only report "Common subdirectories" without descending into them. - Assuming
diffoutput order tells you what changed "from" and "to" — always double check which file was passed first vs. second, since that determines the direction of+/-.
Tips
- Use process substitution to diff the sorted or filtered output of two commands without
writing temp files:
diff <(sort a.txt) <(sort b.txt). diff -yshows a side-by-side comparison, which can be easier to read for short files than inline unified output.- When you only care about whether two files are byte-identical (not what changed),
cmp -sis faster thandiff -qfor that specific check.
Best practices
- Always generate patches with
-u(unified format) — it's smaller, more readable, and the formatpatch/git applyexpect by default. - When diffing config files before a deploy, combine
-uwith-wto filter noise from whitespace-only reformatting and focus on substantive changes. - For directory comparisons in CI or release checks, use
diff -rqfirst to get a quick list of changed files before drilling into individual diffs with-u.
Try it yourself
A simulated shell with a sample home directory — experiment freely, nothing leaves your browser. Type help to list supported commands.
Real-world use cases
- Reviewing what changed in a config file before restarting a service:
diff -u nginx.conf.bak nginx.conf. - Producing a patch to share a fix with a team that doesn't use the same version control
system:
diff -u broken.py fixed.py > fix.patch. - Verifying a deployment matches source by diffing an extracted release directory against
the repository:
diff -rq repo/dist/ /var/www/app/.
Common interview questions
- Why is unified diff format (
-u) preferred over the default format? It shows surrounding context with clear+/-line markers, is far more readable, and is the format expected bypatchandgit apply. - How do you compare two directories recursively?
diff -r dir1/ dir2/— it descends into subdirectories and compares files with matching names on both sides. - What's the difference between
diffandcmp?diffshows a line-by-line textual comparison suited to text files;cmpdoes a byte-by-byte comparison and reports the first differing byte, making it more suitable for binary files or a fast identical/ not-identical check.
Frequently Asked Questions
What's the difference between diff -u and plain diff output?
Plain diff output uses terse ed-style markers (a, c, d) with minimal context. Unified format (-u) shows a few lines of surrounding context with +/- prefixes and is the standard format understood by patch and git, so -u is almost always preferred today.
How do I compare two entire directories?
Use diff -r dir1/ dir2/ to recursively compare every file with a matching name in both directories, reporting which files differ and which exist only on one side.
How do I turn a diff into a patch file, and apply it?
Generate one with diff -u original.txt modified.txt > change.patch, then apply it elsewhere with patch < change.patch (or git apply change.patch if it's in git diff format).
How do I ignore whitespace-only changes when comparing files?
Use diff -w file1 file2, which ignores all whitespace differences, or -b to ignore changes in the amount of whitespace only.
Cheat sheet
Download a quick-reference cheat sheet for diff.