diff — Compare two files or directories line-by-line and report the differences across all 5 shells
Equivalents in every shell
diff file1.txt file2.txtdiff file1.txt file2.txtdiff file1.txt file2.txtCompare-Object (Get-Content file1.txt) (Get-Content file2.txt)Emits diff *objects* (`InputObject` + `SideIndicator` `<=` / `=>`), not Unix unified-diff text. For patch-compatible output, install Git Bash / WSL diff.
fc file1.txt file2.txt`fc` (file compare) prints differing line ranges, not unified-diff hunks. Use `fc /n` to include line numbers and `fc /b` for binary mode.
Worked examples
Show a unified (patch-ready) diff between two files
diff -u file1.txt file2.txtdiff -u file1.txt file2.txtgit diff --no-index file1.txt file2.txtgit diff --no-index file1.txt file2.txtRecursively diff two directory trees
diff -r dir1/ dir2/Compare-Object (Get-ChildItem -Recurse dir1) (Get-ChildItem -Recurse dir2) -Property FullNamefc /l /n dir1\*.* dir2\*.*Ignore whitespace-only changes
diff -w file1.txt file2.txtCompare-Object (Get-Content file1.txt | %{$_.Trim()}) (Get-Content file2.txt | %{$_.Trim()})Gotchas
- `diff` exit code is 0 when files are identical, 1 when they differ, 2 on error. Scripts that use `set -e` will abort on a normal "files differ" result — wrap with `|| true` or test the exit code explicitly.
- `Compare-Object` is symmetric and emits objects, not text. The `<=` / `=>` SideIndicator shows which input the line belonged to; passing `-IncludeEqual` adds `==` lines.
- Windows `fc` and Unix `diff` produce incompatible output formats — `fc` output cannot be fed to `patch` or `git apply`. For patch-compatible diffs on Windows, use Git's bundled `diff.exe` or WSL.
- BSD `diff` (default on macOS pre-Sonoma) lacks `--color` and some GNU flags like `-y` (side-by-side) behave differently. Install GNU diffutils via Homebrew for parity.
- Recursive `diff -r` follows symlinks by default — pass `--no-dereference` to compare the symlinks themselves.
WSL & PowerShell Core notes
Common tasks using diff
- Clone a repo with shallow history
Clone only the last N commits — for CI runners, ephemeral builds, and tooling that doesn't need full git history.
- Compare two files line by line
Show the differences between two text files, line by line.
- Count files changed since a commit
Get the number of distinct files that differ between a reference commit (a tag, SHA, or `origin/main`) and the working tree — for CI gates and PR-size summaries.
- Find which commit introduced a bug
Use `git bisect` to binary-search the history between a known-good and known-bad commit, narrowing thousands of commits to the single guilty one in log₂(N) steps.
- List modified files in a git repo
Print the paths of files with uncommitted changes (staged or unstaged) — for pre-commit hooks, CI lint-only-changed gates, and "what am I about to commit".
- List staged changes
Print files (or the full diff) of what's currently in the git index — what `git commit` will commit if you run it now.
- Show diff between two git branches
Compare two branches' code — for code review, "what did this feature change?" inspection, or merge-conflict preview. The two-dot vs three-dot syntax distinction silently changes what the diff INCLUDES.
- Show git commit history as a graph
Render the commit DAG as an ASCII graph so branch topology — merges, forks, fast-forwards, and orphan tips — is visible at a glance, instead of the default linear `git log` that hides every parallel branch.
- Show the current git branch
Print the name of the branch HEAD points at — used in shell prompts, CI build labels, and "deploy what's on the branch" scripts.
- Use process substitution
Treat a command's output as a file argument to another command — e.g. `diff <(sort a) <(sort b)` — without manual tempfile management.