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
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 andb/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
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.
| Command | Compares |
|---|---|
git diff | working tree ↔ staging area (unstaged changes) |
git diff --staged | staging area ↔ last commit (what you're about to commit) |
git diff HEAD | working 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
omelette.txt | 2 +- pancakes.txt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
git diff HEAD --name-only
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
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
ebe077d (HEAD -> main) Add waffle recipe 7527bdc Adjust pancakes and omelette a1c0941 Add first recipes
git diff HEAD~2 HEAD --stat
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
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.