Skip to content

Git - Patch Operation

A patch is a text file containing a set of changes, similar to the output of git diff. However, patches generated by Git can also include metadata about commits, such as the commit ID, author, date, and commit message. You can create patches from your commits and share them with others, who can then apply these changes to their repositories. This is useful for sharing changes when direct push access isn’t available or for code review processes.

Imagine Jerry has implemented a new feature, say an add_numbers function, in his project. Jerry can create a patch file of his changes and send it to Tom. Tom can then apply this patch to his own version of the project.

Jerry uses the git format-patch command to create a patch for his latest commit. To create patches for a range of commits or a specific commit, you can specify the commit ID or a range. For example, git format-patch -1 creates a patch for the most recent commit (HEAD).

[jerry@dev-machine project/src]$ pwd
/home/jerry/project/src
[jerry@dev-machine src]$ git status -s
M math_operations.c
?? math_operations_test
[jerry@dev-machine src]$ git add math_operations.c
[jerry@dev-machine src]$ git commit -m "Added add_numbers function"
[main b4c7f09] Added add_numbers function
1 file changed, 10 insertions(+)
[jerry@dev-machine src]$ git format-patch -1 HEAD
0001-Added-add_numbers-function.patch

The command above creates a .patch file (e.g., 0001-Added-add_numbers-function.patch) in the current directory. Tom can now use this patch. Git provides two main commands to apply patches: git apply and git am.

git apply takes a patch file (which can be a raw diff or a Git-formatted patch) and applies the changes to the files in your working directory. It does not create a commit. This is useful if you want to review the changes before committing or if the patch is a simple diff without commit metadata.

First, Tom can check if the patch applies cleanly:

[tom@dev-machine project/src]$ git apply --check 0001-Added-add_numbers-function.patch

If there’s no output, the patch should apply cleanly. Now, Tom applies the patch:

[tom@dev-machine project/src]$ pwd
/home/tom/project/src
[tom@dev-machine src]$ git status -s
[tom@dev-machine src]$ git apply 0001-Added-add_numbers-function.patch
[tom@dev-machine src]$ git status -s
M math_operations.c
?? 0001-Added-add_numbers-function.patch

The patch is applied, and math_operations.c is modified. Tom can review the changes using git diff:

[tom@dev-machine src]$ git diff math_operations.c

The output will show the changes introduced by the patch:

diff --git a/src/math_operations.c b/src/math_operations.c
index 8ab7f42..f282fcf 100644
--- a/src/math_operations.c
+++ b/src/math_operations.c
@@ -1,5 +1,12 @@
#include <stdio.h>
+int add_numbers(int a, int b)
+{
+ // Function to add two integers
+ return a + b;
+}
+
double calculate_mean(int *data, int count)
{
double sum = 0.0;

After reviewing, Tom would then stage and commit these changes: git add math_operations.c and git commit -m "Incorporate add_numbers function from Jerry's patch".

git am (apply mailbox) is used to apply patches that are formatted as email messages, which is what git format-patch produces. git am applies the patch and creates a commit, using the metadata (author, message, date) from the patch file. This is generally the preferred way to apply patches created with git format-patch.

If Tom wanted to use git am (assuming he hasn’t already applied and committed):

[tom@dev-machine project/src]$ git am 0001-Added-add_numbers-function.patch
Applying: Added add_numbers function

This command would apply the changes and create a new commit with the original commit message and author information from Jerry’s patch. If there are conflicts, git am will stop and allow you to resolve them.