Topic 1.5
Comparing Changes: git diff in Depth
In one line
git diff answers 'what's different between these two things?'. With no arguments it compares your files with the staging area. --staged compares staged changes with the last commit. git diff A B compares two commits or branches, and A...B (three dots) shows only what B changed since it split from A, which is what a pull request shows. Flags like --stat, --name-only, --word-diff, and -w change how the answer is shown.
Think of it like this
Spot-the-difference puzzles. The puzzle is only useful once you know *which two pictures* you're comparing. git diff is the same: the important part is picking the two sides.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Diff
- A description of the differences between two versions of files: which lines were removed and added.
- Hunk
- One block of changes in a diff, starting with an
@@ … @@header. - Context lines
- Unchanged lines shown around a change so you can see where it is.
- Two-dot (A..B)
- In git diff, comparing the tip of A with the tip of B directly.
- Three-dot (A...B)
- In git diff, comparing the merge base of A and B with B: only B's own changes.
- Merge base
- The latest commit both branches share, where they split.
Step by step
01Three diffs for the three trees
Remember the three trees (Topic 0.2). Each plain diff compares two of them. Priya edits cart.js, stages part of it, then keeps editing, so each diff shows something different.
02Reading a hunk
Here is the staged change. The header says the hunk starts at line 18 in both versions, covering 6 old lines and 7 new ones. One line was replaced and one added.
03Two dots vs three dots
Arjun wants to review Priya's branch. Since she branched, main gained the packaging charge. A two-dot diff compares the tips, so the packaging code appears as *removed*, which is confusing. A three-dot diff starts from where she branched and shows only her work.
04Other handy comparisons
Diff works on any two commits, limited to any paths. Long single-line changes (JSON, Markdown) are easier to read word by word.
Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
"git diff shows nothing, but I changed files!"
Arjun runs git add ., then git diff to review before committing.
Myth vs fact
Myth
git diff main feature shows what the feature branch changed.
Fact
It compares the two tips, mixing in everything main changed too. Use main...feature for the branch's own changes.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
git diff --checkwarns about trailing whitespace and leftover conflict markers, andgit diff --color-movedhighlights moved blocks in a different colour, so refactors that move code around are much easier to review.
Remember this
- 1
git diff= working directory vs staging area: changes you haven't staged yet. If everything is staged, it shows nothing, which surprises beginners. - 2
git diff --staged(same as--cached) = staging area vs last commit: exactly whatgit commitwould record. Read this before every commit. - 3
git diff HEAD= working directory vs last commit: all your uncommitted changes, staged or not. - 4
git diff main feature(ormain..feature) compares the two tips directly, so changes made on main since the branch started show up as if the feature removed them.git diff main...feature(three dots) compares from the merge base, showing only the feature's own changes, like a pull request. - 5
Reading the output:
---/+++name the old and new file,@@ -12,7 +12,9 @@means 'old file from line 12, 7 lines, new file from line 12, 9 lines', lines starting-were removed and+added. Unmarked lines are context. - 6
Useful flags:
--stat(a summary per file),--name-only,--word-diff(changes inside long lines, good for prose and config),-w(ignore whitespace), and-- pathto limit to some files.git difftoolopens the diff in a visual tool.
Explain it without notes
What do git diff, git diff --staged, and git diff HEAD each compare?
Why do pull requests use a three-dot comparison?
Practice
Stage half of a change, then show unstaged, staged, and total changes.
Compare a branch with main using two dots and three dots and explain the difference.
Trade-offs
- ↔
Command-line diffs are fast and scriptable. Visual diff tools (
git difftool, editor views) are easier for large or moved changes. Use both.
Done when you can
I know which trees each plain diff compares.
I can read hunk headers.
I use three dots to review branches.