Preface
In the process of participating in some open source projects, we often encounter problems such as loopholes, which require us to patch them. Especially Linux
source code, which has a large amount of source code. When the kernel is modified and a new kernel is released, it is basically released in the form of patches instead of packaging and releasing the entire kernel
There are many benefits to our use of patch releases
- The patch is small in size and easy for members to obtain.
- Patches are easy to save, and multiple versions of the kernel can be saved locally.
- It is easy and quick to use, just put the patch directly into the directory corresponding to the source code, and then execute the corresponding command.
Note: The blogger himself has not submitted a patch for Linux. This article is only a record of how to submit a patch for learning. I hope it will be helpful to everyone. Please do not complain.
If you know anyone about this, please feel free to share it in the comment area.
diff / patch
Generate patch
We take the classiclinux 0.11
version of the source code as an example. Suppose we have two source code folders in the current directory, and the unmodified source code folder islinux-0.11
, and the modified patch source codelinux-0.11-new
Note: linux 0.11 is an early Linux kernel version, released in 1991. It is quite old and is only for learning use, but it has no use value in engineering. The latest version of the kernel can be found in the source code library below
linux source code library:torvalds/linux: Linux kernel source tree (github.com)
linux 0.11 源码库:karottc/linux-0.11: the source code of linux-0.11 for study linux kernel (github.com)
We can pull two copies of linux 0.11
source code, keep one copy as is, make corresponding modifications to the other copy, and rename the folder to linux-0.11-new
Note: When I pull the source code here, I use the parameters
--exclude=.git
to exclude the .git folder to prevent interference from subsequent patches. If the git version is too low and does not have this function, you can clone it first and then delete the folder
git clone --exclude=.git [email protected]:karottc/linux-0.11.git
or
git clone [email protected]:karottc/linux-0.11.git
git clone [email protected]:karottc/linux-0.11.git ./linux-0.11-new
rm -rf linux-0.11/.git
rm -rf linux-0.11-new/.git
Then use the following diff
command to output the file differences between the original source code and the modified source code, and redirect the output to the linux.patch
patch file a>
sudo diff -uprN linux-0.11/ linux-0.11-new/ > linux.patch
Note:
.patch
is the common name of the patch file extension. Try to abide by the specifications. Otherwise, the name can be arbitrary
Parameter explanation:
-u
: Generates differential output in a unified format, usually used to generate patch files.-p
: Show more contextual information in the diff output for easier reading.-r
: Performs a recursive comparison of directories instead of just individual files.-N
: When the compared file is an empty file, the difference information is also displayed.
Use patches
We can execute the following patching command directly inthe current directory
patch -p0 < linux.patch
Note: The -p parameter represents which level of file path is ignored, 0 indicates that the full path is removed, and 1 indicates that the first level path is removed.
Or enterthe unmodified Linux source code root directory and execute the following patching command
patch -p1 < ../linux.patch
Note: Hereredirect symbol please be careful not to write it backwards. I wrote it backwards at first, and then the system will Stuck, no error will be reported, but it will not terminate either
I am simply using this as an example and only modified the README.md
file
Explain with examples -p
parameters, for example, the patch file fragment is as follows
--- old/modules/pcitable Mon Sep 27 11:03:56 1999
+++ new/modules/pcitable Tue Dec 19 20:05:41 2000
If you use the parameter-p0, it means to find a folder called old from the current directory, and then search under it file to perform patch operationmodules/pcitable
And if you use the parameter-p1, it means ignoring the first-level directory (that is, regardless of old) and searching from the current directory a>modules folder, and then look for pcitable under it
In the end we may have a conflict,usually because the original file has been modified, then we only need toManually resolve these conflicts, and thenexecute the patch again
Note: However, it is recommended that it is best not to modify the original code manually, otherwise it will be more troublesome to continue to modify it
Undo patch
We can execute the following command to undo the patch
patch -Rp0 < linux.patch
Or enter the unmodified source code root directory and execute the following command
patch -Rp1 < ../linux.patch
single file patch
The above is to patch the entire folder. The following will explain how to patch a single file.
Using separate files to apply patches in sequence can more effectively verify the correctness of the patch and facilitate subsequent functional testing
For example, if our current directory has the original file a.c
and the modified file b.c
, we can use the following command to generate the patch file
diff -u a.c b.c > test.patch
# 使用补丁
patch a.c < test.patch
# 撤销补丁
patch -RE < test.patch
quilt
Introduction
When we develop our own projects, we may only produce a large number of patches. Managing these large numbers of patches will be very time-consuming.
So linux kernel developerAndrew Morton developedquilt Patch managementTools to help us better manage patches
Official related documents
- quilt-doc.dvi (shakthimaan.com)
- Linux Kernel Configuration - Managing Your Patches With quilt (linuxtopia.org)
- quilt man | Linux Command Library
This chapter will briefly explain the quilt usage process. For more detailed information, you can view the official document above.
use
As long as we use the quilt command in the source code tree, quilt will create two special directories in the root directory of the source code tree: patches and .pc
The patches folder contains managed patch files.
Its internal working status is saved in the .pc folder
You can install it using the following command
sudo apt-get install quilt
Create a new patch file
quilt new xxx.patch
The patch file is associated with the modified file. After the association, the file can be modified.If you want to associate multiple files, add it repeatedly and then modify it. Yes
quilt add file
Check if the patch is correct
quilt diff
Save the patch, then the patch file will be saved inpatches
quilt refresh
git
git provides two patching solutions
- .diff file generated by git diff
- .patch file generated by git format-patch
The file generated by git diff does not contain commit information. You can specify a file to generate diff, or you can specify a single commit to generate multiple commits.
The .patch file generated by git format-patch contains commit information. One commit corresponds to one patch file.
Note: This chapter will briefly explain the git patch process. If you need more detailed documentation, the blogger will a> for your referenceA link to the official git website documentation is attached at the beginning of each chapter
git diff
Official documentation:Git - git-diff Documentation (git-scm.com)
The command to make a patch is as follows
# 单独文件补丁
git diff Test.java > test.patch
# 所有文件补丁
git diff > test.patch
Specification commit id
Production order
git diff [commit sha1 id] [commit sha1 id]> test.patch
git format-patch
Official documentation:Git - git-format-patch Documentation (git-scm.com)
Make a patch where the current branch is submitted before the specified branch
Note: The command example is to make a patch ahead of the master branch.
git format-patch -M master
Make a patch after a certain submission
git format-patch [commit id]
Patch between two commits
git format-patch [commit sha1 id]..[commit sha1 id]
Apply patch
Check patch file
git apply --stat xxx.patch
Check whether the application is successful
git apply --check xxx.patch
Use patches
git am --signoff < xxx.patch
However, the conflicts we mentioned above may occur, causing the patch to fail and the following error to appear.
$ git am PATCH
Applying: PACTH DESCRIPTION
error: patch failed: file.c:137
error: file.c: patch does not apply
error: patch failed: Makefile:24
error: libavfilter/Makefile: patch does not apply
Patch failed at 0001 PATCH DESCRIPTION
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".
resolve conflicts
Use the following command to automatically merge non-conflicting codes and retain the conflicting parts
After is executed, a file with the suffix .rej
will be generated to save the content that has not been merged. You can refer to this for conflict resolution
After resolving the conflict, delete the file with the suffix .rej and then submit the code to the source code library.
git apply --reject xxxx.patch
Reference link
- Linux kernel generation and patching methods - Zhihu (zhihu.com)
- Patching files/folders - Jianshu (jianshu.com)
- Linux diff command | Newbie tutorial (runoob.com)
- Linux patch command | Novice tutorial (runoob.com)
- Use the patch command to patch, and the diff command to create a patch - Tencent Cloud (tencent.com)
- Patching under Linux-Tencent Cloud Developer Community-Tencent Cloud (tencent.com)
- A first look at Quilt - using quilt to generate and manage patches
- Quilt patch making | Luobu (luobudiao.github.io)
- Submit your first patch to the Linux Kernel - HackMD