Skip to content

Git Patch Workflow — Complete Guide

DodaTech Updated 2026-06-24 7 min read

In this tutorial, you'll learn about Git Patch Workflow. We cover key concepts, practical examples, and best practices.

Git patches are portable representations of commits that can be emailed, reviewed, and applied without requiring a shared remote repository.

In this tutorial, you'll learn the Git patch workflow — how to create patches from commits, apply them to other repositories, manage patch series, and use patches for code review and offline collaboration. Patch workflows are essential for open source contribution via email (Linux kernel style), air-gapped environments, and situations where you can't share a remote repository. By the end, you'll manage a full patch-based contribution workflow.

Real-world use: Durga Antivirus Pro's security research team works in an air-gapped environment. They transfer patches via encrypted USB drives. Doda Browser accepts third-party contributions via patch files for security-sensitive components.

flowchart LR
  A[Developer commits changes] --> B[git format-patch]
  B --> C[Patch files .patch / .mbox]
  C --> D[Share via email / USB / upload]
  D --> E[Reviewer receives patches]
  E --> F[git am / git apply]
  F --> G[Patches applied to target repo]
  G --> H[New commits created]

Creating Patches

Generate patch files from commits using git format-patch.

# Create a patch for the latest commit
git format-patch -1 HEAD

# Create patches for the last 3 commits
git format-patch -3 HEAD

# Create patches for all commits since a specific commit
git format-patch a1b2c3d..HEAD

# Create patches since a tag
git format-patch v1.0..HEAD

# Output to a specific directory
git format-patch -3 HEAD -o ./patches/

Expected output:

$ git format-patch -3 HEAD
0001-Refactor-auth-middleware-to-use-JWT.patch
0002-Fix-null-handler-in-login-callback.patch
0003-Add-OAuth2-login-with-Google-and-GitHub.patch

$ cat 0001-Refactor-auth-middleware-to-use-JWT.patch
From a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b Mon Sep 17 00:00:00 2001
From: Jane Doe <jane@example.com>
Date: Mon, 24 Jun 2026 10:00:00 +0000
Subject: [PATCH] Refactor auth middleware to use JWT

---
 src/middleware/auth.js | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

Each patch file contains the commit message, author, date, and the diff — everything needed to recreate the commit identically.

Customizing Patch Output

Control patch content and format.

# Include number of files changed stat
git format-patch -1 HEAD --stat

# Add a cover letter for patch series
git format-patch -3 HEAD --cover-letter --output-directory=./patches

# Include signature in patches
git format-patch -1 HEAD --signature="DodaTech Code Review"

# Number patches starting from a custom counter
git format-patch -3 HEAD --start-number=42

# Create patches as a single mbox file
git format-patch -3 HEAD --stdout > all-patches.mbox

The cover letter is useful for patch series with multiple commits, explaining the overall purpose.

Applying Patches

Two main methods: git am (applies with commit metadata) and git apply (applies raw diff).

# Apply a single patch (preserves author, message, date)
git am 0001-Refactor-auth-middleware-to-use-JWT.patch

# Apply a series of patches
git am *.patch

