Skip to content

Inspecting Differences

git status tells you which paths have changed. A diff tells you what content changed. Inspect both before recording work so you know which lines are in the Index and which are still only in the Working Tree.

last commit (HEAD) → Index → Working Tree
git diff --staged │
git diff

The ordinary command compares the Index with the Working Tree:

Terminal window
git diff

It displays changes not yet put in the Index. Once you stage the current content of a file, this command becomes empty for that file unless you edit it again.

This command compares the last commit with the Index:

Terminal window
git diff --staged

It shows what the next commit would record from the Index, not later Working Tree edits. If there is no commit yet, Git compares the Index against an empty starting point. git diff --cached is an equivalent spelling for this comparison; --staged is often clearer to read.

All of these diff commands only read and report content. They do not stage, discard, or commit anything.

A diff groups nearby changes into a hunk:

@@ -1,5 +1,5 @@
<?php
-echo 11;
+echo 11999;
?>

The @@ header gives the old and new line ranges. A line beginning with - exists on the old side of this comparison; a line beginning with + exists on the new side. Lines beginning with a space are unchanged context. They make the change understandable; they are not added or removed.

For git diff, the new side is the Working Tree. For git diff --staged, the new side is the Index. A displayed line such as No newline at end of file reports a line-ending detail; it is not a Git error.

In a disposable PHP example, the last commit contained echo 11;. The Index contained echo 11999;. The Working Tree contained both echo 11999; and a later added echo 388;.

Without running git add between the two inspections:

Terminal window
git diff
git diff --staged

The first result showed echo 11999; as unchanged context and +echo 388; as the Working Tree addition. The second result showed -echo 11; and +echo 11999; as the difference between the last commit and the Index. If a commit were made in that state, the Index version would be recorded while echo 388; would remain outside it.

Do not run git add between two outputs intended to compare the same state. Staging changes the Index and therefore changes what each diff is comparing. In the first attempt of this exercise, an intervening git add . made both outputs look similar for different reasons; repeating the inspection without that command separated the three versions clearly.

To see only affected path names:

Terminal window
git diff --name-only
git diff --staged --name-only

To see a per-file change summary with insertion and deletion counts:

Terminal window
git diff --stat
git diff --staged --stat

The --staged option still chooses the comparison; --name-only or --stat only changes how that comparison is displayed. Use a full diff for review, not just a count: a small number of lines can still include an unintended secret or behavior change.

  • Do not use git add when you only want to inspect a diff; it changes the Index. Use git diff.
  • Do not assume an empty ordinary diff means there is nothing to commit. Staged changes may still appear under git diff --staged.
  • Do not read + as “staged” in every command. It means the new side of the particular comparison.
  • Do not treat context lines as changes just because they appear in a hunk.
  • Check both comparisons before a commit when a file may have been edited again after staging.
git diff → Index versus Working Tree
git diff --staged → last commit versus Index
git diff --cached → same as --staged
--name-only → changed path names only
--stat → per-file change summary
+ / - / leading space → new / old / unchanged context
Can the ordinary diff be empty while a staged diff is not?

Yes. The Working Tree may match the Index while the Index differs from the last commit.

What does a context line without + or - mean?

It is unchanged in the comparison and shown to give the surrounding context.

Why should you avoid staging between two diff commands in a comparison exercise?

Staging changes the Index, so the commands would inspect different repository states.