Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2554150
  • 博文数量: 709
  • 博客积分: 12251
  • 博客等级: 上将
  • 技术积分: 7905
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-17 00:00
个人简介

实现有价值的IT服务

文章存档

2012年(7)

2011年(147)

2009年(3)

2008年(5)

2007年(74)

2006年(431)

2005年(42)

分类: LINUX

2006-06-05 17:24:54

How to create and use a patch in Linux
Updated March 17, 2003
Created November 19, 2001


Creating a Patch File:

diff -Naur olddir newdir > new-patch
- or -
diff -Naur oldfile newfile >new-patch

A Note concerning Patch and the number of Directory Levels used:

Try to make sure when creating a patchfile that you have the same number of directories levels for both the olddir path and newdir path. For Ex:
--- old/modules/pcitable	Mon Sep 27 11:03:56 1999
+++ new/modules/pcitable	Tue Dec 19 20:05:41 2000
The above diff would work ok as a patch.
--- old/try1/other/modules/pcitable	Mon Sep 27 11:03:56 1999
+++ new/modules/pcitable	Tue Dec 19 20:05:41 2000
You may have problems with the above diff working as a patch. Note that the first one has 4 directory levels mentioned and the 2nd one has only two. I would suggest modifying the --- and +++ lines to make the directory structure in both to be the same number of levels deep.

Using the Patch Command:

patch -p0 Which one of the above patch commands you use depends on your current working directory.
Other Methods for calling the patch command - using standard input of patch:
cat new-patch | patch -p0
Other methods for calling the patch command - using a "here document":
patch -p0 << EOF
--- old/modules/pcitable	Mon Sep 27 11:03:56 1999
+++ new/modules/pcitable	Tue Dec 19 20:05:41 2000
@@ -1,4 +1,6 @@
 0x0e11	0xae10	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
+0x1000	0x0010	"cpqarray"	"Compaq|Integrated Array Controller"
+0x1011	0x0046	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae32	"tlan"	"Compaq|Netelligent 10/100"
 0x0e11	0xae34	"tlan"	"Compaq|Netelligent 10"
 0x0e11	0xae35	"tlan"	"Compaq|Integrated NetFlex-3/P"
@@ -21,6 +23,7 @@
 0x1000	0x000f	"ncr53c8xx"	"Symbios|53c875"
 0x1000	0x0012	"ncr53c8xx"	"Symbios|53c895a"
 0x1000	0x008f	"ncr53c8xx"	"Symbios|53c875J"
+0x1000	0x000a	"sym53c8xx"	"Symbios|53c1510"
 0x1000	0x0701	"yellowfin"	"Symbios|83C885 gigabit ethernet"
 0x1000	0x0702	"yellowfin"	"Symbios|Yellowfin G-NIC gigabit ethernet"
 0x1011	0x0001	"tulip"	"DEC|DECchip 21050"
--- old/usr/share/kudzu/pcitable	Sun Sep 26 17:11:23 1999
+++ new/usr/share/kudzu/pcitable	Tue Dec 19 20:05:41 2000
@@ -15,6 +15,8 @@
 0x0e11	0x3034	"unknown"	"Compaq|QVision 1280/p"
 0x0e11	0x4000	"unknown"	"Compaq|4000 [Triflex]"
 0x0e11	0xa0f3	"ignore"	"Compaq|Triflex PCI to ISA Bridge"
+0x1000	0x0010	"cpqarray"	"Compaq|Integrated Array Controller"
+0x1011	0x0046	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae10	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae29	"unknown"	"Compaq|MIS-L"
 0x0e11	0xae2a	"unknown"	"Compaq|MPC"
@@ -46,6 +48,7 @@
 0x1000	0x000f	"ncr53c8xx"	"Symbios|53c875"
 0x1000	0x0012	"ncr53c8xx"	"Symbios|53c895a"
 0x1000	0x008f	"ncr53c8xx"	"Symbios|53c875J"
