Course outline · 0% complete

0/28 lessons0%

Course overview →

git diff

lesson 3-2 · ~12 min · 7/28

Seeing exactly what changed

A diff is a line-by-line comparison of two versions of a file: which lines were removed, which were added. This idea is older than Git. Linux ships a diff command that compares any two files, and Git's diffing is a descendant of it.

Let's use the plain Linux diff first, since it runs in our sandbox. Its output style takes one minute to learn: lines starting with < are from the first file, lines starting with > are from the second.

Code exercise · bash

Run this. We build an old and a new version of an ingredient list, then ask diff what changed. In the output, 3c3,4 means line 3 changed into lines 3 and 4, the < line is the old text, the > lines are the new text.

git diff's three questions

Git's version compares the three zones from lesson 2-2 and marks removed lines with - and added lines with +:

$ git diff
-milk
+oat milk
+sugar

The command has three everyday forms:

CommandComparesAnswers
git diffworking directory vs staging area"what have I edited but not staged?"
git diff --stagedstaging area vs last commit"what will my next commit contain?"
git diff a1b2c3d c7d8e9ftwo commits"what changed between these snapshots?"

A classic moment of confusion: you edit a file, run git add, then git diff prints nothing. Nothing is wrong. The edit moved into the staging area, so working directory and staging area now match. Ask git diff --staged to see it.

Reading Git's real output: hunks

The git diff sample above was trimmed to its -/+ core. The real output wraps those lines in a little machinery, and it stops looking cryptic the moment you know why each piece exists:

diff --git a/pancakes.txt b/pancakes.txt
--- a/pancakes.txt
+++ b/pancakes.txt
@@ -3,1 +3,2 @@
-milk
+oat milk
+sugar
  • The header names the two versions being compared: a/ is the old one, b/ the new one.
  • @@ -3,1 +3,2 @@ is a hunk header. A hunk is one changed region; because diffs of big files would be unreadable shown whole, Git prints only the changed regions plus a few surrounding context lines (shown with a leading space). The numbers mean: this hunk starts at line 3 and covers 1 line in the old version (-3,1), and starts at line 3 covering 2 lines in the new version (+3,2).

This exact format (the unified diff) is what code review tools render (unit 8), so learning to read it pays off everywhere. Linux's diff -u flag produces it too — try it below.

Code exercise · bash

Your turn. Recreate old.txt (flour, eggs, milk) and new.txt (flour, eggs, oat milk, sugar), then run diff with the -u flag to get the unified format Git uses. The tail -n +3 just trims the two timestamp header lines so the output is stable. Finish with echo "done".

Code exercise · bash

Your turn with the Linux diff. Create before.txt containing the lines red, green, blue (in that order), and after.txt containing red, yellow, blue. Run diff before.txt after.txt, then echo "done".

Quiz

You staged your changes with git add and want to review exactly what the next commit will contain. Which command?

Problem

You edited notes.txt, ran git add notes.txt, and now plain git diff prints nothing. Which flag do you add to git diff to see your staged change?