Skip to content
masterclass Buddy

Git · Command

git apply

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

How it works

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.

Syntax

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>…]

Parameters

NameTypeDescription
<patch>...pathThe patch files to read. Use - to read from standard input.
--checkflagOnly tests whether the patch would apply and reports errors. Nothing is changed.
--index / --cachedflag--index patches the index and the working tree. --cached patches only the index.
-3, --3wayflagFalls back to a 3-way merge using the blob IDs recorded in the patch, and may leave conflict markers.
-R, --reverseflagApplies the patch in reverse, which undoes it.
--rejectflagApplies the hunks that fit and saves the failed ones to *.rej files.
-p<n>integerHow many leading path components to remove from the paths in the diff. Default is 1.
--directory=<root>pathAdds <root> in front of every filename, after any -p stripping.
--whitespace=<action>enumWhat to do with whitespace errors: nowarn, warn (the default), fix, error, or error-all.
--exclude / --include=<path-pattern>patternSkip, or limit the patch to, files that match the pattern.

Returns

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.

Key points

  • git apply never records a commit. You stage and commit the result yourself, or use git am to keep the authorship and message.
  • Run --check first, for example in CI or a script, to see whether a patch will apply without touching any files.
  • -p<n> sets how many leading directory parts to drop from the diff paths. The default of 1 removes the a/ and b/ prefixes that git diff adds.
  • With --3way, Git can merge a patch whose context no longer matches exactly, provided you have the original blobs locally. Conflicts can then be settled with --ours, --theirs or --union.
  • If you run it inside a subdirectory of a repository, changes to files outside that subdirectory are quietly skipped.
  • When you combine --include and --exclude, each path is tested against them in the order given on the command line, and the first pattern that matches wins.
  • Whitespace problems such as trailing spaces only produce warnings by default and the patch still applies. Use --whitespace=fix or error to be stricter.

Common mistakes

  • By default it is all or nothing: if one hunk fails, no file is changed. Add --reject to apply what fits and get .rej files for the rest.
  • --index fails if a file's staged copy and working copy differ, even when the patch would apply to each of them separately.
  • Patches made with --unified=0 have no context lines, so they need --unidiff-zero, and the docs advise against using them.
  • A patch that touches paths outside the working area is refused unless you pass --unsafe-paths, and that option does nothing when --index or --cached is used.

Example: Preview, check, apply, and undo a patch

#!/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.patch

The 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.

When to use it

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.

Moving a change to a vendored copy

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.

Staging an edited patch

You edit a saved hunk by hand and then put it straight into the index with --cached --recount, leaving the working tree untouched.

Checking patches in CI

A pipeline runs git apply --check --whitespace=error so that patches that don't apply or have whitespace errors are rejected before merging.

Interview questions

QWhat is the difference between git apply and git am?

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.

QHow do --index and --cached change what git apply does?

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.

QA patch fails because a few hunks don't match. What can you do?

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 am
  • git diff
  • git format-patch
  • git add
  • git cherry-pick
  • git config

Source: Git - git-apply Documentation. Checked 2026-11-02.