Skip to content

Apply a patch

Time to read:Activity duration:
5 minutes10 minutes

Overview

bash
# 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.patch

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

bash
./scripts/create-playground.sh patch_apply

This 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 apply provides 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:

bash
git apply --check 0013*.patch

Output 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:

bash
git apply --check 0014*.patch

Output will dump some errors, and if you check command result code with echo $? the display should be 1.

console
error: patch failed: src/main.ts:19
error: src/main.ts: patch does not apply

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

bash
git apply 0013*.patch

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

bash
git apply --check 0014*.patch

Apply 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:

bash
git am 0014*.patch

Command 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:

bash
git am --abort

Now, stage and commit changes on main and continue.

bash
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:

bash
git am 0014*.patch

Output will only confirm that patch is applied and will also give the commit message.

console
Applying: feat: compute disk width relative to container via CSS custom properties

What we learned

You practice with the most common use cases to apply a patch:

  • git apply --check validates a patch before applying it.
  • git apply applies a diff to the working directory without committing.
  • git am applies email-format patches and preserves authorship metadata.