+0x1000	0x000a	"sym53c8xx"	"Symbios|53c1510"
 0x1000	0x0701	"yellowfin"	"Symbios|83C885 gigabit ethernet"
 0x1000	0x0702	"yellowfin"	"Symbios|Yellowfin G-NIC gigabit ethernet"
 0x1000	0x0901	"unknown"	"Symbios|61C102"
EOF
For the "here document", patch will read all the following lines, up until it reaches the delimeter that we specified after the << symbol. The delimeter we choose must appear at the beginning of a line, and must appear alone. In our case we are using the delimeter EOF. EOF has no special meaning, other than the fact that it is not likely that we would have a reason to type EOF at the beginning of any given line.

For more information on here documents click here:
heredoc.html

Levels in the Patch Command (-p0 or -p1?):

The -p option will optionally strip off directory levels from the patchfile. For Ex: if you have a patchfile with a header as such:
--- old/modules/pcitable	Mon Sep 27 11:03:56 1999
+++ new/modules/pcitable	Tue Dec 19 20:05:41 2000
Using a -p0 will expect, from your current working directory, to find a subdirectory called "new", then "modules" below that, then the "pcitable" file below that.

Using a -p1 will strip off the 1st level from the path and will expect to find (from your current working directory) a directory called "modules", then a file called "pcitable". Patch will ignore the "new" directory mentioned in the header of the patchfile.

Using a -p2 will strip of the first two levels from the path. Patch will expect to find "pcitable" in the current working directory. Patch will ignore the "new" and "modules" directories mentioned in the header of the patchfile.

Using a -p3 in this example would not be a good thing. Patch probably wouldn't patch anything.

...

Applying a Patch:

Just change to the correct directory and give the patch command (see above). Usually is:
cd /usr/src/linux
patch -p0 unless the patchfile has "linux" as part of the directory structure on the +++ line, in that case issue the patch command with the -p1 as follows: 
patch -p1 

Patch Header:

In these examples a patch header begins with the two lines that begin with a --- and +++. This would indicate which filename to begin processing.

Multiple Patches in a Patchfile:

A patchfile can have multiple sections, each beginning with the --- / +++ headers mentioned above. So a single patchfile can actually modify several files. If you are reviewing a patchfile be sure to search for every instance of --- throughout the patchfile to see all the different files it patches.

An Example of one method to browse a patchfile:

less /tmp/file-patch 
/--- 
n
n
n
Note that the "/" invokes the search function in less, and each time you press "n" less will search for the next matching searchstring.

Hunks:

A hunk is a section to be patched. A hunk usually begins and ends with lines that don't need any changes, they are just mentioned so that Patch can find the appropriate place in the files to be patched. Hunk in these examples begins with a double at symbol (@@) and ends when either a new hunk starts or it finds a new patch header. Here's an example of a hunk:
@@ -1,4 +1,6 @@
 0x0e11	0xae10	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
+0x1000	0x0010	"cpqarray"	"Compaq|Integrated Array Controller"
+0x1011	0x0046	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae32	"tlan"	"Compaq|Netelligent 10/100"
 0x0e11	0xae34	"tlan"	"Compaq|Netelligent 10"
 0x0e11	0xae35	"tlan"	"Compaq|Integrated NetFlex-3/P"

Indentation in a Hunk:

In these examples you will notice that each hunk has been indented so that the text does not occupy the first column. In these examples Patch uses the first column in each patch to list the lines to be added or removed.

The First Column of a Hunk (+, -, and a blank):

The + would indicate that this particular line is to be added.

The - would indicate that this particular line is to be removed.

A line with neither a plus or minus would indicate that this particular line of code is just a reference point.

An Example Patchfile:

diff -u old/modules/pcitable new/modules/pcitable
--- old/modules/pcitable	Mon Sep 27 11:03:56 1999
+++ new/modules/pcitable	Tue Dec 19 20:05:41 2000
@@ -1,4 +1,6 @@
 0x0e11	0xae10	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
+0x1000	0x0010	"cpqarray"	"Compaq|Integrated Array Controller"
+0x1011	0x0046	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae32	"tlan"	"Compaq|Netelligent 10/100"
 0x0e11	0xae34	"tlan"	"Compaq|Netelligent 10"
 0x0e11	0xae35	"tlan"	"Compaq|Integrated NetFlex-3/P"
