How to apply a patch in git

You can apply a patch in git using the patch commandgit apply, and git am commands. patch and git apply would only apply the changes and not create any commits. “git am” is the most used way as it applies the patch in the form of commits existing in the source patch.

Let us see through a hands-on example where I run these commands on an actual machine taken on AWS cloud with a real GitHub account.

The initial setup is as shown. The repository repoone has a branch main. There are seven commits in it.

~/repoone$ git log --oneline
bead66e (HEAD -> main) Another change to new file
3f54558 This is new file
4632c0d Adding empty directory
908d6ac Third commit in main
42296d0 Second commit in main
453424e This is first commit
2673111 Initial commit

~/repoone$ git remote -v
origin  git@github.com:codeversionmaster/repoone.git (fetch)
origin  git@github.com:codeversionmaster/repoone.git (push)

~/repoone$ git branch
* main

A patch was created using git format-patch and is in file 3commits.patch. It would apply changes from 3 commits.

~/repoone$ cat 3commits.patch
From 27658cf1c79a4d05f19e5715ec9d8e9e89ed3658 Mon Sep 17 00:00:00 2001
From: codeversionmaster <112749588+codeversionmaster@users.noreply.github.com>
Date: Sun, 16 Oct 2022 08:03:20 +0530
Subject: [PATCH 1/3] Fourth line added in newfile

---
 newfile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/newfile b/newfile
index dc1c99a..bce4762 100644
--- a/newfile
+++ b/newfile
@@ -1,2 +1,4 @@
 This is new file
 Another change added to this file
+
+This is fourth line
--
2.34.1


From 9870df785ad166f8da826ad862288841b9663667 Mon Sep 17 00:00:00 2001
From: codeversionmaster <112749588+codeversionmaster@users.noreply.github.com>
Date: Sun, 16 Oct 2022 08:11:20 +0530
Subject: [PATCH 2/3] Update newfile

Fifth line in newfile
---
 newfile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/newfile b/newfile
index bce4762..66ac9df 100644
--- a/newfile
+++ b/newfile
@@ -2,3 +2,4 @@ This is new file
 Another change added to this file

 This is fourth line
+This is fifth line
--
2.34.1


From d0978f91e9ce6c4a2368ba6c4463e5ac41eb155c Mon Sep 17 00:00:00 2001
From: codeversionmaster <112749588+codeversionmaster@users.noreply.github.com>
Date: Sun, 16 Oct 2022 08:16:58 +0530
Subject: [PATCH 3/3] Sixth line in newfile

---
 newfile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/newfile b/newfile
index 66ac9df..022e8bc 100644
--- a/newfile
+++ b/newfile
@@ -3,3 +3,4 @@ Another change added to this file

 This is fourth line
 This is fifth line
+This is sixth line
--
2.34.1

Before applying the patch, we can check the stats of what might happen after applying the patch. We do this using git apply — stat.

~/repoone$ git apply --stat 3commits.patch
 newfile |    2 ++
 newfile |    1 +
 newfile |    1 +
 3 files changed, 4 insertions(+)

You can use git apply –check to see if any errors might occur on the actual patch. Note the patch again is not applied. This is to verify. Empty output in this example means that there will be no errors.

~/repoone$ git apply --check 3commits.patch

Now we have three ways to apply the patch. Let us see below.

git apply, or git patch would apply changes without creating commits

The patch above will modify the file newfile as part of one of its commits. So, we will review its contents before applying the patch. Note that the file has only two lines.

~/repoone$ cat newfile
This is new file
Another change added to this file

We can patch -p1 to apply the patch as shown.

~/repoone$ patch -p1 < 3commits.patch
patching file newfile
patching file newfile
patching file newfile

Alternatively, we can use git apply as shown.

~/repoone$ git apply < 3commits.patch

In both of these cases, we can see the output of git log –oneline to list the commits after applying the patch. You can see that no new commits have been added. There are the same seven commits even now.

~/repoone$ git log --oneline
bead66e (HEAD -> main) Another change to new file
3f54558 This is new file
4632c0d Adding empty directory
908d6ac Third commit in main
42296d0 Second commit in main
453424e This is first commit
2673111 Initial commit

But we can make out by seeing the file newfile contents to see that changes are applied.

~/repoone$ cat newfile
This is new file
Another change added to this file

This is fourth line
This is fifth line
This is sixth line

git status would show that newfile is modified. And it is not added or committed.

~/repoone$ git status
On branch main
Your branch is behind 'origin/main' by 3 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   newfile
...

Use git am to apply the patch along with commits

We will reset the commits to the previous status to remove the effect of git apply or patch -p1 commands.

We will also verify the contents of newfile file and use git log –oneline to see the list of commits to confirm we are back to the initial setup.

~/repoone$ git reset --hard bead66e
HEAD is now at bead66e Another change to new file

ubuntu@ip-172-31-0-61:~/repoone$ cat newfile
This is new file
Another change added to this file
ubuntu@ip-172-31-0-61:~/repoone$ git log --oneline

bead66e (HEAD -> main) Another change to new file
3f54558 This is new file
4632c0d Adding empty directory
908d6ac Third commit in main
42296d0 Second commit in main
453424e This is first commit
2673111 Initial commit

You can use git am with the patch file as an argument to apply the patch.

~/repoone$ git am 3commits.patch
Applying: Fourth line added in newfile
Applying: Update newfile
Applying: Sixth line in newfile

Use git log –oneline to see that all three commits are applied now.

~/repoone$ git log --oneline
a680a8e (HEAD -> main) Sixth line in newfile
d869c00 Update newfile
6fedf42 Fourth line added in newfile
bead66e Another change to new file
3f54558 This is new file
4632c0d Adding empty directory
908d6ac Third commit in main
42296d0 Second commit in main
453424e This is first commit
2673111 Initial commit