Applying a contributor's diff
Someone sends you a plain diff, not a format-patch email. You apply it with git apply, review the result, and commit it under your own message.
Git · Command
git apply reads a diff (a patch) and applies it to files in the working tree, the index, or both. It does not create a commit. Use git am when you want commits made from mailed or format-patch patches.
Last updated
You give git apply one or more patch files, or - to read from stdin. It finds the target paths, strips leading path components (one by default), and checks that the context lines match. Then it changes the files. With no flags it only edits working-tree files and works even outside a repository. --index patches both the files and the index, while --cached patches only the index. Some options, like --stat, --numstat, --summary and --check, only report on the patch and change nothing, unless you add --apply after them.
git apply [--stat] [--numstat] [--summary] [--check] [--index | --intent-to-add] [--3way] [--ours | --theirs | --union] [--apply] [--no-add] [--build-fake-ancestor=<file>] [-R | --reverse] [--allow-binary-replacement | --binary] [--reject] [-z] [-p<n>] [-C<n>] [--inaccurate-eof] [--recount] [--cached] [--ignore-space-change | --ignore-whitespace] [--whitespace=(nowarn|warn|fix|error|error-all)] [--exclude=<path>] [--include=<path>] [--directory=<root>] [--verbose | --quiet] [--unsafe-paths] [--allow-empty] [<patch>…]| Name | Type | Description |
|---|---|---|
<patch>... | path | The patch files to read. Use - to read from standard input. |
--check | flag | Only tests whether the patch would apply and reports errors. Nothing is changed. |
--index / --cached | flag | --index patches the index and the working tree. --cached patches only the index. |
-3, --3way | flag | Falls back to a 3-way merge using the blob IDs recorded in the patch, and may leave conflict markers. |
-R, --reverse | flag | Applies the patch in reverse, which undoes it. |
--reject | flag | Applies the hunks that fit and saves the failed ones to *.rej files. |
-p<n> | integer | How many leading path components to remove from the paths in the diff. Default is 1. |
--directory=<root> | path | Adds <root> in front of every filename, after any -p stripping. |
--whitespace=<action> | enum | What to do with whitespace errors: nowarn, warn (the default), fix, error, or error-all. |
--exclude / --include=<path-pattern> | pattern | Skip, or limit the patch to, files that match the pattern. |
Changes the working tree and/or the index, but makes no commit. Report-only options such as --stat, --numstat, --summary and --check print information and change nothing. --allow-empty stops it from failing on a patch with no diff.
#!/usr/bin/env bash
set -euo pipefail
# Make a patch from uncommitted changes, then reset the tree
git diff > fix.patch
git restore .
# See what the patch touches
git apply --stat fix.patch
# Check that it applies cleanly
git apply --check fix.patch
# Apply to the working tree and stage it as well
git apply --index fix.patch
git status --short
# Undo it again
git apply -R --index fix.patchThe script saves local changes as a patch, previews it with --stat, checks it with --check, applies and stages it with --index, then undoes it with -R.
Someone sends you a plain diff, not a format-patch email. You apply it with git apply, review the result, and commit it under your own message.
A fix written for an upstream repo is applied to a copy kept in a subfolder, using --directory=vendor/lib and, if needed, -p to adjust the paths.
You edit a saved hunk by hand and then put it straight into the index with --cached --recount, leaving the working tree untouched.
A pipeline runs git apply --check --whitespace=error so that patches that don't apply or have whitespace errors are rejected before merging.
git apply only changes files and/or the index and never makes a commit. git am reads patches from a mailbox, such as git format-patch output, and creates a commit for each one, keeping the author and message. Use git apply for plain diffs, and git am when you want the history kept.
Follow-up: Can git am pass options through to git apply? Yes. Options like -p, -C, --directory, --exclude, --include, --reject and the whitespace flags are handed on to git apply.
With neither flag, only working-tree files are patched, and you don't even need a repository. --index patches both the index and the working tree, and needs them to match for the affected paths. --cached updates only the index and leaves the files alone.
Follow-up: Which option turns on --index without you asking? --3way does, unless you also pass --cached. In that case any conflicts are stored as higher stages in the index.
Use --3way to merge using the blob IDs in the patch, which may leave conflict markers for you to resolve. Or use --reject to apply the good hunks and save the failed ones as .rej files. If the patch had only small whitespace changes, --ignore-whitespace or -C<n> can make it apply.
Follow-up: Can --3way and --reject be used together? No, the docs say they are incompatible. Choose merging with conflict markers or partial application with .rej files.
git amgit diffgit format-patchgit addgit cherry-pickgit config