Skip to content
TextDiff

git diff Explained: Every Common Usage with Examples

A practical reference for git diff — comparing working tree, staged changes, branches, commits, and specific files. Includes output format and useful flags.

By Editorial Team Updated
  • git
  • diff
  • version control
  • command line
  • code review
git diff Explained: Every Common Usage with Examples

git diff shows the differences between various states in your repository — working tree, staging area, commits, and branches. Here’s a complete reference with examples.

The three states

Git tracks files in three states:

  • Working tree — files on disk, modified but not staged
  • Staging area (index) — changes added with git add, ready to commit
  • Repository — committed changes

git diff compares between these states or between named commits and branches.

Most common uses

Unstaged changes (working tree vs. staging area)

git diff

Shows changes in tracked files that have not been staged yet. If you’ve modified a file but haven’t run git add, this shows those changes.

Staged changes (staging area vs. last commit)

git diff --staged
# or equivalently:
git diff --cached

Shows what you’ve staged that will go into the next commit. This is what you should review before running git commit.

All changes since last commit (working tree + staged)

git diff HEAD

Combines both staged and unstaged changes relative to HEAD.

Comparing commits and branches

# Two commits
git diff abc1234 def5678

# Current branch vs main
git diff main

# Current branch vs origin/main (remote)
git diff origin/main

# What's in branch-a but not branch-b
git diff branch-b...branch-a

# Previous commit vs current HEAD
git diff HEAD~1 HEAD
git diff HEAD~1    # shorthand: HEAD~1 vs working tree

The ... (three-dot) syntax is particularly useful for branch comparisons: branch-b...branch-a shows changes on branch-a since it diverged from branch-b, which is what a pull request shows.

Comparing specific files

# Single file, unstaged changes
git diff src/utils.js

# Single file between branches
git diff main src/utils.js

# Directory
git diff main src/

# Multiple files
git diff HEAD -- src/utils.js src/helpers.js

Reading the output

diff --git a/src/utils.js b/src/utils.js
index a1b2c3d..e4f5g6h 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -12,6 +12,7 @@
 
 function greet(name) {
-  return "Hello, " + name;
+  return `Hello, ${name}!`;
+  // template literal for clarity
 }
  • diff --git a/... b/... — file being shown
  • index — blob hashes for the before/after versions
  • --- a/ and +++ b/ — original and modified labels
  • @@ -12,6 +12,7 @@ — hunk header: from old line 12 (6 lines shown), new line 12 (7 lines shown)
  • - lines: removed from old version
  • + lines: added in new version
  • Lines with spaces: context (unchanged)

Useful flags

FlagEffect
--statShow summary: files changed, insertions, deletions
--name-onlyList only file names that changed
--name-statusFile names with M/A/D status
--word-diffHighlight word-level changes within lines
-w / --ignore-all-spaceIgnore whitespace changes
--ignore-blank-linesIgnore blank line changes
-U NShow N lines of context (default 3)
--colorColorized output (usually on by default)
--no-colorForce plain output (for piping)
-p or --patchShow patch output (default for most uses)
--diff-algorithm=histogramUse histogram diff (often cleaner)

Examples:

# Quick summary of changes
git diff --stat main

# Only file names that changed
git diff --name-only HEAD~3

# Word-level diff for prose
git diff --word-diff README.md

# Ignore whitespace reformatting
git diff -w HEAD~1

Word-level diff

--word-diff is useful for documentation changes where a line changes but you want to see which words changed:

git diff --word-diff README.md

Output:

The quick [-brown-]{+red+} fox jumps over the lazy dog.

[-removed-] shows deleted text; {+added+} shows inserted text.

For plain text format (easier to copy):

git diff --word-diff=plain README.md

Diff algorithm selection

# Patience diff — better for moved blocks
git diff --diff-algorithm=patience

# Histogram — extends patience, often better for code
git diff --diff-algorithm=histogram

# Set globally
git config --global diff.algorithm histogram

The default is myers. For code with many common lines (like language boilerplate), histogram typically produces more readable diffs.

Generating and applying patches

# Generate a patch file from diff
git diff > my-changes.patch

# Generate proper patch files for mailing (one per commit)
git format-patch main

# Apply a patch
git apply my-changes.patch

# Apply with commit metadata intact (from format-patch)
git am 0001-my-commit.patch

Comparing commits across repos

# Add a remote temporarily
git remote add upstream https://github.com/original/repo.git
git fetch upstream

# Compare
git diff upstream/main

Online diff tool

For quick comparisons outside of git — comparing config files, API responses, or code snippets — textdiff.pro provides a browser-based diff view without any local setup required.