# Apply patches from a directory
git am ./patches/*.patch

# Apply with custom recipient
git am --signoff 0001*.patch

# Dry run — check if patches apply cleanly
git am --dry-run 0001*.patch

Expected output:

$ git am 0001*.patch
Applying: Refactor auth middleware to use JWT

$ git log --oneline -1
a1b2c3d Refactor auth middleware to use JWT  # Author and date preserved

Using git apply

For raw diffs (output of git diff) that don't include commit metadata.

# Create a raw diff
git diff > changes.patch

# Apply the diff to working tree (no commit)
git apply changes.patch

# Apply and stage changes
git apply --index changes.patch

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

# Apply with offset (lines shifted)
git apply --reject changes.patch
# Creates .rej files for rejected hunks

Expected output:

$ git apply --check changes.patch
# No output = patch applies cleanly

$ git apply changes.patch
$ git diff --stat
 src/middleware/auth.js | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

Handling Patch Conflicts

When a patch doesn't apply cleanly, resolve conflicts.

# If git am fails, it stops and reports the conflict
$ git am 0002*.patch
Applying: Fix null handler in login callback
error: patch failed: src/handler.js:25
error: src/handler.js: patch does not apply
Patch failed at 0002 Fix null handler in login callback
hint: Use 'git am --show-current-patch' to see the failed patch

# Resolve conflicts
git status
# Edit the conflicted files manually
git add src/handler.js
git am --continue

# Or skip this patch
git am --skip

# Or abort the entire am session
git am --abort

# For git apply conflicts:
git apply --reject patch.diff
# Apply what it can, leave .rej files for the rest
# Manually fix .rej files, then delete them

Patch Series Workflow

A complete workflow for contributing via patches.

# Contributor side
git checkout -b feature/new-algorithm

# Make changes across multiple commits
git commit -m "feat: add compression algorithm interface"
git commit -m "feat: implement LZ4 compression"
git commit -m "feat: add decompression tests"

# Create patches
git format-patch main --output-directory=./patches --cover-letter

# This creates:
# patches/0000-cover-letter.patch
# patches/0001-feat-add-compression-algorithm-interface.patch
# patches/0002-feat-implement-LZ4-compression.patch
# patches/0003-feat-add-decompression-tests.patch

# Reviewer side
git checkout -b review/new-algorithm main
git am ./patches/*.patch

# If patches apply cleanly, merge
git checkout main
git merge review/new-algorithm

Sending Patches via Email

For projects that use email-based workflows (Linux kernel, git itself).

# Configure git-send-email
git config sendemail.smtpServer smtp.gmail.com
git config sendemail.smtpServerPort 587
git config sendemail.smtpEncryption tls
git config sendemail.smtpUser your-email@gmail.com

# Send a patch series
git send-email \
  --to=maintainer@project.org \
  --cc=mailing-list@project.org \
  --cover-letter \
  ./patches/*.patch

# Send a single patch
git send-email \
  --to=maintainer@project.org \
  0001-My-change.patch

Patch Review Workflow

Review patches without applying them.

# View the patch stat
git apply --stat 0001*.patch

# View the full patch content
git diff --stat 0001*.patch
cat 0001*.patch

# Check if the patch applies to current HEAD
git apply --check 0001*.patch

# Apply to a temporary branch for testing
git checkout -b test-patch main
git am 0001*.patch
# Run tests, inspect code, then delete the branch
git checkout main
git branch -D test-patch

Common Errors

  1. patch does not apply — The target code has diverged from the source. Rebase the patch series on the latest target branch, or use git am --3way to enable three-way merge fallback.
  2. Trailing whitespace warnings — Patches fail if the linter catches whitespace. Use git am --whitespace=fix to automatically fix trailing whitespace.
  3. git am requires a clean working treegit am refuses to run with uncommitted changes. Stash or commit before applying patches.
  4. Binary file patches are large — Patches for binary files are sent as base64-encoded full files. Consider using Git LFS for binaries and excluding them from patches with .gitattributes.
  5. Wrong patch order — Applying patches in the wrong order creates conflicts. Use git format-patch output which numbers patches sequentially, and apply with git am *.patch (sorted order).

Practice Questions

What is the difference between git format-patch and git diff?

git format-patch outputs complete email-ready patches with commit metadata (author, date, message) and can be applied with git am to recreate commits exactly. git diff outputs only the raw changes without metadata, for use with git apply which changes the working tree without creating commits.

How do I create a patch for only staged changes?

Use git diff --cached > staged.patch for raw diff, or git format-patch -1 HEAD if you've already committed. For unstaged changes, use git diff > unstaged.patch.

How do I handle binary files in patches?

By default, git format-patch includes binary files as base64-encoded attachments. This makes patches very large. Use .gitattributes with binary export-ignore to exclude binaries, or use Git LFS for large binary files.

Can I use patches with pull requests on GitHub?

Yes. You can download a patch version of any GitHub pull request by appending .patch to the PR URL: https://github.com/user/repo/pull/123.patch. This can be applied with git am.

What is the Linux kernel patch workflow?

The Linux kernel uses an email-based workflow. Developers send patches to mailing lists via git send-email. Maintainers review and apply patches using git am. There is no central pull request system — all changes flow through mailing list patches. Over 500 patches are applied per day using this workflow

Challenge

Simulate a complete patch-based contribution workflow. Fork a repository, make three related commits on a feature branch, generate patches with a cover letter, transfer the patches to a fresh clone (no remotes), apply them with git am, resolve any conflicts by editing the patches, and verify the commits match the original (same author, message, and diff).

Real-World Task

The security research team at Durga Antivirus Pro needs to share signature updates with the main development team across an air-gapped network. Set up a patch workflow: researchers generate patches from their internal repository, transfer them on encrypted media, and the development team applies them via git am. The workflow must preserve commit authorship, include a cover letter describing each batch, handle conflicts gracefully, and verify patch integrity with GPG signatures.


Previous: Git Diff & Patch | Related: Git Hooks | Related: GPG Signing

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro