Viewing Differences (git diff)
git diff shows the changes between two versions of your code. It is the way you answer questions like “what did I change since the last commit?”, “what is staged for the next commit?”, or “what is different between these two branches?”. Without git diff, every commit would be a leap of faith — with it, you always know exactly what you are about to ship.
The four most useful diff invocations
Daily diffs
git diff # working dir vs staging area git diff --staged # staging area vs last commit git diff HEAD # working dir + staging vs last commit git diff main..feature # one branch vs another
Reading diff output
Typical diff output
diff --git a/src/app.js b/src/app.js
index 1a2b3c4..5d6e7f8 100644
--- a/src/app.js
+++ b/src/app.js
@@ -10,7 +10,9 @@ function greet(name) {
if (!name) {
return "Hello, world!";
}
- return "Hi " + name;
+ return `Hello, ${name}!`;
}
+// New helper
+const farewell = (n) => `Goodbye, ${n}`;diff --git a/src/app.js b/src/app.js— the file being compared.index 1a2b...5d6e... 100644— old and new blob hashes plus file mode.--- a/src/app.js/+++ b/src/app.js— old and new versions.@@ -10,7 +10,9 @@— “hunk header”: starting at line 10 of the old file (7 lines), line 10 of the new file (9 lines).Lines starting with
-are removals;+are additions; a space is unchanged context.
Compare specific files
git diff src/app.js # one file git diff src/ # a folder git diff -- "*.js" # by pattern git diff HEAD~3 HEAD -- src/app.js # one file across commits
Word-level and character-level diffs
# Show changes word-by-word git diff --word-diff # Even finer — character-by-character (useful for prose) git diff --word-diff=color --word-diff-regex='.'
Stat summaries
Just count the changes
git diff --stat # src/app.js | 5 +++-- # src/util.js | 12 +++++++++++- # 2 files changed, 14 insertions(+), 3 deletions(-) git diff --shortstat # 2 files changed, 14 insertions(+), 3 deletions(-) git diff --numstat # 3 2 src/app.js # 11 1 src/util.js # Just the file names that changed git diff --name-only # src/app.js # src/util.js
Comparing branches and commits
Branches and commits
git diff main feature # what does feature have that main doesn't git diff main..feature # same — two-dot is exclusive on each side git diff main...feature # three-dot: changes on feature since it forked git diff HEAD~3 HEAD # changes in the last 3 commits git diff v1.0..v1.1 # changes between two tags
Diffs in colour and side-by-side
# Force colour even when piped git diff --color=always | less -R # Side-by-side with delta, diff-so-fancy, or a GUI tool git config --global core.pager delta git config --global delta.side-by-side true # Or use a built-in difftool git difftool main..feature
Useful flags
--cached/--staged— diff between staging and last commit.--name-status— show only file names + a one-letter status (A/M/D/R).-w/--ignore-all-space— hide whitespace-only changes.-b/--ignore-space-change— ignore changes in amount of whitespace.--no-color— plain output, no terminal codes.-U10— show 10 lines of context around each hunk (default is 3).--patience/--minimal/--histogram— different diff algorithms; histogram is often best.
Inspect a single past commit
# What did commit abc1234 change? git show abc1234 git diff abc1234^ abc1234 # equivalent: parent to commit
Ignoring whitespace
Don't get distracted by reformatting
git diff -w main..feature # ignore all whitespace differences git diff --ignore-blank-lines # ignore added/removed empty lines
Using external diff tools
Configure a GUI diff tool once
# VS Code git config --global diff.tool vscode git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE' # Beyond Compare git config --global diff.tool bc4 # Then: git difftool # opens GUI git difftool main..feature
Practical patterns
Before every commit —
git diff --stagedto confirm what you are about to commit.Before every push —
git log origin/main..HEAD --statthengit diff origin/main..HEADto see exactly what is going to the remote.During code review —
git diff main...featurefor the three-dot view that PR tools show.Debugging a regression —
git diff v1.0..HEAD -- path/to/fileto see how a file evolved across a range.
git diff --color | less -R for paged colour output, or install a prettifier like delta to make diffs look like a modern review UI in the terminal.