iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

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 comparison
Try it Yourself »

Discussion

Loading…