git diff
git diff shows what changed. Unstaged vs staged, ranges, --stat, --color-words, and the flags that turn it from useful to indispensable.
Git — git diff
EXAMPLE
# ===== Default =====
git diff # unstaged changes (working tree vs index)
git diff --staged # staged changes (index vs HEAD)
git diff HEAD # both staged + unstaged (working tree vs HEAD)
# ===== Against a branch / commit =====
git diff main # current branch vs main
git diff main..feature # range: between the two
git diff main...feature # 3-dot: feature vs the merge base with main
git diff <sha1> <sha2> # any two commits
# ===== Specific files =====
git diff -- src/handlers.ts
git diff main -- src/
# ===== Stat summary =====
git diff --stat HEAD~3
# src/a.ts | 8 ++++++--
# src/b.ts | 3 +++
# 2 files changed, 9 insertions(+), 2 deletions(-)
git diff --shortstat HEAD~3
git diff --numstat # machine-readable
# ===== Word-level diff =====
git diff --color-words # highlights differing WORDS, not whole lines
git diff --word-diff=plain # plain output
# ===== Whitespace =====
git diff -w # ignore all whitespace
git diff --ignore-space-change # collapse runs of whitespace
# ===== Binary + names only =====
git diff --name-only HEAD~3
git diff --name-status HEAD~3 # M, A, D, R prefixes
git diff --binary # include binary patches
# ===== After commit, between commits =====
git diff HEAD~1 HEAD # last commit's changes
git show HEAD # same idea, with commit message
# ===== Combined / merge diffs =====
git diff --cc HEAD # combined diff for merge commits
git log -p --first-parent main # patches on main's first-parent line
# ===== External diff tools =====
git config --global diff.tool vscode
git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'
git difftool HEAD~1
# ===== Common workflows =====
# Pre-commit review:
git diff --staged
# Pre-push review:
git diff @{u}..HEAD
# Inspect a colleague's PR locally:
git fetch origin pull/123/head:pr-123
git diff main..pr-123
# ===== Aliases worth having =====
git config --global alias.d 'diff --stat'
git config --global alias.dc 'diff --staged'
# ===== Patterns to internalise =====
# - git diff before every commit
# - git diff --staged immediately before 'git commit'
# - --color-words for prose / docs / configs
# - --stat for an at-a-glance change summary
# ===== Pitfalls =====
# - 'git diff' (no args) does NOT show staged changes; --staged for that
# - Diffs of generated files / minified code flood the output (add to .gitignore)
# - Comparing branches with .. vs ... silently changes meaning
# - Wrapped terminals; pipe through 'less -SR' for wide diffs
Why it matters
git diff is the lens. Default for unstaged, --staged for index, --stat for summary, --color-words for prose. Look before every commit, look before every push, and the surprises mostly disappear.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
git diff # unstaged changes git diff --staged # staged for commit git diff main..feature # branch comparisonTry it Yourself »
Discussion
Loading…