Git Diff Guide — Reading and Using git diff Commands
git diff shows what changed between commits, branches, or the working tree. Here's how to read git diff output, diff specific files, compare branches, and use diff flags to...
Use the tool
Text Diff
Compare two text blocks line-by-line or word-by-word. Unified and split view. Shows added, removed, and changed segments with full color coding.
git diff shows what changed between states of your repository. Understanding the output and knowing which flags to use makes reviewing changes and debugging history much faster.
Use the text compare tool to compare any two texts side by side.
Basic git diff commands
# Unstaged changes (working tree vs last commit):
git diff
# Staged changes (what will be committed):
git diff --staged
git diff --cached # same thing
# All changes (staged + unstaged):
git diff HEAD
# Specific file:
git diff README.md
git diff src/components/Header.tsx
# Two commits:
git diff abc1234 def5678
# Last n commits:
git diff HEAD~3 HEAD # last 3 commits
git diff HEAD~1 # just the most recent commit changes
# Two branches:
git diff main feature-branch
# What's on feature-branch but not main:
git diff main...feature-branch
Reading git diff output
diff --git a/src/utils.js b/src/utils.js
index 3a4b5c6..7d8e9f0 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -15,7 +15,10 @@ function parseConfig(filePath) {
const data = fs.readFileSync(filePath, 'utf8');
- return JSON.parse(data);
+ try {
+ return JSON.parse(data);
+ } catch (err) {
+ throw new Error(`Invalid JSON in ${filePath}: ${err.message}`);
+ }
}
Line by line:
diff --git a/... b/...— files being comparedindex 3a4b5c6..7d8e9f0— git object hashes of the two versions--- a/src/utils.js— the “before” file+++ b/src/utils.js— the “after” file@@ -15,7 +15,10 @@— hunk header:-15,7means original file at line 15 for 7 lines;+15,10means new file at line 15 for 10 lines-lines — deleted+lines — addedlines — context (unchanged)
Useful diff flags
# Word-level diff (highlights specific words changed):
git diff --word-diff
# Ignore whitespace:
git diff -w # ignore all whitespace
git diff --ignore-blank-lines # ignore blank line additions/removals
# Show just file names that changed:
git diff --name-only
git diff --name-status # also shows A/M/D status
# Stat summary (shows +/- counts per file):
git diff --stat
# No color output (for piping):
git diff --no-color
# Compact summary:
git diff --compact-summary
Diffing specific content
# Changes to a directory:
git diff src/components/
# Changes matching a pattern:
git diff '*.ts'
git diff -- '*.test.js'
# Ignore changes to generated files:
git diff ':!package-lock.json' ':!*.min.js'
# Only show certain file extensions:
git diff -- '*.py' '*.js'
Comparing branches in detail
# All changes on feature branch relative to main:
git diff main...feature-branch
# Two-dot vs three-dot diff:
git diff main..feature-branch # direct comparison of tips
git diff main...feature-branch # changes on feature since branching from main
# See what will be merged:
git diff main...HEAD
# Show branch history summary:
git log --oneline main..feature-branch
Diff in scripts and CI
# Exit code 0 if no diff, 1 if diff found:
git diff --quiet && echo "No changes" || echo "Changes found"
# Check if specific files changed:
if git diff --name-only HEAD~1 HEAD | grep -q "package.json"; then
echo "package.json changed, running npm install"
npm install
fi
# Get list of changed files as an array:
changed_files=$(git diff --name-only HEAD~1 HEAD)
Viewing diffs in different tools
# Open in vimdiff:
git difftool -t vimdiff
# Use VSCode as diff tool:
git config --global diff.tool vscode
git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'
git difftool
# Open GitHub PR diff in browser (with gh CLI):
gh pr diff 123
Generating patch files
# Create a patch file from unstaged changes:
git diff > my-changes.patch
# Create a patch from a commit:
git format-patch HEAD~1
# Apply a patch:
git apply my-changes.patch
git am < formatted.patch # for format-patch patches
Common workflows
Review before committing
# 1. Stage your changes:
git add -p # interactive staging — reviews each hunk
# 2. See exactly what will be committed:
git diff --staged
# 3. Commit:
git commit -m "fix: handle invalid JSON in parseConfig"
Find when a line was introduced
# git log -S searches for when a string appeared/disappeared:
git log -S "parseConfig" --oneline
# git log -G searches commit diffs for a regex:
git log -G "throw new Error" --oneline
# git blame shows who last touched each line:
git blame src/utils.js
git blame -L 15,25 src/utils.js # only lines 15–25
Related tools
- Text Diff Tool — compare any two texts online
- Diff Algorithm Explained — how diff algorithms work
- Merge Conflict Resolution — resolving git conflicts
Related posts
- How Diff Tools Work: Myers Algorithm, Unified Format, and Merge Conflicts — A technical walkthrough of how diff works: the Myers algorithm, the three output…
- Diff Algorithm Explained — How Text Comparison Tools Work — Text diff tools use the LCS (Longest Common Subsequence) or Myers diff algorithm…
- Understanding Merge Conflicts — How 3-Way Diff Works — Merge conflicts occur when two branches edit the same lines differently. Learn h…
- Merge Conflict Resolution — How to Resolve Git Conflicts — Git merge conflicts occur when two branches change the same lines differently. H…
- Text Diff Online — How to Compare Two Texts Side by Side — Text diff tools compare two versions of text and highlight additions, deletions,…
Related tool
Text Diff
Compare two text blocks line-by-line or word-by-word. Unified and split view. Shows added, removed, and changed segments with full color coding.
Written by Mian Ali Khalid. Part of the Dev Productivity pillar.