Apply a patch
| Time to read: | Activity duration: |
|---|---|
| 5 minutes | 10 minutes |
Overview
# Apply a patch to the working directory
git apply changes.patch
# Check if a patch applies cleanly
git apply --check changes.patch
# Apply an email-format patch (from format-patch)
git am 0001-feat-add-goodbye-function.patchThe git apply command applies a diff to your working directory without creating a commit.
The git am command applies an email-format patch and creates a commit using the original author and message.
Activity goal
In this activity you will apply patches to a repository, first with git apply and then with git am.
Setup
Use the utility script to create the playground folder:
./scripts/create-playground.sh patch_applyThis script prepare a working directory and provides two patch files. A simple git status command will highlight those two untracked files:
On branch main
Untracked files:
(use "git add <file>..." to include in what will be committed)
0013-refactor-remove-unused-stop-button-and-live-preview-.patch
0014-feat-compute-disk-width-relative-to-container-via-CS.patch
0015-fix-align-tower-pegs-with-disk-center-positions.patch
nothing added to commit but untracked files present (use "git add" to track)Check before apply
You wouldn't jump from a plane without a parachute.
Well, in the very same way you wouldn't commit without checking first what you are going to commit.
You should follow multiple rules when you patch your code, among them:
- commits must be applied in the order given by their numbering.
- patch author might not be on the same level of code base as you, so it's expected to have conflicts and
applyprovides some options to handle that
For this tutorial I will keep things simple. As you progress and handle more complex scenario you will have to check the reference of the apply command.
Easy scenario
You have three patches. Consider the first one, numbered 0013:
git apply --check 0013*.patchOutput should nothing, and if you check command result code with echo $? the display should be 0.
Path 0013 is fine and can be applied without issue
Failing scenario
Now, let's check the second one, numbered 0014:
git apply --check 0014*.patchOutput will dump some errors, and if you check command result code with echo $? the display should be 1.
error: patch failed: src/main.ts:19
error: src/main.ts: patch does not applyPath 0014 cannot be applied on the code as it is. Attempting to apply it will fail.
Apply but don't commit
We identified that first patch, numbered 0013, can be applied safely. So let's do that by removing the --check option.
git apply 0013*.patchCommand should apply with success and if you check your git status you should see that src/main.ts is now modified and not staged.
Note
If you check again if the patch 0014 can be applied you will note that now it's passing the test with success.
git apply --check 0014*.patchApply and commit
We applied patch 0013 but still have 0014 and 0015 to apply.
But this time we will directly commit the changes.
Make it fail
If you followed previous steps in this exercice, you should have pending modification on src/main.ts file.
We will experiment how am command behave in this context. Run the following command to apply patch 0014:
git am 0014*.patchCommand should fail and output should be like:
Applying: feat: compute disk width relative to container via CSS custom properties
error: src/main.ts: does not match index
Patch failed at 0001 feat: compute disk width relative to container via CSS custom properties
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"You could solve conflicts and proceed. But in most scenario, the best approach will be to ensure you don't have pending changes in you local clone.
Just cancel the commit action with command:
git am --abortNow, stage and commit changes on main and continue.
git add src/main.ts
git commit -m 'applied my first patch'Patch with success
Now that our local clone is clean, let's apply the patch 0014:
git am 0014*.patchOutput will only confirm that patch is applied and will also give the commit message.
Applying: feat: compute disk width relative to container via CSS custom propertiesWhat we learned
You practice with the most common use cases to apply a patch:
git apply --checkvalidates a patch before applying it.git applyapplies a diff to the working directory without committing.git amapplies email-format patches and preserves authorship metadata.