Thuta Learning
IntermediateDevOps & Toolsintermediate

Reading Changes with git diff

What you'll walk away with

  • Explain the core ideas behind Reading Changes with git diff
  • Read the diagram and trace how state or data flows through the Git/GitHub workflow
  • Decide how this applies to your own project or team

Build the mental model

`git diff` answers one question in three different contexts: what exactly changed, and between which two points?

CommandCompares
git diffworking directory vs staging area
git diff --stagedstaging area vs last commit
git diff A...Btwo commits/branches directly

The output format is the same in every case. Each changed file gets a header, followed by hunks marked `@@ -a,b +c,d @@` that show which line ranges are involved.

  • `-` lines — existed before and were removed
  • `+` lines — newly added
  • Unmarked lines — unchanged context

A `-` line right above a nearly identical `+` line usually means one word changed, not the whole line — look for the small difference between them.

text
THREE THINGS git diff CAN COMPARE
---------------------------------
THREE THINGS git diff CAN COMPARE
------------------------------------
git diff                 : working dir   vs   staging area
git diff --staged        : staging area  vs   last commit
git diff main...feature  : branch main   vs   branch feature

Connect it to a real scenario

See the unstaged diff

Edit a file and run `git diff` — you'll see a header, `@@` hunk marker, and `-`/`+` lines.

See the staged diff

`git add` then `git diff --staged` — same content, just a different baseline.

Compare two branches

`git diff main...feature` shows what changed since the branches diverged.

Try the working example

bash
git init -q -b main
git config user.name "Thuta Learner"
git config user.email "learner@example.com"

export GIT_AUTHOR_NAME="Thuta Learner"
export GIT_AUTHOR_EMAIL="learner@example.com"
export GIT_COMMITTER_NAME="Thuta Learner"
export GIT_COMMITTER_EMAIL="learner@example.com"

cat > greet.js <<'EOF'
function greet(name) {
  console.log("Hello, " + name);
}
greet("world");
EOF
git add greet.js
GIT_AUTHOR_DATE="2026-01-07T09:00:00" GIT_COMMITTER_DATE="2026-01-07T09:00:00" \
  git commit -m "Add greet function"
git branch -M main

cat > greet.js <<'EOF'
function greet(name) {
  console.log("Hello, " + name + "!");
}
greet("world");
EOF

git diff

git add greet.js
git diff --staged

GIT_AUTHOR_DATE="2026-01-07T10:00:00" GIT_COMMITTER_DATE="2026-01-07T10:00:00" \
  git commit -m "Add exclamation to greeting"

git checkout -b feature
cat > greet.js <<'EOF'
function greet(name) {
  console.log("Hi there, " + name + "!");
}
greet("world");
EOF
git add greet.js
GIT_AUTHOR_DATE="2026-01-07T11:00:00" GIT_COMMITTER_DATE="2026-01-07T11:00:00" \
  git commit -m "Change greeting wording on feature branch"

git diff main...feature
You should see
$ git diff
diff --git a/greet.js b/greet.js
index c30f984..629b3db 100644
--- a/greet.js
+++ b/greet.js
@@ -1,4 +1,4 @@
 function greet(name) {
-  console.log("Hello, " + name);
+  console.log("Hello, " + name + "!");
 }
 greet("world");

$ git add greet.js
$ git diff --staged
diff --git a/greet.js b/greet.js
index c30f984..629b3db 100644
--- a/greet.js
+++ b/greet.js
@@ -1,4 +1,4 @@
 function greet(name) {
-  console.log("Hello, " + name);
+  console.log("Hello, " + name + "!");
 }
 greet("world");

$ git diff main...feature
diff --git a/greet.js b/greet.js
index 629b3db..54bea71 100644
--- a/greet.js
+++ b/greet.js
@@ -1,4 +1,4 @@
 function greet(name) {
-  console.log("Hello, " + name + "!");
+  console.log("Hi there, " + name + "!");
 }
 greet("world");

5-minute try-it

Edit a tracked file and run `git diff` to see the unstaged change. Stage it and run `git diff --staged` to see the same change from a different baseline. Then create a second branch, make a different change there, and run `git diff main...yourbranch` from main to see exactly what the branch changed, independent of your working directory.

One important caution

Running `git diff` after staging a file shows nothing, because the change is now already reflected in the staging area — you need `git diff --staged` to see staged changes.

Two-dot (`git diff main..feature`) and three-dot (`git diff main...feature`) syntax compare different things — three-dot compares against the common ancestor, which is almost always what you want when reviewing a branch's changes.

Git Documentation: git-diffGit & GitHub

Easy traps

  • Running `git diff` after staging a file shows nothing, because the change is now already reflected in the staging area — you need `git diff --staged` to see staged changes.
  • Two-dot (`git diff main..feature`) and three-dot (`git diff main...feature`) syntax compare different things — three-dot compares against the common ancestor, which is almost always what you want when reviewing a branch's changes.
  • Always run `git status` before any destructive or history-rewriting command, to know exactly what state you're in.

Exercise

Edit a tracked file and run `git diff` to see the unstaged change. Stage it and run `git diff --staged` to see the same change from a different baseline. Then create a second branch, make a different change there, and run `git diff main...yourbranch` from main to see exactly what the branch changed, independent of your working directory.

You'll know it worked when: $ git diff diff --git a/greet.js b/greet.js index c30f984..629b3db 100644 --- a/greet.js +++ b/greet.js @@ -1,4 +1,4 @@ function greet(name) { - console.log("Hello, " + name); + console.log("Hello, " + name + "!"); } greet("world"); $ git add greet.js $ git diff --staged diff --git a/greet.js b/greet.js index c30f984..629b3db 100644 --- a/greet.js +++ b/greet.js @@ -1,4 +1,4 @@ function greet(name) { - console.log("Hello, " + name); + console.log("Hello, " + name + "!"); } greet("world"); $ git diff main...feature diff --git a/greet.js b/greet.js index 629b3db..54bea71 100644 --- a/greet.js +++ b/greet.js @@ -1,4 +1,4 @@ function greet(name) { - console.log("Hello, " + name + "!"); + console.log("Hi there, " + name + "!"); } greet("world");

Reading Changes with git diff | Thuta Learning