The Hook (The "Byte-Sized" Intro)
git diff is the x-ray machine for your code. While git status tells you which files changed, git diff tells you exactly what changed inside them — line by line, character by character, with red for removals and green for additions. It's the difference between knowing "the engine was modified" and seeing the mechanic's wrench marks.
📖 What is git diff?
git diff shows the exact line-by-line changes between different states of your files. By default, it compares the working tree to the staging area. With flags, it can compare any two commits, branches, or states.
Conceptual Clarity
git diff has three main modes:
| Command | Compares | Use Case |
|---|---|---|
git diff | Working tree ↔ Staging area | "What have I changed but not staged?" |
git diff --staged | Staging area ↔ Last commit | "What am I about to commit?" |
git diff HEAD | Working tree ↔ Last commit | "Everything I changed since last commit" |
Reading the output:
- Lines starting with
-(red) = removed - Lines starting with
+(green) = added - Lines with no prefix = unchanged context
- The
@@header shows which lines are affected
Real-Life Analogy
git diff is the "Track Changes" feature in Microsoft Word — but for code. It shows every insertion in green and every deletion in red, with enough surrounding context to understand the change.
Visual Architecture
Why It Matters
- Review before commit: Never commit blindly —
git diff --stagedshows exactly what will be saved. - Catch mistakes: Spot accidental changes, debug prints, or leftover code before they enter history.
- Compare anything: Diff between branches, commits, or even specific files across time.
- Code review: Understand exactly what a pull request changes.
Code
# ─── See unstaged changes (working tree vs staging) ───
git diff
# Output:
# diff --git a/app.js b/app.js
# --- a/app.js
# +++ b/app.js
# @@ -1,3 +1,4 @@
# const express = require('express');
# +const cors = require('cors'); ← added line (green)
# const app = express();
# -app.listen(3000); ← removed line (red)
# +app.listen(8080); ← replacement line (green)
# ─── See staged changes (staging vs last commit) ───
git diff --staged
# This shows what will be committed when you run git commit
# ─── See ALL changes (working tree vs last commit) ───
git diff HEAD
# ─── Diff a specific file only ───
git diff app.js
git diff --staged style.css
# ─── Diff between two branches ───
git diff main feature/login
# ─── Diff between two commits ───
git diff a1b2c3d e4f5g6h
# ─── Show only file names that changed ───
git diff --name-only
git diff --name-only main..feature/login
# ─── Show stats (like --stat in git log) ───
git diff --stat
# Output:
# app.js | 3 +-
# style.css | 1 +
# 2 files changed, 3 insertions(+), 1 deletion(-)
# ─── Word-level diff (see changes within a line) ───
git diff --word-diff
# Output shows {+added+} and [-removed-] inlinegit diff Cheat Sheet
| Command | What It Compares |
|---|---|
git diff | Working tree ↔ Staging area |
git diff --staged (or --cached) | Staging area ↔ Last commit |
git diff HEAD | Working tree ↔ Last commit |
git diff <branch1> <branch2> | Two branches |
git diff <hash1> <hash2> | Two specific commits |
git diff --name-only | Just filenames, no content |
git diff --stat | Summary (files, insertions, deletions) |
git diff --word-diff | Inline word-level changes |
Key Takeaways
git diffshows unstaged changes;git diff --stagedshows staged changes.- Always run
git diff --stagedbefore committing to verify what you're about to save. - Use
--name-onlyfor a quick overview,--statfor a summary, and no flags for full detail. - You can diff between any two commits, branches, or states.
Interview Prep
-
Q: What is the difference between
git diffandgit diff --staged? A:git diffcompares the working tree to the staging area (shows changes not yet staged).git diff --stagedcompares the staging area to the last commit (shows changes that will be included in the next commit). -
Q: How do you see what changed between two branches? A: Use
git diff branch1 branch2. This shows all the line-by-line differences between the tips of the two branches. Add--name-onlyto see just the file names. -
Q: What does the
@@line in a diff output mean? A: The@@line is the hunk header. It shows the line numbers affected in both the old and new versions. For example,@@ -1,3 +1,4 @@means the change starts at line 1 in the old file (3 lines of context) and line 1 in the new file (4 lines of context).