Git's Patch feature

Patch function of Git Most software development in the UNIX world is collaborative. Therefore, Patch is a very important thing, because almost all ordinary contributors to large UNIX projects submit code through Patch. As one of the most important open source projects, Linux, is the same. Ordinary developers clone the code from the software repository, then write the code, make a Patch, and finally send it to the Linux Kernel maintainer by E-mail. Git was originally used as a version control tool for Linux, providing a transparent, complete and stable Patch function.

Let's first introduce what Patch is. If a software has a new version, we can completely download the new version of the code to compile and install. However, with a large project like the Linux Kernel, the code, even compressed, exceeds 70MB, and each fresh download comes at a considerable cost. However, the code changed in each update may not exceed 1MB, so as long as we can have the diff data of the two versions of the code, we should be able to update the program at a very low cost. So Larry Wall developed a tool: patch. It can do version updates based on a diff file.

But in git, we don't need to use diff and patch directly to do patches, which is dangerous and troublesome. git provides two simple patch schemes. One is the standard patch generated by git diff, and the other is the Git-specific patch generated by git format-patch.

1. Standard patch generated
by git diff We can first make a patch with git diff. The working directory of the example in this article initially has a file a with the content "This is the file a.", placed in the master branch. In order to modify the code, our general practice is to create a new branch:

sweetdum@sweetdum-ASUS:~/GitEx$ git branch Fix
sweetdum@sweetdum-ASUS:~/GitEx$ git checkout Fix
Switched to branch 'Fix'

Next we append a line to the a file and execute git diff.
sweetdum@sweetdum-ASUS:~/GitEx$ echo 'Fix!!!'>>a
sweetdum@sweetdum-ASUS:~/GitEx$ git diff
diff --git a/ab/a
index 4add65f..0d295ac 100644
--- a/a
+++ b/a
@@ -1 +1,2 @@
This is the file a.
+Fix!!!

We see the output of Git diff, which is a very typical Patch-style diff. This way we can directly turn this output into a Patch:
sweetdum@sweetdum-ASUS:~/GitEx$ git commit -a -m "Fix"
[Fix b88c46b] Fix
1 files changed, 1 insertions(+), 0 deletions(- )
sweetdum@sweetdum-ASUS:~/GitEx$ git diff master > patch
sweetdum@sweetdum-ASUS:~/GitEx$ git checkout master
Switched to branch 'master'

We now have a patch file and master checked out, next we can use git apply to apply the patch. Of course, in practical applications, we will not build a patch in one branch and apply it to another branch, because only merge is enough. We don't have this Fix branch right now. Normally, to protect master, we create a branch dedicated to handling new patches:

sweetdum@sweetdum-ASUS:~/GitEx$ git branch PATCH
sweetdum@sweetdum-ASUS:~/GitEx$ git checkout PATCH
Switched to branch 'PATCH'
sweetdum@sweetdum-ASUS:~/GitEx$ git apply patch
sweetdum@sweetdum-ASUS:~/GitEx$ git commit -a -m "Patch Apply"
[PATCH 9740af8] Patch Apply
1 files changed, 1 insertions( +), 0 deletions(-)

Look, now that we have applied this patch in the PATCH branch, we can compare the PATCH branch with the Fix, and the result must be nothing, indicating that the PATCH branch and the Fix branch are exactly the same. The patch was applied successfully. git diff can generate a patch even with multiple files.

2. The git-specific patch generated by git format-patch.
We also use the working directory of the above example, this time, we use git format-patch to generate a patch after adding a new line to a in the Fix branch.
sweetdum@sweetdum-ASUS:~/GitEx$ git checkout Fix
Switched to branch 'Fix'
sweetdum@sweetdum-ASUS:~/GitEx$ echo 'Fix!!!'>>a
sweetdum@sweetdum-ASUS:~/GitEx$ git commit -a -m "Fix1"
[Fix 6991743] Fix1
1 files changed, 1 insertions(+), 0 deletions(-)
sweetdum@sweetdum-ASUS:~/GitEx$ git format-patch -M master
0001-Fix1.patch

The -M option of git format-patch indicates that this patch is to be compared with that branch. Now that it generates a patch file, let's see what that is:

sweetdum@sweetdum-ASUS:~/GitEx$ cat 0001-Fix1.patch
From 6991743354857c9a6909a253e859e886165b0d90 Mon Sep 17 00:00:00 2001
From: Sweetdumplings <linmx0.130@163 com>
Date: Mon, 29 Aug 2011 14:06:12 +0800
Subject: [PATCH] Fix1

---
a | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/ab/a
index 4add65f..0d295ac 100644
--- a/a
+ ++ b/a
@@ -1 +1,2 @@
This is the file a.
+Fix!!!
--
1.7.4.1

Look, there are a lot more things this time, not only the diff information, but also the submitter , time, etc. If you look carefully, you will find that this is an E-mail file, you can send it directly! This patch, we use git am to apply.

sweetdum@sweetdum-ASUS:~/GitEx$ git checkout master
Switched to branch 'master'
sweetdum@sweetdum-ASUS:~/GitEx$ git branch PATCH
sweetdum@sweetdum-ASUS:~/GitEx$ git checkout PATCH
sweetdum@sweetdum-ASUS :~/GitEx$ git am 0001-Fix1.patch
Applying: Fix1
sweetdum@sweetdum-ASUS:~/GitEx$ git commit -a -m "PATCH apply"

After submitting the patch, we can look at the current status of file a:

sweetdum@sweetdum-ASUS:~/GitEx$ cat a
This is the file a.
Fix!!!

Sure enough, there is one more Fix!!!

But it should be noted that if there are multiple commits between the master and the Fix branch, it will generate a patch for each commit.

3. Comparison of the two patches:
• Compatibility: Obviously, the patches generated by git diff are highly compatible. If the official repository of the code you are modifying is not a Git-managed repository, then you must use the patch generated by git diff in order for your code to be accepted by the maintainers of the project.
• Debugging function: For the patch generated by git diff, you can use git apply --check to check whether the patch can be applied to the current branch cleanly and smoothly; if the patch generated by git format-patch cannot be applied to the current branch, git am will Give tips and assist you in completing the patching work. You can also use git am -3 for three-way merge. For details, please refer to the git manual or "Progit". From this point of view, the debugging function of both is very strong.
•Repository information: Since the patch generated by git format-patch contains the name of the patch developer, this name will be recorded in the repository when the patch is applied. Obviously, this is appropriate. Therefore, the open source community currently using Git often recommends that you use format-patch to generate patches.
[size=medium]
[/size]

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327074929&siteId=291194637