Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Git Patch Workflows: Format and Apply Patch Text

Generate reviewable patch series with git format-patch and safely inspect or apply unified diff patches with git apply.

Levels: Advanced ~55 min read

Advanced

Two patch formats, two jobs

A patch is text describing changes, but Git has more than one patch workflow. `git format-patch` takes commits and turns each non-merge commit into a mailbox-style message containing metadata, the commit message, and its patch. `git apply` instead reads diff output and applies the file changes; it does not reconstruct the commit metadata or create a commit.

bash
git format-patch -o patches BASE..HEAD
git diff BASE HEAD > change.patch
git apply --check change.patch
git apply change.patch

Quick check

Which statement correctly distinguishes the two commands?

Generate a patch series with `git format-patch`

A revision range selects the commits to turn into patches. With `BASE..HEAD`, each selected non-merge commit normally becomes a separate file. The files resemble UNIX mailbox messages and contain the author/date/subject metadata, the commit message, a separator, and the patch. This is the format intended for email-oriented patch workflows and for `git am`.

bash
git format-patch -o patches BASE..HEAD
git format-patch --stdout BASE..HEAD > series.mbox
git format-patch --numbered-files -o numbered BASE..HEAD
git format-patch --signoff -o signed BASE..HEAD

Use `-o`/`--output-directory` when you want separate patch files in a directory. `--stdout` writes the whole series as mailbox-formatted output. `--numbered-files` makes filenames simple numbers instead of deriving them from subjects. `--signoff` adds a `Signed-off-by` trailer using the current committer identity. These options change the representation or metadata of the generated patch series; they do not apply the patches.

Quick check

What does `git format-patch --stdout BASE..HEAD` produce?

Cover letters and series metadata

For a multi-commit contribution, `--cover-letter` adds a cover-letter file alongside the patches. The generated cover letter contains a place for a series description, the commit list, and an overall diffstat. The patches remain separate messages. This is preparation for an email workflow, not a replacement for the actual commits in your repository.

bash
git format-patch --cover-letter -o patches BASE..HEAD

Current Git also supports series-review metadata such as `--subject-prefix`, `--reroll-count`, `--thread`, and `--range-diff`. Those options belong to patch-series presentation and review; they do not change the underlying commit history. Use them when the receiving workflow calls for them rather than treating them as generic patch-application controls.

Create raw diff text for `git apply`

`git apply` expects diff output. A simple repository-to-repository laboratory can generate that text with `git diff BASE HEAD > change.patch`. Unlike `format-patch`, this file is not a mailbox message and carries no commit-message workflow by itself.

bash
git diff BASE HEAD > change.patch
git apply --check change.patch
git apply change.patch

`--check` performs the applicability check without changing the worktree or index. If the check succeeds, the plain command applies the patch to the working tree. No commit is created; inspect the resulting diff and decide separately whether and how to record the change.

Quick check

What does `git apply --check change.patch` do?

Choose the target: working tree, index, or both

By default, `git apply` changes files in the working tree. `--cached` changes only the index. `--index` applies to both the index and working tree and checks that the relevant index and working-tree entries agree. These are state transitions, not commits.

bash
git apply change.patch
git apply --cached change.patch
git apply --index change.patch

Use `git diff` and `git diff --cached` after applying a patch to see which state changed. This distinction matters because `git apply` does not use the normal commit workflow automatically.

Reverse, statistics, and path selection

bash
git apply --stat change.patch
git apply --numstat change.patch
git apply --summary change.patch
git apply -R change.patch
git apply --include='src/**' change.patch
git apply --exclude='docs/**' change.patch

`--stat`, `--numstat`, and `--summary` inspect a patch without applying it. `-R`/`--reverse` applies it in the opposite direction. `--include` and `--exclude` restrict which paths are considered. Include/exclude patterns are evaluated in command-line order; when any include pattern exists, paths that match no include are ignored.

Quick check

Which option reverses a patch?

Context, path prefixes, whitespace, and failures

Git normally applies patches atomically: if a hunk cannot be applied, the command fails rather than partially modifying the working tree. `--reject` changes that behavior by applying applicable hunks and writing rejected hunks to `.rej` files. `-p<n>` strips leading path components such as the default `a/` and `b/` prefixes. `-C<n>` requires additional surrounding context to match. `--whitespace=<action>` controls how whitespace errors in added or modified lines are handled.

bash
git apply --check -p1 change.patch
git apply -C1 change.patch
git apply --whitespace=error change.patch
git apply --reject change.patch

Do not use `--reject` as a generic conflict-resolution mechanism. It deliberately permits partial application and leaves rejected hunks for manual handling. For a patch generated by `git format-patch`, use `git am` when you want Git to reconstruct commits from the mailbox messages.

What this lesson does not own

`git format-patch` does not send email; `git send-email` is the dedicated sending surface. `git apply` does not create commits from mailbox messages; `git am` owns that workflow. `git diff` owns direct snapshot comparison and is used here only to produce raw diff text. `git bundle` transports Git objects and refs and is unrelated to textual patch application. `git cherry-pick`, `git rebase`, and `git revert` operate on commits and history rather than merely applying a text patch to files.

Practice what you learned

Use the dedicated Git code-completion exercise for this lesson.

Official source boundary

This lesson uses the official Git documentation for `git-format-patch`, `git-apply`, revision ranges, and diff generation. No third-party documentation is used for Git command semantics.

Was this page helpful?

Mark this learning resource complete to track your learning progress.