Apply Patches with git apply and git am
Learn to apply patches using git apply and git am. This lesson covers both commands, their differences, practical use cases, and hands-on steps to integrate patches into your Git workflow.
Focus: apply patches with git apply and git am
You've just received a patch file from a teammate who fixed a critical bug, but it's not a pull request — it's a .patch file sitting in your inbox. You could manually copy the changes, but that's error-prone and slow. The pain is real: you need to apply that patch cleanly and quickly, without breaking your working tree. Enter git apply and git am — two powerful commands that apply patches directly from files or email, making collaboration seamless even when you're not using a shared remote.
The problem this lesson solves
Patches are a fundamental way to share changes in the Git world. They represent a diff — a set of changes to one or more files — that can be applied to another repository. You might receive a patch from a contributor who doesn't have push access, or from a teammate working on a separate branch. Without git apply or git am, you'd have to manually edit files, which is tedious and prone to mistakes. The problem is even more pressing when you're maintaining an open-source project and need to integrate contributions from many people via email.
Imagine you're working on a shared codebase, and a colleague sends you a patch that adds a new feature. If you can't apply it cleanly, you waste time debugging merge conflicts or accidentally overwriting someone else's work. git apply and git am solve this by providing a standardized way to apply these changes, with options to check, revert, and even preserve commit history.
Core concept / mental model
Think of a patch file as a set of instructions for changing your code. git apply is like a surgical tool that applies those instructions directly to your working directory and index, without touching your commit history. It's perfect for quick fixes or when you want to test a change before committing.
git am, on the other hand, is like a mailbox that processes patches as if they were emails. It applies the changes and creates a commit for each patch, preserving the original commit message and author information. This makes git am ideal for integrating patches that were sent via email, like those from a mailing list or a contributor who doesn't have push access.
Here's a simple mental picture:
git apply: applies changes to files, like applying a sticker to a notebook. You see the change, but the notebook's history (the table of contents) stays the same.git am: applies changes and writes a new entry in the notebook's history, like adding a new chapter with the author's name and date.
Both commands operate on patch files, but they serve different purposes. git apply is for when you want to apply changes without committing, while git am is for when you want to apply changes and commit them in one go, preserving metadata.
The git apply command works on the patch format generated by git diff, which includes context lines that help Git locate the changes. It can apply patches to the working tree, the index, or both. git am works with patches formatted as emails (the format used by git format-patch), which include the commit message and author info. Internally, git am uses git apply under the hood, but it adds the commit step.
How it works step by step
Applying a patch might seem magical, but understanding the steps demystifies it. Here's what happens when you run git apply:
- Parse the patch: Git reads the patch file, which contains hunks (groups of changes) with context lines.
- Validate: Git checks whether the patch can be applied to the current state of the files. If the context doesn't match, it may fail.
- Apply changes: Git modifies the files in your working directory (and optionally the index) according to the patch.
The git am process is similar, but with extra steps:
- Read the patch as an email: The patch file contains headers (Subject, From, Date) and a body (commit message).
- Apply the changes: Git applies the diff (using
git applyinternally). - Commit the changes: Git creates a new commit with the message and author from the patch.
If any step fails, Git stops and leaves you to resolve the issue — either by fixing conflicts manually or by aborting the process.
For git apply, you can check if a patch applies cleanly before actually applying it, using the --check option. This is a great way to avoid messing up your working tree.
Hands-on walkthrough
Let's get practical. We'll create a simple repository, generate a patch, and apply it using both commands.
Setup: Create a repo and make a change
First, create a project with a file and commit it:
mkdir patch-demo
cd patch-demo
git init
echo "Hello, world!" > hello.txt
git add hello.txt
git commit -m "Add hello.txt"
Now, make a change (as if you were the contributor) and commit it:
echo "Hello, Git!" > hello.txt
git add hello.txt
git commit -m "Update greeting"
Generate a patch with git format-patch
To create a patch file for the last commit, use git format-patch:
git format-patch -1
This creates a file like 0001-Update-greeting.patch. It's formatted as an email, including the commit message.
Apply the patch with git am
Now, go back to the first commit with git reset (or git checkout to detach), but for simplicity, we'll simulate a different branch. First, create a new branch and reset:
git checkout -b apply-demo HEAD~1
Now apply the patch:
git am 0001-Update-greeting.patch
Check the log:
git log --oneline
You'll see a new commit with the message "Update greeting". The patch was applied and committed.
Apply a simple diff with git apply
For git apply, you need a plain diff, not an email-formatted patch. Let's create one:
git diff HEAD~1 HEAD > greeting.diff
Now, reset to the branch without the change and apply:
git reset --hard HEAD~1
git apply greeting.diff
Check hello.txt — it now has "Hello, Git!" but there's no new commit. You've applied the changes directly to your working tree.
Verify the patch applies cleanly
Before applying, you can check:
git apply --check greeting.diff
If it exits with no output, the patch will apply cleanly.
Revert a patch
To undo a patch, use git apply -R:
git apply -R greeting.diff
This reverts the changes, taking you back to "Hello, world!".
Compare options / when to choose what
| Command | Purpose | Commit created? | Preserves author? | Best for |
|---|---|---|---|---|
git apply |
Apply changes to working tree/index | No | No | Quick fixes, testing patches, reverting |
git am |
Apply patches and create commits | Yes | Yes | Integrating email patches, maintaining history |
- Use
git applywhen you're reviewing a patch and want to see the changes without committing, or when you need to apply a diff to a specific file or with--3wayto handle conflicts. - Use
git amwhen you have a patch from a contributor (especially in email format) and want to incorporate it as a commit with proper attribution.
Other tools like git cherry-pick apply a commit from another branch, but they require the commit to exist in your repo. git am is designed for external patches.
For patches generated with git diff (plain diffs), use git apply. For patches from git format-patch (email format), use git am. But you can also use git apply on email-formatted patches — it will just apply the diff part.
Troubleshooting & edge cases
Applying patches can sometimes fail. Here are common issues and fixes:
Patch fails to apply (context mismatch)
If the files have changed since the patch was created, the context may not match. Use --3way for git apply to perform a three-way merge if the blob IDs are available:
git apply --3way patch.diff
This lets Git merge changes, marking conflicts if needed.
git am fails and aborts
If git am hits a conflict, it stops and leaves you in a special state. You can resolve conflicts manually, then run:
git am --continue
Or abort entirely with:
git am --abort
Patch was generated from a different directory
If the patch was created with paths relative to a different root, you can use --directory in git apply to target a different subdirectory:
git apply --directory=src patch.diff
Empty patch or invalid format
If git apply reports "unrecognized input", the file might not be a valid patch. Ensure it's in unified diff format (e.g., generated by git diff).
Working tree is dirty
Before applying, commit or stash your changes. Otherwise, the patch may not apply cleanly.
What you learned & what's next
You've learned how to apply patches with git apply and git am — two essential commands for integrating changes from outside your repository. You now understand the core difference: git apply modifies your working tree without committing, while git am applies changes and commits them, preserving commit metadata. You practiced generating patches with git format-patch, applying them with both commands, and troubleshooting common issues.
This skill is crucial for open-source contributions, email-based workflows, and collaborating with teammates who don't share a remote. As the next step in your Git journey, explore git rebase to combine these patches with your existing history, or git cherry-pick to move commits between branches. Keep practicing, and you'll master patch management in no time.
Practice recap
In your existing repo, create a new commit, export it with git format-patch -1, then switch to an older branch and apply it with git am. Try generating a plain diff with git diff and apply it using git apply --check and then git apply. Experiment with git apply -R to revert the changes.
Common mistakes
- Using
git amon a plain diff (git diff) instead of an email-format patch fromgit format-patch— it fails with a parse error. - Forgetting to stage or commit local changes before applying a patch, leading to conflicts.
- Applying a patch without checking with
--checkfirst, only to discover it fails halfway and leaves partial changes. - Confusing
git applywithgit amand expectinggit applyto create a commit.
Variations
- Use
git apply --indexto apply changes to both the working tree and the index, ready for commit. - Use
git am --3wayto allow three-way merges during patch application, reducing conflicts. - For interactive patch application, use
git apply --rejectto apply non-conflicting hunks and leave.rejfiles for manual resolution.
Real-world use cases
- Applying a bugfix patch emailed by a contributor to an open-source project without giving them push access.
- Integrating a series of patches from a mailing list into your feature branch while preserving each commit's author and message.
- Quickly testing a patch from a teammate by applying it to a clean worktree using
git applybefore deciding to commit.
Key takeaways
git applyapplies changes to your working tree and index without creating commits.git amapplies patches as email-formatted files and creates commits, preserving commit metadata.- Use
git apply --checkto verify a patch applies cleanly before actually applying it. - Use
--3waywithgit applyorgit amto handle patches that don't apply cleanly by performing a three-way merge. - Revert a patch with
git apply -Rto undo changes. - For patches from
git format-patch, usegit am; for plain diffs, usegit apply.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.