Git Diff: Comparing Repository States
Use git diff to inspect differences between the working tree, index, and committed snapshots without confusing observation with mutation.
Basic
What `git diff` actually compares
`git diff` is a comparison command. Its meaning depends on which two states you ask Git to compare. The plain form compares the working tree with the index; `--cached` compares the index with a commit, normally `HEAD`. Neither form creates a commit or changes the working tree or index.
git diff
git diff --cachedQuick check
After editing a tracked file without staging it, which comparison does plain `git diff` show?
printf "second
" > README.md
git diffgit diff
Quick check
What does `git diff --cached` compare in an ordinary committed repository?
git add README.md
git diff --cachedgit diff --cached
One file can be in two different comparisons
A file can have a staged change and then receive another unstaged edit. In that state, plain `git diff` shows only the later working-tree change, while `git diff --cached` shows the staged version relative to `HEAD`. This is why the two commands can show different hunks for the same pathname.
printf "staged
" > README.md
git add README.md
printf "staged plus unstaged
" > README.md
git diff
git diff --cachedQuick check
If a change is staged and then the file is edited again, what does plain `git diff` show?
git add README.md
printf "later
" >> README.md
git diffgit diff
Quick check
Which command inspects what is currently staged for the next commit?
git add README.md
git diff --cachedgit diff --cached
Compare a commit with the working tree
Supplying a commit changes the comparison. `git diff HEAD` compares the working tree and index together against `HEAD`, so it answers a different question from either plain `git diff` or `git diff --cached`. This is useful when you want the total local difference from the last commit.
git diff HEADQuick check
What does `git diff HEAD` show in the normal single-branch workflow?
git diff HEADgit diff HEAD
Compare two commits without changing either one
`git diff <commit1> <commit2>` compares the trees associated with two commits. It does not compare your current index or working tree unless one of the supplied sides explicitly refers to such a state. This makes it suitable for asking exactly how two committed snapshots differ.
git diff HEAD~1 HEADQuick check
What does `git diff HEAD~1 HEAD` compare?
git diff HEAD~1 HEADgit diff HEAD~1 HEAD
Use paths to narrow the comparison
A `--` followed by pathspecs limits the comparison to selected paths. This is useful when a repository has several simultaneous changes but you need evidence about one file or directory. The path restriction changes what is reported, not the underlying state being compared.
git diff -- README.md
git diff --cached -- README.mdQuick check
Why is `-- README.md` useful in a diff command?
git diff -- README.mdgit diff -- README.md
Read changes as patch text
The normal human-readable output from `git diff` is patch text. Lines beginning with `-` represent content from the old side and lines beginning with `+` represent content from the new side; context lines show unchanged surrounding content. The patch describes a difference; it is not itself a repository mutation.
git diff --patchQuick check
What do `+` and `-` lines normally communicate in a patch hunk?
git diff --patchgit diff --patch
Names and machine-readable inspection
When the content of the patch is not needed, options such as `--name-status` can summarize changed paths and their change status. This is particularly useful for scripts or quick state inspection. It still reports a comparison; it does not stage, commit, or otherwise mutate the repository.
`git diff` compares tracked content. An untracked file does not appear in an ordinary `git diff` or `git diff --name-status` result merely because it exists on disk; use repository-state inspection such as `git status` when you need to account for untracked paths.
git diff --name-status
git diff --cached --name-statusQuick check
What is `--name-status` useful for?
git diff --name-statusgit diff --name-status
Practice what you learned
Use the dedicated Git code-completion exercise for this lesson.
Official-source boundary
This lesson is grounded only in the official Git project documentation for `git diff` and its documented comparison model. The current official documentation baseline is Git 2.56.0, and the `git diff` manual records no changes from Git 2.47.1 through 2.47.3. The local verification executable is Git 2.47.3. The lesson therefore distinguishes documented behavior from locally executed evidence and does not present newer-version behavior as if it were locally verified.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.