Home/Blog/How do I create and apply patch files from diffs?
Development

How do I create and apply patch files from diffs?

Patch files are a standard way to share and apply changes. Learn how to create patch files from diffs and apply them to other codebases.

By Inventive HQ Team
How do I create and apply patch files from diffs?

Understanding Patch Files

A patch file is a text file containing the differences between two versions of code, generated in a standard format that any developer can apply to their own version of the code. Patch files are one of the oldest and most reliable ways to share code changes across teams, projects, and communities.

Whether you're contributing to open-source projects, sharing fixes with team members, or maintaining compatibility across versions, patch files provide a portable, version-control-independent way to apply changes.

Creating Patch Files from Diffs

Basic Patch Creation with Git

The simplest way to create patch files is using Git:

# Create a patch from the latest commit
git format-patch -1

# This creates: 0001-your-commit-message.patch

# Create patches for multiple commits
git format-patch -5
# Creates: 0001-.patch, 0002-.patch, etc.

# Create patch from two commits
git format-patch -2 HEAD

Diff-Based Patch Creation

For non-Git projects or comparing arbitrary files:

# Create unified diff patch
diff -u original.js modified.js > changes.patch

# Comparing directories
diff -ruN original-dir/ modified-dir/ > changes.patch

Git Diff to Patch

# Create patch from uncommitted changes
git diff > uncommitted-changes.patch

# Create patch comparing branches
git diff main feature-branch > feature.patch

# Create patch comparing commits
git diff abc123 def456 > changes.patch

# Create patch for specific file
git diff main -- path/to/file.js > file-changes.patch

Patch File Format

Understanding Patch File Structure

diff --git a/file.js b/file.js
index abc1234..def5678 100644
--- a/file.js
+++ b/file.js
@@ -1,7 +1,8 @@
 function calculateTotal(items) {
-  let total = 0;
-  for (let i = 0; i < items.length; i++) {
-    total += items[i].price;
+  return items.reduce((total, item) => {
+    return total + item.price;
   }
-  return total;
+  }, 0);
 }

Components:

  • Header: File paths (a/ = original, b/ = modified)
  • Line numbers: @@ -1,7 +1,8 @@ (7 lines starting at line 1 in original, 8 lines in modified)
  • Context: Lines with space prefix (unchanged)
  • Additions: Lines with + prefix
  • Removals: Lines with - prefix

Multi-File Patches

Patches can contain changes to multiple files:

diff --git a/file1.js b/file1.js
[changes to file1.js]

diff --git a/file2.js b/file2.js
[changes to file2.js]

diff --git a/file3.js b/file3.js
[changes to file3.js]

Apply all changes at once with one command.

Applying Patch Files

Using git apply

# Apply patch file
git apply changes.patch

# Check if patch applies cleanly
git apply --check changes.patch

# Apply with specific path
git apply --include="src/*" changes.patch

# Reject patch on failures
git apply --reject changes.patch

Using patch Command

# Standard patch command
patch < changes.patch

# Patch specific directory
cd project/
patch < ../changes.patch

# Show what would be patched without applying
patch --dry-run < changes.patch

# Apply with specific strip level
patch -p1 < changes.patch  # For git-generated patches
patch -p0 < changes.patch  # For diff-generated patches

Strip Levels Explained

The -p flag specifies how many directory levels to strip from file paths:

Patch file contains:

--- a/src/component.js
+++ b/src/component.js

Different strip levels:

patch -p0 < changes.patch
# Looks for: a/src/component.js

patch -p1 < changes.patch
# Looks for: src/component.js (strips "a/")

patch -p2 < changes.patch
# Looks for: component.js (strips "a/src/")

Git patches usually need -p1.

Creating Shareable Patches

Creating a Clean Patch for Email

# Format patch nicely for email
git format-patch -1 --stdout > my-change.patch

# For multiple commits
git format-patch -2 --stdout | cat > my-changes.patch

Creating Patch with Context

# Include more context lines (default 3)
git diff -U5 > generous-context.patch

# This helps patches apply in similar but not identical codebases

Creating Patch with Commit Message

# Git format-patch includes commit message
git format-patch -1

# Results in file that includes commit message that can be preserved
# when applying with: git am 0001-message.patch

Real-World Patch Workflows

Scenario 1: Contributing to Open Source

# Clone repository
git clone https://github.com/project/repo.git
cd repo

# Create feature branch
git checkout -b fix-bug

# Make changes
# ...commit changes...

# Create patch for submission
git format-patch origin/main

