diff — File & Output Comparison
Comparison patterns — unified diff, side-by-side, process substitution for comparing command outputs, and preview-before-apply workflows.
Basic diff
Default output — ed-style change commands
diff file1.txt file2.txt
# Output format: line-range + action (a=add, d=delete, c=change)
# 3c3 means "line 3 in file1 changes to line 3 in file2"
Exit codes — useful in scripts
diff -q file1.txt file2.txt
# Exit 0: files are identical
# Exit 1: files differ
# Exit 2: trouble (file not found, etc.)
Brief mode — just report whether files differ, no details
diff -q file1.txt file2.txt
Unified Format — -u
Unified diff — the standard for patches and code review
diff -u original.conf modified.conf
Unified diff with more context lines — default is 3
diff -u -U10 original.conf modified.conf
Unified diff with labels — cleaner headers
diff -u --label "before" --label "after" original.conf modified.conf
Side-by-Side — -y
Side-by-side comparison — visual alignment
diff -y file1.txt file2.txt
Side-by-side with custom width — fit terminal
diff -y -W "$(tput cols)" file1.txt file2.txt
Side-by-side showing only differences — suppress common lines
diff -y --suppress-common-lines file1.txt file2.txt
Context Format — -c
Context diff — older format, shows surrounding lines with ! for changes
diff -c file1.txt file2.txt
Context diff with more surrounding lines
diff -c -C5 file1.txt file2.txt
Recursive — -r
Compare two directory trees recursively
diff -r dir1/ dir2/
Recursive unified diff — suitable for patch files
diff -ru dir1/ dir2/ > changes.patch
Recursive diff excluding certain files
diff -r --exclude='*.log' --exclude='.git' dir1/ dir2/
Recursive diff with brief output — just list differing files
diff -rq dir1/ dir2/
Process Substitution — diff Without Temp Files
Compare command outputs directly — no temp files needed
diff <(sort file1.txt) <(sort file2.txt)
Compare remote and local config
diff <(ssh server cat /etc/nginx/nginx.conf) /etc/nginx/nginx.conf
Compare before and after a command — verify a change
diff <(systemctl list-units --type=service --state=running) <(sleep 5; systemctl list-units --type=service --state=running)
Compare package lists between two systems
diff <(ssh host1 'pacman -Q | sort') <(ssh host2 'pacman -Q | sort')
Compare two git branches — file list difference
diff <(git ls-tree -r --name-only main | sort) <(git ls-tree -r --name-only feature | sort)
colordiff
Colorized diff — easier to read in terminal
colordiff -u file1.txt file2.txt
Use colordiff as a drop-in replacement if available
diff -u file1.txt file2.txt | colordiff
Fallback pattern — use colordiff if installed, else plain diff
if command -v colordiff &>/dev/null; then
colordiff -u file1.txt file2.txt
else
diff -u file1.txt file2.txt
fi
diff3 — Three-Way Merge
Three-way diff — compare file with two variants
diff3 mine.txt original.txt yours.txt
Merge three files — output merged result
diff3 -m mine.txt original.txt yours.txt > merged.txt
Creating and Applying Patches
Create a patch file from unified diff
diff -u original.conf modified.conf > fix.patch
Apply a patch — transforms original into modified
patch < fix.patch
Apply a patch with backup — keeps .orig files
patch -b < fix.patch
Dry run — check if patch applies cleanly without modifying
patch --dry-run < fix.patch
Reverse a patch — undo the change
patch -R < fix.patch
Create a recursive patch for a directory tree
diff -ruN original_dir/ modified_dir/ > project.patch
# -N treats absent files as empty — includes new files in the patch
git diff vs diff
git diff uses unified format with enhanced headers
git diff # Unstaged changes
git diff --staged # Staged changes
git diff HEAD~3..HEAD # Last 3 commits
git diff main..feature # Branch comparison
git diff with word-level highlighting — finer granularity than line diff
git diff --word-diff
git diff stat — summary of changes per file
git diff --stat main..feature
Use regular diff when git is not available or for non-repo files
# diff works on any two files — no repository needed
diff -u /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
Practical Patterns
Verify a config change — before/after pattern
cp /etc/ssh/sshd_config /tmp/sshd_config.before
# ... make changes ...
diff -u /tmp/sshd_config.before /etc/ssh/sshd_config
Compare two URLs' content
diff <(curl -s https://example.com/config.json | jq .) <(curl -s https://staging.example.com/config.json | jq .)
Ignore whitespace differences — focus on content changes
diff -u -w file1.txt file2.txt # Ignore all whitespace
diff -u -b file1.txt file2.txt # Ignore changes in whitespace amount
diff -u -B file1.txt file2.txt # Ignore blank lines
Ignore comments when comparing configs
diff <(grep -v '^#' original.conf | grep -v '^$') <(grep -v '^#' modified.conf | grep -v '^$')