Diffing and Commit References
diff answers “what changed?” In Git, first distinguish three states: the working tree, staging area, and most recent commit.
Working-tree and staging-area differences
git diff
git diffPurpose: view working-tree modifications not yet staged.
Appropriate when:
- inspecting what you changed before
git add; - quickly confirming a local difference after code changes.
git diff --staged
git diff --stagedPurpose: view staged changes that will enter the next commit.
Equivalent common form:
git diff --cachedAppropriate when:
- reviewing commit content before
git commit; - confirming selections after
git add -p.
git diff HEAD
git diff HEADPurpose: view tracked-path differences from the most recent commit to the current working tree, including staged and unstaged content. Ordinary untracked files do not appear, so still inspect git status --short.
Appropriate when:
- you want a single overview of “everything in the current directory versus the last commit”;
- doing a total review before a commit.
Differences between commits
git show <commit>
git show HEAD~1Purpose: view a commit’s metadata and the difference it introduced relative to its parent.
Appropriate when:
- reviewing what a particular commit actually changed;
- understanding one commit’s concrete content before code review.
git diff <commit> <commit>
git diff main feature/demoPurpose: compare content differences between two commits.
Examples:
git diff main feature-branch
git diff HEAD~3 HEADOrder affects display direction. Usually read it as “change from the first commit to the second.”
git diff <commit> -- <file>
git diff HEAD~1 -- README.mdPurpose: view how one file changed from a specified commit to current state.
Appropriate when:
- you care about one file, not the entire repository;
- confirming how one configuration or document differs from an older version.
git diff <commit> --stat
git diff HEAD~1 --stat
git show HEAD~1 --statPurpose: view a difference summary instead of a complete patch.
Appropriate when:
- judging change scale quickly;
- summarizing touched files for handoff notes.
What <commit> can mean
When a command contains <commit>, several reference forms are available.
| Form | Meaning | Example |
|---|---|---|
| Branch name | Commit currently targeted by that branch | main |
| Tag name | A release or marked location | v0.1 |
| Commit ID | Hash prefix or complete hash for one commit | 3e887ab |
| Remote branch | Current remote-tracking branch target | origin/main |
HEAD | The currently checked-out commit | HEAD |
HEAD^ | Parent of the current commit | HEAD^ |
HEAD~3 | Three first-parent steps before the current commit | HEAD~3 |
Notes:
HEAD^^^andHEAD~3are common ways to trace three parent generations back.- A merge commit has multiple parents, so
^can take a number to choose a parent, such asHEAD^2. - Before using an unfamiliar reference, inspect a graph with
git log --oneline --graph --decorate. --clearly separates commit/options from paths and avoids ambiguity when a branch and file share a name.
Minimum self-check
- Which two layers do
git diff,git diff --staged, andgit diff HEADcompare? - Why preserve
--ingit diff HEAD~1 -- README.md? - Why can
HEAD^1andHEAD^2of a merge commit target different parents?