As a programmer, it is necessary to understand diff & patch command. For example, if we find that a project has a bug code, and we do not have the svn submission permission, the most appropriate solution is to use the diff command to make a patch and send it to the project members. Project Members can immediately learn your intentions through the patch command. Some people may say that it is easier to directly upload a new file? Do not forget that the size of a patch file is smaller and faster, and you can clearly see what changes have been made.
Make sure that the current directory is the demo directory:
# Mkdir demo
# Cd demo
First simulate a project directory old:
# Mkdir-P old/a/B
# Vi old/a/B/foo.txt
Old_line_1
Old_line_2
Suppose we find that the project old has a bug code. Next we will copy a new directory new and modify the bug code here:
# Cp-r old New
# Vi new/a/B/foo.txt
New_line_1
New_line_2
Make sure that both the old and new directories are in the current directory. You can use the diff command below. Do not use absolute paths, but use relative paths. As for the reason, you will be clear at the end of the article:
# Lc_all = c tz = utc0 diff-Naur old New> Foo. Patch
If you do not care about character sets or time differences, you can also omit the lc_all = c tz = utc0 environment variable:
# Diff-Naur old New> Foo. Patch
Among them, the-Naur parameter is a fixed strategy. Whether it is a file or a directory, you can use this parameter.
Take a look at the patch file:
# Cat Foo. Patch
Diff-Naur old/a/B/foo.txt new/a/B/foo.txt
--- Old/a/B/foo.txt 2009-12-07 20:40:07. 000000000 + 0800
++ New/a/B/foo.txt 20:41:51. 000000000 + 0800
@-1, 2 + 1, 2 @@
-Old_line_1
-Old_line_2
+ New_line_1
+ New_line_2
The content after the plus or minus sign is useful. Other content is the relevant information that you can easily check and complete patch preparation.
The file directory structure is roughly as follows:
# Tree
Demo
| -- Old
| '--
| '-- B
| '-- Foo.txt
| -- New
| '--
| '-- B
| '-- Foo.txt
'-- Foo. Patch
Next let's take a look at how to use patch to apply patches. Note that the current directory is demo. Try the following command:
# Patch-P0 <Foo. Patch
Patching file old/a/B/foo.txt
The only thing to note here is the meaning of P0, because the path information in the foo. Patch patch file is as follows:
--- Old/a/B/foo.txt
P indicates skipping several levels of directories. Because the patch command is used in the demo directory, the old directory is under the demo directory, so you do not have to skip any directories, the full path of old/a/B/foo.txt should be used, so P0 is used at this time.
Check the target file and you will find that the content has been changed to a new one:
# Cat old/a/B/foo.txt
New_line_1
New_line_2
If you use the patch command again, the system will ask you if you want to restore it:
# Patch-P0 <Foo. Patch
Patching file old/a/B/foo.txt
Reversed (or previusly applied) patch detected! Assume-r? [N] y
Check the target file and you will find that the content has been restored to the old one:
# Cat old/a/B/foo.txt
Old_line_1
Old_line_2
If you want to strictly specify the application patch, use the following command (that is, add the N parameter ):
# Patch-np0 <Foo. Patch
If you want to strictly specify a restoration patch, use the following command (that is, add the R parameter ):
# Patch-Rp0 <Foo. Patch
Note: In this example, after each patch is applied, you can restore the patch by yourself for further testing.
If you are not clear about the p parameter of the patch, let's change the current path:
# Cd old
In this case, it should be P1, not P0. The path to reference the foo. patch file should also be changed, because the current directory is already old:
# Patch-P1 <../Foo. Patch
Patching file a/B/foo.txt
At this time, we use the patch command under old, which is at the same level as sub-directory A. The path declaration in the patch file Foo. Patch is:
--- Old/a/B/foo.txt
That is to say, the old/part on the left of the first diagonal line is useless. This is the meaning of P1!
Continue to change the path to the depth, and test the P2 and P3 parameters in sequence:
# CD
# Patch-P2 <.../../Foo. Patch
Patching file B/foo.txt
# Cd B
# Patch-P3 <.../Foo. Patch
Patching file foo.txt
In this example, P3 is already the deepest directory. You can omit the p parameter:
# Patch <../Foo. Patch
Patching file foo.txt
That is to say, when the p parameter is not used, the patch command will ignore any directory and directly use the file.
Next, the article above explains why it is best to use relative paths instead of absolute paths when using the diff command?
A: If you use an absolute path when using diff, the file path information in the patch file will look like the following:
---/A/B/C/D/E/F/G/bar.txt
As a result, when someone else wants to apply your patch, the directory structure must be different, so they have to make efforts to determine whether to use p. In this way, errors are very easy. On the contrary, if relative paths are used, most of the time, P0 or P1 is enough, and errors are not easy.
Follow the steps in this article to learn about diff & patch usage. Basically, diff is a fixed strategy like "Diff-Naur from to" (from, to is a variable, then, when using the patch, first look at the general content of the patch file, combined with the current directory to determine the number of directories to be skipped, and then apply "patch-PN <patch. file "(N is a variable.
-------------------
Summary:
Single file
Diff-UN from-file to-File> to-file.patch
Patch-P0 <to-file.patch
Patch-re-P0 <to-file.patch
Multiple files
Diff-unr from-docu to-docu> to-docu.patch
Patch-P1 <to-docu.patch
Patch-r-p1
-------------------
Application
Patch the kernel. When creating a cross-compilation toolchain, one step is to patch the kernel. At that time, I was not very familiar with it, but now it is clear. Refer to the previous article "establishing a development tool chain based on ARM + LINUX embedded development".
1. decompress the package because the released patch files are compressed using gzip.
$ Gunzip ../setup-DIR/patch-2.4.21-rmk1.gz
2. Enter your kernel source code directory.
$ Linux-2.4.21 CD
3. Patch
$ Patch-P1 <.../../setup-DIR/patch-2.4.21-rmk1
After the patch is installed, check whether the file is rejected, that is, check the existence of the. rej file. Run the following command:
$ Find.-Name *. rej
If it is found, it will be output to the standard output terminal, the default screen. Of course, you can also use redirection to output to a specified file, such as reject.
$ Fine.-Name *. rej> reject
Then you can view the reject content.