@@ -21,6 +23,7 @@
 0x1000	0x000f	"ncr53c8xx"	"Symbios|53c875"
 0x1000	0x0012	"ncr53c8xx"	"Symbios|53c895a"
 0x1000	0x008f	"ncr53c8xx"	"Symbios|53c875J"
+0x1000	0x000a	"sym53c8xx"	"Symbios|53c1510"
 0x1000	0x0701	"yellowfin"	"Symbios|83C885 gigabit ethernet"
 0x1000	0x0702	"yellowfin"	"Symbios|Yellowfin G-NIC gigabit ethernet"
 0x1011	0x0001	"tulip"	"DEC|DECchip 21050"
--- old/usr/share/kudzu/pcitable	Sun Sep 26 17:11:23 1999
+++ new/usr/share/kudzu/pcitable	Tue Dec 19 20:05:41 2000
@@ -15,6 +15,8 @@
 0x0e11	0x3034	"unknown"	"Compaq|QVision 1280/p"
 0x0e11	0x4000	"unknown"	"Compaq|4000 [Triflex]"
 0x0e11	0xa0f3	"ignore"	"Compaq|Triflex PCI to ISA Bridge"
+0x1000	0x0010	"cpqarray"	"Compaq|Integrated Array Controller"
+0x1011	0x0046	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae10	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae29	"unknown"	"Compaq|MIS-L"
 0x0e11	0xae2a	"unknown"	"Compaq|MPC"
@@ -46,6 +48,7 @@
 0x1000	0x000f	"ncr53c8xx"	"Symbios|53c875"
 0x1000	0x0012	"ncr53c8xx"	"Symbios|53c895a"
 0x1000	0x008f	"ncr53c8xx"	"Symbios|53c875J"
+0x1000	0x000a	"sym53c8xx"	"Symbios|53c1510"
 0x1000	0x0701	"yellowfin"	"Symbios|83C885 gigabit ethernet"
 0x1000	0x0702	"yellowfin"	"Symbios|Yellowfin G-NIC gigabit ethernet"
 0x1000	0x0901	"unknown"	"Symbios|61C102"

Analyzing the above Example:

This example was created using the following diff command:
diff -u old/modules/pcitable new/modules/pcitable
However, now I would probably only use the -Naur options instead of just -u. This example modifies two files: new/modules/pcitable, and new/usr/share/kudzu/pcitable.

The first patch header has two hunks. These particular hunks are adding 2 lines and 1 line respectively
 

如何创建和使用Linux中的patch

, ,

创建补丁文件:
diff -Naur 旧的目录 新的目录 > patch文件
或者
diff -Naur 旧的文件 新的文件 > patch文件


对于目录层数的一些限制


在创建patch的时候文件夹的层数应当是一样的,比如
--- old/modules/pcitableMon Sep 27 11:03:56 1999
+++ new/modules/pcitableTue Dec 19 20:05:41 2000

这样是可以的。

--- old/try1/other/modules/pcitableMon Sep 27 11:03:56 1999
+++ new/modules/pcitableTue Dec 19 20:05:41 2000

这样做可能会有一些问题。

如何使用patch
对于一个patch文件,有两种常用使用方法:
1.
cat new-patch | patch -p0

2.
patch -p0 < new-patch


patch命令里面的层数(-p0?-p1?)
参数-p来指定从第几层开始比较。比如有一个patch文件的补丁头是这样的:
--- old/modules/pcitableMon Sep 27 11:03:56 1999
+++ new/modules/pcitableTue Dec 19 20:05:41 2000

如果使用参数-p0,就表示从当前目录,找一个叫作new的目录,在它下面找一个叫modules的目录,再在它下面找一个叫pcitableMon的目录。
如果使用参数-p1,就表示忽略第一层,从当前目录找一个叫modules的目录,在它下面找一个叫modules的目录。这样会忽略掉补丁头提到的new目录。
依此类推。

