git diff answers a simple question—what changed?—but the correct command depends on which two states you want to compare. This cheat sheet starts with the commands used most often, then covers output options that make a diff easier to review or share.

The mental model

Keep these three states in mind:

  • working tree: files currently on disk
  • index: changes staged by git add
  • HEAD: the commit currently checked out

Plain git diff compares the working tree with the index. It does not show staged changes.

Everyday Git diff commands

Show unstaged changes

git diff

Compares the working tree with the index.

Show staged changes

git diff --cached

git diff --staged is an equivalent spelling.

Show all uncommitted changes

git diff HEAD

Compares the working tree, including staged and unstaged changes, with HEAD.

Show the latest commit

git diff HEAD~1 HEAD

For a commit-centric view with its message and metadata, git show HEAD is often more convenient.

Compare two commits

git diff <older-commit> <newer-commit>

Example:

git diff a1b2c3d e4f5a6b

Compare two branches directly

git diff main feature

This compares the tips of the two branches. Changes that landed on main after the branch split can appear in the output.

Review what a branch introduced

git diff main...feature

The three-dot form compares the merge base of the branches with feature. This is usually the most useful command for reviewing the work introduced on a feature branch.

Limit the diff

One file

git diff -- src/server.ts

The -- separates revisions and options from paths, which prevents ambiguous filenames from being interpreted as revision names.

One directory

git diff main...HEAD -- apps/web/

Multiple paths

git diff -- package.json pnpm-lock.yaml

Exclude generated files

git diff -- . ':(exclude)dist/**' ':(exclude)*.snap'

Quote pathspecs so the shell does not expand them before Git sees them.

Make the output easier to read

Show a compact summary

git diff --stat

Show only changed filenames

git diff --name-only

Show the change status

git diff --name-status

The leading letter identifies added, modified, deleted, renamed, copied, and other change types.

Highlight changed words

git diff --word-diff

For terminal-friendly color without inline markers:

git diff --color-words

Ignore whitespace-only changes

git diff -w

Use this carefully. Ignoring whitespace can hide meaningful changes in indentation-sensitive languages.

Detect renames and copies

git diff -M -C

-M enables rename detection and -C enables copy detection. Git often detects renames automatically, but explicit flags are useful when tuning a review.

Create an applyable patch that includes binary changes

git diff --binary main...HEAD > feature-review.patch

Ordinary diff output only reports that binary files differ. --binary includes Git’s binary patch data so git apply can reproduce the change. The binary portion is for transport, not human review.

Use a different diff algorithm

git diff --histogram

Histogram often produces clearer hunks for code with repeated lines. Other options include --patience, --minimal, and --diff-algorithm=myers.

Inspect whether a specific change happened

Find commits where a string’s count changed

git log -S'functionName' -p

This is the “pickaxe” search: it finds commits that add or remove occurrences of the string.

Find commits whose patch matches a regex

git log -G'functionName\(' -p

-G searches the added and removed lines themselves.

Check a diff without printing it

git diff --quiet
echo $?

Exit code 0 means no differences; 1 means differences exist. This is useful in shell scripts and CI.

Check for whitespace errors

git diff --check

Run this before committing or sending a patch.

Save and share a diff

Save a branch review as a file

git diff main...HEAD > feature-review.diff

Create an email-style patch with commit metadata

git format-patch -1 HEAD

For a series in one mailbox file:

git format-patch --stdout -3 HEAD > feature-series.mbox

Use git diff when you need the state difference. Use git format-patch when commit messages, authors, and series order are part of what you are sharing.

Apply a plain diff

Check first:

git apply --check feature-review.diff

Then apply:

git apply feature-review.diff

Apply a format-patch email

git am 0001-example.patch

git am creates commits from the email metadata; git apply only changes files.

Review the file before sharing

A .diff or .patch is plain text. Open it locally, use your IDE’s diff viewer, or load it into a browser-based viewer such as SharePatch when the code is allowed to leave your machine.

A Git diff rendered line by line in SharePatch

SharePatch accepts pasted unified diffs, uploaded files, and raw URLs, then provides file navigation and side-by-side or line-by-line views. The resulting link is unlisted, not access-controlled, so never upload credentials or confidential code.

For a comparison of repository reviews, attached patch files, Gists, browser viewers, and local tools, read how to share a Git diff.

Copy-and-keep summary

GoalCommand
Unstaged changesgit diff
Staged changesgit diff --cached
All uncommitted changesgit diff HEAD
Latest commitgit diff HEAD~1 HEAD
Branch work since divergencegit diff main...HEAD
One pathgit diff -- path/to/file
File summarygit diff --stat
Filenames onlygit diff --name-only
Ignore whitespacegit diff -w
Whitespace errorsgit diff --check
Save to filegit diff main...HEAD > review.diff