Comparing Changes

git diff shows exactly which lines changed — between your working tree and the staging area, between the staging area and the last commit, or between any two commits or branches. Reading a diff before you commit is the easiest way to catch mistakes.

Unstaged changes

Sam changes the amount of milk and adds a line to the pancake recipe:

$
printf 'Pancakes\n\nIngredients:\n- 200 g flour\n- 250 ml milk\n- 2 eggs\n- 1 tbsp sugar\n\nMix and fry in a hot pan.\n' > pancakes.txt
git diff
Output
diff --git a/pancakes.txt b/pancakes.txt
index d678af5..dccd1bd 100644
--- a/pancakes.txt
+++ b/pancakes.txt
@@ -2,7 +2,8 @@ Pancakes

 Ingredients:
 - 200 g flour
-- 300 ml milk
+- 250 ml milk
 - 2 eggs
+- 1 tbsp sugar

 Mix and fry in a hot pan.

Reading a diff

  • diff --git a/pancakes.txt b/pancakes.txt — the file being compared; a/ is the old version and b/ the new one.
  • index … — internal IDs of the two versions, and the file mode.
  • --- a/… and +++ b/… — which side is marked with - and which with +.
  • @@ -2,7 +2,8 @@ Pancakes — a hunk header: this section covers 7 lines starting at line 2 of the old file, and 8 lines starting at line 2 of the new one. The text after the second @@ is a nearby line from above the change, to help you find your place in a long file.
  • Lines starting with - were removed, + were added, and a space means unchanged context. A changed line appears as a removal followed by an addition.

In a terminal with colour, removed lines are red and added lines green.

Staged changes

Plain git diff compares the working tree with the staging area — so once you stage a change, it disappears from that view:

$
git add pancakes.txt
git diff

To see what will be committed, compare the staging area with the last commit using --staged (--cached is an older name for the same option):

$
git diff --staged
Output
diff --git a/pancakes.txt b/pancakes.txt
index d678af5..dccd1bd 100644
--- a/pancakes.txt
+++ b/pancakes.txt
@@ -2,7 +2,8 @@ Pancakes

 Ingredients:
 - 200 g flour
-- 300 ml milk
+- 250 ml milk
 - 2 eggs
+- 1 tbsp sugar

 Mix and fry in a hot pan.
CommandCompares
git diffworking tree ↔ staging area (unstaged changes)
git diff --stagedstaging area ↔ last commit (what you're about to commit)
git diff HEADworking tree ↔ last commit (all your changes)

Summaries

For a quick overview, show just file names or a change count:

$
echo "Omelette: eggs, butter, cheese" > omelette.txt
git diff HEAD --stat
Output
 omelette.txt | 2 +-
 pancakes.txt | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)
$
git diff HEAD --name-only
Output
omelette.txt
pancakes.txt

Word-level differences

For prose or long lines, a whole-line diff can hide a one-word change. --word-diff marks removed words with [-…-] and added ones with {+…+}:

$
git diff --word-diff omelette.txt
Output
diff --git a/omelette.txt b/omelette.txt
index b4927c2..671eb8e 100644
--- a/omelette.txt
+++ b/omelette.txt
@@ -1 +1 @@
Omelette: eggs, [-butter-]{+butter, cheese+}

Comparing commits

Give two commits to see everything that changed between them. HEAD~2 means "two commits before HEAD" (lesson 13 explains this notation):

$
git log --oneline
Output
ebe077d (HEAD -> main) Add waffle recipe
7527bdc Adjust pancakes and omelette
a1c0941 Add first recipes
$
git diff HEAD~2 HEAD --stat
Output
 omelette.txt | 2 +-
 pancakes.txt | 3 ++-
 waffles.txt  | 5 +++++
 3 files changed, 8 insertions(+), 2 deletions(-)

You can use hashes, branch names or tags in the same way: git diff main feature shows how the tip of feature differs from the tip of main. Add a file name after -- to restrict the comparison to that file:

$
git diff HEAD~2 HEAD -- pancakes.txt
Output
diff --git a/pancakes.txt b/pancakes.txt
index d678af5..dccd1bd 100644
--- a/pancakes.txt
+++ b/pancakes.txt
@@ -2,7 +2,8 @@ Pancakes

 Ingredients:
 - 200 g flour
-- 300 ml milk
+- 250 ml milk
 - 2 eggs
+- 1 tbsp sugar

 Mix and fry in a hot pan.

Graphical diff tools

For long changes, a side-by-side view helps. Code editors show diffs when you click a changed file in their Git panel, and git difftool opens the comparison in an external tool of your choice (configured with diff.tool).

Try it yourself

Edit two files, stage only one, and predict what git diff, git diff --staged and git diff HEAD will each show. Run them to check.