Understanding Unified Diff Format: A Deep Dive
A thorough guide to the unified diff format — hunk headers, context lines, binary diffs, multi-file patches, and creating and applying patches.
Priya Sharma
Platform Engineer
The Unified Diff Standard
The unified diff format is the universal language of code changes. Every patch file, every git diff output, every PR diff you've ever read uses this format. Mastering it makes you faster at code review, better at debugging, and more effective at open-source contribution. This guide goes deeper than the basics.
Complete Format Anatomy
diff --git a/src/server.ts b/src/server.ts (1)
index 3a1b2c4..5d6e7f8 100644 (2)
--- a/src/server.ts (3)
+++ b/src/server.ts (4)
@@ -10,12 +10,15 @@ function startServer() { (5)
import express from 'express' (6)
import cors from 'cors' (6)
+import helmet from 'helmet' (7)
const app = express() (6)
-app.use(cors()) (8)
+app.use(cors({ origin: ALLOWED_ORIGINS })) (9)
+app.use(helmet()) (9)
app.listen(PORT, () => { (6)
console.log('Listening on', PORT) (6)
})
diff --git— Git-specific header identifying this as a git diffindex— blob SHA1 hashes of old and new versions; file mode (100644 = regular file)---— old file path (a/prefix is convention)+++— new file path (b/prefix is convention)@@ -10,12 +10,15 @@— hunk header: old starts line 10, 12 lines; new starts line 10, 15 lines; function context hint- Space-prefixed lines — unchanged context (3 lines by default)
+line — added in new version-line — removed from old version+lines — replacements (one delete followed by adds)
The Hunk Header in Detail
@@ -10,12 +10,15 @@ breaks down as:
-10,12: In the original file, this hunk starts at line 10 and spans 12 lines (context + removed lines)+10,15: In the modified file, this hunk starts at line 10 and spans 15 lines (context + added lines)- The difference (15 - 12 = 3) tells you the net change: 3 lines were added to the file at this point
Special Cases
# New file (no old version)
--- /dev/null
+++ b/src/new-feature.ts
@@ -0,0 +1,25 @@
+// New file content...
# Deleted file (no new version)
--- a/src/old-code.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-// All deleted lines...
# Binary file change
Binary files a/assets/logo.png and b/assets/logo.png differ
Context Control
# More context (useful for readability)
git diff -U10 # 10 context lines instead of 3
# No context (minimal diff, useful for patches)
git diff -U0
# Entire file as context
git diff --unified=999999
Applying Patches
# Apply a patch file
patch -p1 < changes.patch # -p1 strips the a/ b/ prefixes
# Apply with git (more robust)
git apply changes.patch
# Apply and create a commit (with email/author metadata preserved)
git am 0001-Add-helmet-middleware.patch
# Dry-run: check if it applies cleanly
patch --dry-run -p1 < changes.patch
git apply --check changes.patch
Creating Distribution Patches
# Single commit as patch
git format-patch HEAD~1
# Multiple commits as patch series
git format-patch main..feature/my-feature
# All commits since fork point
git format-patch origin/main
# Patch with statistics
git format-patch --stat HEAD~3
Reverse Patches (Undo Changes)
# Apply a patch in reverse (undo its changes)
patch -R -p1 < changes.patch
git apply --reverse changes.patch
Share this article
Was this article helpful?
Ready to try it? Start a free comparison →
Priya Sharma
Platform Engineer
Priya Sharma writes about developer tools, software engineering best practices, and productivity for the DiffChecker Pro blog. With extensive experience in software development, Priya focuses on practical guides that help developers work more effectively.