X Xerobit

Patch File Format — How .patch Files Work and How to Apply Them

Patch files contain diff output you can apply to source files. Here's how the unified diff format used in .patch files works, how to create patch files with git and diff, and...

Mian Ali Khalid · · 4 min read
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.
Open Text Diff →

A patch file contains unified diff output that describes changes to files. You can create patches with git diff or diff, share them by email or file, and apply them with git apply or the patch command.

Use the text compare tool to compare texts and generate diffs visually.

What a patch file looks like

From abc1234 Mon Sep 17 00:00:00 2001
From: Alice Smith <alice@example.com>
Date: Mon, 11 May 2026 10:00:00 +0000
Subject: [PATCH] Fix divide-by-zero error in calculator

---
 src/calculator.js | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/calculator.js b/src/calculator.js
index abc1234..def5678 100644
--- a/src/calculator.js
+++ b/src/calculator.js
@@ -10,9 +10,12 @@ function calculate(a, op, b) {
   switch (op) {
     case '/':
-      return a / b;
+      if (b === 0) {
+        throw new Error('Division by zero');
+      }
+      return a / b;
     case '*':
       return a * b;
   }
 }
-- 
2.34.1

Creating patch files

From git changes

# Create patch from staged changes:
git diff --staged > my-changes.patch

# Create patch from unstaged changes:
git diff > my-changes.patch

# Create patch from last N commits (format-patch):
git format-patch -1 HEAD            # last commit
git format-patch -3 HEAD            # last 3 commits
git format-patch main..feature      # all commits on feature branch

# format-patch creates one file per commit:
# 0001-Fix-login-bug.patch
# 0002-Add-user-profile.patch

From the diff command

# Standard unified diff:
diff -u original.txt modified.txt > changes.patch

# Recursive diff for multiple files:
diff -ruN original-dir/ modified-dir/ > changes.patch
# -r: recursive, -u: unified format, -N: treat missing files as empty

Applying patch files

With git apply

# Apply a patch:
git apply my-changes.patch

# Check if patch applies without applying:
git apply --check my-changes.patch

# Apply with whitespace fixes:
git apply --whitespace=fix my-changes.patch

# Apply even with some errors (risky):
git apply --reject my-changes.patch
# Creates .rej files for chunks that fail

With git am (for format-patch patches)

git am preserves commit metadata (author, message):

# Apply a single format-patch file:
git am 0001-Fix-login-bug.patch

# Apply all patches in a directory:
git am *.patch
git am patches/*.patch

# If apply fails, fix the conflict and continue:
git am --continue
# Or abort:
git am --abort

With the patch command

The patch command works on any system:

# Apply a patch:
patch -p1 < my-changes.patch
# -p1: strip first path component (usually needed for git patches)

# Dry run (check without applying):
patch -p1 --dry-run < my-changes.patch

# Reverse apply (undo a patch):
patch -R -p1 < my-changes.patch

# Apply from a specific directory:
patch -p1 -d /path/to/repo < my-changes.patch

Understanding the @@ header

@@ -15,7 +15,10 @@ function calculate(a, op, b) {

Format: @@ -old_start,old_count +new_start,new_count @@

  • -15,7 — starts at line 15 in the original, covers 7 lines
  • +15,10 — starts at line 15 in the new file, covers 10 lines (3 lines added)
  • function calculate(a, op, b) { — context from the nearby code (optional)

Emailing patches

The traditional Linux kernel workflow: create a patch and email it:

# Create formatted patches for emailing:
git format-patch --cover-letter -n origin/main

# This creates:
# 0000-cover-letter.patch   (summary)
# 0001-Fix-bug.patch
# 0002-Add-feature.patch

# Send via git send-email:
git send-email --to=maintainer@example.com 0001-Fix-bug.patch

GitHub and GitLab replaced most email-based workflows with pull requests, but some open-source projects (Linux kernel, git itself) still use email patches.

Patch conflicts

When a patch doesn’t apply cleanly (context lines don’t match):

$ git apply my-changes.patch
error: patch failed: src/utils.js:15
error: src/utils.js: patch does not apply

Options:

  1. Manually apply the change shown in the patch
  2. Use --reject to apply what fits and create .rej files for conflicts
  3. Apply the patch at a different point in history

Related posts

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.