最新消息:

patch文件的结构 使用和制作patch文件

patch admin 4168浏览 0评论

创建补丁文件:

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
or
patch -p1 < 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。
第一个补丁头包含两个块,分别增加了两行和一行。

对某个版本的Linux内核做了修改以后,如果希望发布出去给别人用,那么就需要制作针对此版本的patch文件。
patch文件也叫补丁,就是一个文本文档,这个文档包含了在两个不同版本的源代码树之间的变化。
补丁是通过diff应用程序来创建的。
为了正确地打上一个补丁,你需要知道这个补丁是从哪个基础版本产生出来的以及这个补丁将要把
目前的源代码树变化到什么新的版本。这些信息或者会出现在补丁文件的原数据中,或者可能从文件名中推断出来。

1,如何制作补丁patch文件

比如基于kernel内核 做了修改,修改了LCD代码,修改前的内容放在文件夹kernel下,修改后的内容放在文件夹kernel_new下,那么制作patch文件的命令为
zhenwx-desktop:~/sourcecode/$diff -Naur kernel/    kernel_new/ > zwx-lcd.patch

当前目录为   /home/zhenwx/sourcecode/,该目录有原来修改前的内核kernel目录和修改后的目录kernel_new
执行命令为  diff -Naur kernel/    kernel_new/ > zwx-lcd.patch
diff命令就会对比kernel和kernel_new目录的文件,产生patch文件zwx-lcd.patch
这时就 可以把zwx-lcd.patch发布到网上。
这个patch文件是描述文件的路径信息和将第几行内容删除,在第几行添加内容,删除用减号,添加用加号

2,怎样打补丁patch和卸载补丁patch
可以使用patch程序来打一个补丁。patch程序读取一个diff(或者patch)文件,然后把文件中
描述的变化内容应用到代码树上。
Linux内核中的补丁是相对于保存内核源代码目录的父目录而生成的。
这就意味着:patch文件中的文件路径包含了它所基于的内核源文件目录的名字(或者像是”a/”和”b/”
之类的其它名字)。
由于这很可能和你本地机器上的内核源代码目录的名字不匹配。你应该切换到你的内核源代码目录,并且在打补丁的时候去掉patch
中文件名字路径的第一个分量(patch命令的-p1参数可以完成这个任务)。
为了卸载掉一个以前已经打上的补丁,使用-R参数来打补丁。
于是,如果你使用如下的命令来打补丁:
patch -p1

那么你可以像下面这样来卸载掉这个补丁:
patch -R -p1

例如其他人下载到上面提供的patch文件后,只需在标准的kernel内核目录里执行
zhenwx-desktop:~/sourcecode/kernel/$

patch -p1<../zwx-lcd.patch

这里假设zwx-lcd.patch和kernel文件夹是在同一目录下,且上述命令 在kernel文件夹内执行
如果在/sourcecode目录下面执行命令
zhenwx-desktop:~/sourcecode/$

patch -p0<../zwx-lcd.patch

linux下patch命令使用详解

linux打补丁命令

功能说明:修补文件。

语  法:patch [-bceEflnNRstTuvZ][-B <备份字首字符串>][-d <工作目录>][-D <标示符号>][-F <监别列数>][-g <控制数值>][-i <修补文件>][-o <输出文件>][-p <剥离层级>][-r <拒绝文件>][-V <备份方式>][-Y <备份字首字符串>][-z <备份字尾字符串>][–backup-if   -mismatch][–binary][–help][–nobackup-if-mismatch][–verbose][原始文件 <修补文件>] 或 path [-p <剥离层级>] < [修补文件]

补充说明:patch指令让用户利用设置修补文件的方式,修改,更新原始文件。倘若一次仅修改一个文件,可直接在指令列中下达指令依序执行。如果配合修补文件的方式则能一次修补大批文件,这也是Linux系统核心的升级方法之一。

