Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Git Diff: Comparing Repository States

Use git diff to inspect differences between the working tree, index, and committed snapshots without confusing observation with mutation.

Levels: Beginner ~25 min read

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.

bash
git diff
git diff --cached

Quick 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.

bash
printf "staged
" > README.md
git add README.md
printf "staged plus unstaged
" > README.md
git diff
git diff --cached

Quick 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.

bash
git diff HEAD

Quick 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.

bash
git diff HEAD~1 HEAD

Quick 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.

bash
git diff -- README.md
git diff --cached -- README.md

Quick 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.

bash
git diff --patch

Quick 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.

bash
git diff --name-status
git diff --cached --name-status

Quick 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.

Was this page helpful?

Mark this learning resource complete to track your learning progress.