# Or create patch from feature branch
git diff main fix-bug > fix-bug.patch

# Send patch to project maintainers

Maintainers apply with:

patch < fix-bug.patch
# or
git apply fix-bug.patch

Scenario 2: Emergency Patch Deployment

# In production environment, identified bug needs emergency fix
# Rather than full deployment, deploy a patch

# Create patch from fixed version
git diff production staging > emergency-fix.patch

# Apply to production at customer sites
cd /production/code
patch -p1 < emergency-fix.patch

# Verify changes
git status

Scenario 3: Backporting Fixes

# Fix developed in main branch
git log --oneline main | head

# Need same fix in older release branch
git checkout release-1.0

# Apply main branch fix
git format-patch release-1.0...main -- src/buggy-file.js \
  | git am

# Or manually create and apply patch
git show main:file.js > fixed-file.js
diff release-1.0:file.js fixed-file.js > backport.patch
patch < backport.patch

Handling Patch Conflicts

When Patches Don't Apply Cleanly

# Try applying with conflict markers
patch -l < changes.patch  # --ignore-whitespace

# If still fails, patch creates .rej files
# file.js.rej contains rejected hunks

# Manually review rejected changes
cat file.js.rej

# Make manual adjustments
# Then apply remaining changes
patch -R < changes.patch  # Reverse if needed

Fuzzy Matching

# Use fuzzy patch application
patch -F3 < changes.patch

# -F3 allows up to 3 lines of fuzz when matching context

Advanced Patch Operations

Creating Patches from Specific Commits

# Patch for specific commit (not pushed)
git format-patch -1 abc1234

# Patches for commits in range
git format-patch main..feature-branch

# Patches for all unpushed commits
git format-patch origin/main..HEAD

Applying Patches with Git AM

# Apply patch AND preserve commit message
git am my-change.patch

# Apply multiple patches in order
git am *.patch

# Skip problematic patch
git am --skip

# Abort if problems occur
git am --abort

# Resolve conflicts then continue
git am --continue

Creating Binary Patches

# Binary files in patches
git diff --binary > binary-changes.patch

# Apply binary patch
git apply binary-changes.patch

Best Practices with Patches

1. Always Check Before Applying

# Verify patch applies cleanly
patch --dry-run < changes.patch
# or
git apply --check changes.patch

2. Include Context Information

# Document why patch exists
# Add commentary in email or README

3. Use Meaningful Patch Names

# Good
fix-authentication-token-refresh.patch
feature-dark-mode-support.patch
security-patch-sql-injection.patch

# Bad
fix.patch
changes.patch
update.patch

4. Sign Patches for Security

# Sign patch file
gpg --sign changes.patch

# Verify signature
gpg --verify changes.patch

5. Test Patches Thoroughly

# Test on clean checkout
git clone repo test-repo
cd test-repo
patch < ../changes.patch
# Run tests
npm test

Patch Management Tools

Quilt - Patch Stack Management

# Manage stacks of patches
quilt new fix.patch
quilt edit file.js
quilt refresh

# View patch stack
quilt series
quilt status

StGit - Stack of Git Patches

# Git-based patch management
stg new my-patch
stg push
stg pop
stg status

Troubleshooting Patches

Patch Doesn't Apply

Possible causes:

  • Different code versions
  • Whitespace differences
  • File paths don't match
  • Already applied

Solutions:

# Try different strip level
patch -p0 < changes.patch
patch -p1 < changes.patch

# Ignore whitespace
patch --ignore-whitespace < changes.patch

# See what would happen
patch --dry-run < changes.patch

# Check if already applied
grep -F "$(head -1 changes.patch)" target-file

Partial Application

# If some hunks fail, .rej files show what failed
cat file.js.rej

# Manually apply failed sections
# Then patch rest of file
patch < changes.patch

Conclusion

Patch files are a fundamental tool for sharing code changes, contributing to open source, and applying fixes across versions. By understanding how to create patches from diffs and apply them effectively, you can:

  • Contribute fixes to projects you don't directly control
  • Share code changes with team members
  • Deploy emergency fixes to production systems
  • Backport fixes to older release versions
  • Maintain compatibility across versions

Whether using simple diff and patch commands or Git's more sophisticated format-patch and git am tools, patch files remain one of the most reliable and portable ways to share and apply code changes across different environments, versions, and workflows.

Mastering patch creation and application is essential for any developer working in open source communities, maintaining multiple versions, or collaborating across distributed teams.

Need Expert IT & Security Guidance?

Our team is ready to help protect and optimize your business technology infrastructure.