参  数:
-b或–backup  备份每一个原始文件。
-B<备份字首字符串>或–prefix=<备份字首字符串>  设置文件备份时,附加在文件名称前面的字首字符串,该字符串可以是路径名称。
-c或–context  把修补数据解译成关联性的差异。
-d<工作目录>或–directory=<工作目录>  设置工作目录。
-D<标示符号>或–ifdef=<标示符号>  用指定的符号把改变的地方标示出来。
-e或–ed  把修补数据解译成ed指令可用的叙述文件。
-E或–remove-empty-files  若修补过后输出的文件其内容是一片空白,则移除该文件。
-f或–force  此参数的效果和指定-t参数类似,但会假设修补数据的版本为新 版本。
-F<监别列数>或–fuzz<监别列数>  设置监别列数的最大值。
-g<控制数值>或–get=<控制数值>  设置以RSC或SCCS控制修补作业。
-i<修补文件>或–input=<修补文件>  读取指定的修补问家你。
-l或–ignore-whitespace  忽略修补数据与输入数据的跳格,空格字符。
-n或–normal  把修补数据解译成一般性的差异。
-N或–forward  忽略修补的数据较原始文件的版本更旧,或该版本的修补数据已使 用过。
-o<输出文件>或–output=<输出文件>  设置输出文件的名称,修补过的文件会以该名称存放。
-p<剥离层级>或–strip=<剥离层级>  设置欲剥离几层路径名称。
-f<拒绝文件>或–reject-file=<拒绝文件>  设置保存拒绝修补相关信息的文件名称,预设的文件名称为.rej。
-R或–reverse  假设修补数据是由新旧文件交换位置而产生。
-s或–quiet或–silent  不显示指令执行过程,除非发生错误。
-t或–batch  自动略过错误,不询问任何问题。
-T或–set-time  此参数的效果和指定-Z参数类似,但以本地时间为主。
-u或–unified  把修补数据解译成一致化的差异。
-v或–version  显示版本信息。
-V<备份方式>或–version-control=<备份方式>  用-b参数备份目标文件后,备份文件的字尾会被加上一个备份字符串,这个字符串不仅可用-z参数变更,当使用-V参数指定不同备份方式时,也会产生不同字尾的备份字符串。
-Y<备份字首字符串>或–basename-prefix=–<备份字首字符串>  设置文件备份时,附加在文件基本名称开头的字首字符串。
-z<备份字尾字符串>或–suffix=<备份字尾字符串>  此参数的效果和指定-B参数类似,差别在于修补作业使用的路径与文件名若为src/linux/fs/super.c,加上backup/字符串后,文件super.c会备份于/src/linux/fs/backup目录里。
-Z或–set-utc  把修补过的文件更改,存取时间设为UTC。
–backup-if-mismatch  在修补数据不完全吻合,且没有刻意指定要备份文件时,才备份文件。
–binary  以二进制模式读写数据,而不通过标准输出设备。
–help  在线帮助。
–nobackup-if-mismatch  在修补数据不完全吻合,且没有刻意指定要备份文件时,不要备份文件。
–verbose  详细显示指令的执行过程。

patch,是打补丁的命令,有很多用法,见帮助#man patch
-p参数决定了是否使用读出的源文件名的前缀目录信息,不提供-p参数,则忽略所有目录信息,
patch -p0       (“p”指的是路径,后面的数字表示去掉路径的第几部分。0,表示不去掉,为全路径)
patch -p1       (“p”后面的数字1,表示去掉前第一个路径,第一个”/”以前的目录,依此类推。
如/usr/src/linux-2.6.11/Makefile这样的文件名,在提供-p3参数时将使用linux-2.6.11/Makefile作为所要patch的文件。

对于刚才举的Linux内核源码LCD升级包的例子,假定源码目录位于/home/zhenwx/sourcecode/kernel中,
则在当前目录为/home/zhenwx/sourcecode/时使用”patch -p0<../zwx-lcd.patch”可以工作,
在当前目录为/home/zhenwx/sourcecode/kernel时,使用”patch -p1<../zwx-lcd.patch”也可以正常工作。

如果patch文件里面描述的第一级目录和你自己的第一级目录名字不一样,要将第一级的目录去掉,这个方法就派上用场了。

比如如果你拿到的patch描述的目录和你的不一样,patch第一行描述的目录信息

diff —Git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c

但是你的目录既不是a,也不是b,那么你就要将目录的第一层去掉,到你的kernel的路径下面打patch

用-p1参数

转载请注明:爱开源 » patch文件的结构 使用和制作patch文件

您必须 登录 才能发表评论!