Guide

git diff, explained

One command, four comparisons: working tree, index, branches and commits. This guide covers what git diff compares by default, the variants you'll use daily, and how to make the output readable when it's prose or data instead of code.

By Kris ยท Updated September 2026

What plain git diff compares

Plain git diff compares your working tree against the index: it shows edits you have not staged yet. Once you git add something, it leaves this view. The other two everyday forms: git diff --staged shows what is staged against the last commit (what would be committed right now), and git diff HEAD shows both at once, everything uncommitted.

# unstaged edits (working tree vs index)
$ git diff
 
# staged edits (index vs HEAD), --cached is the same thing
$ git diff --staged
 
# everything uncommitted (working tree vs HEAD)
$ git diff HEAD

How to diff staged changes

git diff --staged shows exactly what your next commit will contain: the index compared with HEAD. --cached is an older name for the same option. If plain git diff prints nothing after git add, this is the diff you're looking for.

# everything staged, line by line
$ git diff --staged
 
# only the names of the staged files
$ git diff --staged --name-only
 
# one staged file
$ git diff --staged -- src/app.ts

Diff between two branches

Name the two branches and git compares their tips. Add a path to narrow it to one file. The three-dot form answers a different question: not "how do these branches differ" but "what did this branch change since it split off", which is what a pull request will contain.

# everything that differs between the two tips
$ git diff main feature
 
# one file, between the same two branches
$ git diff main feature -- src/app.ts
 
# what the feature branch changed since it left main
$ git diff main...feature

Diff between two commits

# any two commits, oldest first reads naturally
$ git diff 4d17e0b 8f2a91c
 
# the last commit's changes
$ git diff HEAD~1 HEAD
 
# same thing with the message included
$ git show HEAD
 
# one commit's change to one file
$ git diff HEAD~1 HEAD -- README.md

Single files and arbitrary files

# limit any diff to one path
$ git diff -- src/app.ts
 
# two arbitrary files, even outside a repo
$ git diff --no-index old.csv new.csv

How to see what's in a stash

git stash show on its own prints only a file summary. Add -p to see the full diff of a stash against the commit it was made on.

# what's inside the latest stash, without applying it
$ git stash show -p
 
# an older stash by index
$ git stash show -p stash@{2}
 
# include untracked files the stash saved with -u
$ git stash show -p -u
 
# the stash compared with your working tree instead
$ git diff stash@{0}

git stash show -p is worth memorising: it lets you check what a stash contains before deciding whether to apply it, instead of applying it to find out.

The flags worth knowing

FlagWhat it does
--statSummary per file: how many lines added and removed
--name-onlyJust the changed file names
--word-diffMark changed words instead of whole lines; the terminal's best answer for prose
-wIgnore whitespace changes
--stagedCompare the index against HEAD instead of the working tree against the index
--no-indexCompare two files that aren't in a repository

Cheat sheet

TaskCommand
Unstaged editsgit diff
Staged editsgit diff --staged
Everything uncommittedgit diff HEAD
Two branches, tip to tipgit diff main feature
What a branch changed since it splitgit diff main...feature
Two commitsgit diff 4d17e0b 8f2a91c
The last commit, with its messagegit show HEAD
One file onlygit diff -- src/app.ts
Two files outside a repogit diff --no-index a b
Inside a stash, without applyinggit stash show -p

Download as PDF

When the diff is prose or data, not code

Everything above prints line diffs, and line diffs were built for code. A reworded paragraph, an edited CSV or a changed image comes out as noise or "Binary file". --word-diff helps with prose; for the rest, the terminal has no answer.

Read the change, not the diff

Meridian is a native Git client for the Mac. It opens from the terminal in under a second, renders Markdown, images and data as themselves, then lets you stage and commit.

Free 14-day trial | One licence, three Macs

Related: Git worktrees, explained | Best Git client for Mac | Meridian, a native Git client for the Mac

Kris is the founder of Meridian and spends most days in the workflow these guides cover: worktrees, diffs, and reading what the agents wrote.

git diff, answered

How do I exit git diff?

Press q. git pipes diffs through a pager (usually less), and q quits it. To print without the pager, use git --no-pager diff.

How do I see staged changes in git diff?

Run git diff --staged (or its older name, git diff --cached). Plain git diff shows only unstaged edits, so it goes quiet after git add.

How do I see the diff of my last commit?

git diff HEAD~1 HEAD, or the shorter git show HEAD, which prints the last commit's message and its diff together.

Why are untracked files missing from git diff?

git diff only compares tracked content. Mark a new file with git add -N file (intent to add) and it appears in the diff as all-new content, or compare it directly with git diff --no-index /dev/null file.

What is the difference between two dots and three dots?

git diff main..feature is the same as git diff main feature: it compares the two tips. git diff main...feature compares feature against the common ancestor, showing only what the feature branch changed. For "what will my PR contain", three dots is usually what you mean.