patch文件的结构
补丁头
补丁头是分别由---/+++开头的两行,用来表示要打补丁的文件。
一个补丁文件中的多个补丁
一个补丁文件中可能包含以---/+++开头的很多节,每一节用来打一个补丁。所以在一个补丁文件中可以包含好多个补丁。

块是补丁中要修改的地方。它通常由一部分不用修改的东西开始和结束。他们只是用来表示要修改的位置。他们通常以@@开始,结束于另一个块的开始或者一个新的补丁头。
块的缩进
块会缩进一列,而这一列是用来表示这一行是要增加还是要删除的。
块的第一列
+号表示这一行是要加上的。
-号表示这一行是要删除的。
没有加号也没有减号表示这里只是引用的而不需要修改。

一个patch的例子

diff -u old/modules/pcitable new/modules/pcitable
--- old/modules/pcitableMon Sep 27 11:03:56 1999
+++ new/modules/pcitableTue Dec 19 20:05:41 2000
@@ -1,4 +1,6 @@
 0x0e110xae10"cpqarray""Compaq|Smart-2/P RAID Controller"
+0x10000x0010"cpqarray""Compaq|Integrated Array Controller"
+0x10110x0046"cpqarray""Compaq|Smart-2/P RAID Controller"
 0x0e110xae32"tlan""Compaq|Netelligent 10/100"
 0x0e110xae34"tlan""Compaq|Netelligent 10"
 0x0e110xae35"tlan""Compaq|Integrated NetFlex-3/P"
@@ -21,6 +23,7 @@
 0x10000x000f"ncr53c8xx""Symbios|53c875"
 0x10000x0012"ncr53c8xx""Symbios|53c895a"
 0x10000x008f"ncr53c8xx""Symbios|53c875J"
+0x10000x000a"sym53c8xx""Symbios|53c1510"
 0x10000x0701"yellowfin""Symbios|83C885 gigabit ethernet"
 0x10000x0702"yellowfin""Symbios|Yellowfin G-NIC gigabit ethernet"
 0x10110x0001"tulip""DEC|DECchip 21050"
--- old/usr/share/kudzu/pcitableSun Sep 26 17:11:23 1999
+++ new/usr/share/kudzu/pcitableTue Dec 19 20:05:41 2000
@@ -15,6 +15,8 @@
 0x0e110x3034"unknown""Compaq|QVision 1280/p"
 0x0e110x4000"unknown""Compaq|4000 [Triflex]"
 0x0e110xa0f3"ignore""Compaq|Triflex PCI to ISA Bridge"
+0x10000x0010"cpqarray""Compaq|Integrated Array Controller"
+0x10110x0046"cpqarray""Compaq|Smart-2/P RAID Controller"
 0x0e110xae10"cpqarray""Compaq|Smart-2/P RAID Controller"
 0x0e110xae29"unknown""Compaq|MIS-L"
 0x0e110xae2a"unknown""Compaq|MPC"
@@ -46,6 +48,7 @@
 0x10000x000f"ncr53c8xx""Symbios|53c875"
 0x10000x0012"ncr53c8xx""Symbios|53c895a"
 0x10000x008f"ncr53c8xx""Symbios|53c875J"
+0x10000x000a"sym53c8xx""Symbios|53c1510"
 0x10000x0701"yellowfin""Symbios|83C885 gigabit ethernet"
 0x10000x0702"yellowfin""Symbios|Yellowfin G-NIC gigabit ethernet"
 0x10000x0901"unknown""Symbios|61C102"


分析
这个例子是由命令
diff -u old/modules/pcitable new/modules/pcitable

创建的。不过最好是用命令diff -Naur来代替diff -u。
它修改了两个文件,new/modules/pcitable和new/usr/share/kudzu/pcitable。
第一个补丁头包含两个块,分别增加了两行和一行。





这个是参考了这篇文章来总结翻译。由于刚刚接触这些东西,很多地方可能翻译的不恰当,尤其是一些术语,如有发现问题,请给我留言说明,以便我来改正,谢谢。
阅读(1109) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~