[技术] patch 打补丁程序和 diff

May 27th, 2010

转载本站文章请注明,转载自:扶凯[http://www.php-oa.com]

本文链接: http://www.php-oa.com/2010/05/27/linux-patch-diff.html

patch 来打补丁很常用,表面看和 diff 是没有关系 的,但其它 patch 是离不开 diff 的,因为通常 patch 都使用 diff 的结果来完成打补丁的工作,在 patch 时,是这样工作的.
patch 通过读入 patch 文件对目标文件进行修改.所以需要先用 diff 命令来比较新老版本的差异,patch 命令会使用 diff 的输出文件,从而保持原版本与新版本一致.其它很多软件都是基于 diff 来开发的,比如 svn ,每次更新会产生一个 diff 的文件的.
 

diff 来生成 patch 文件
 

我们先看怎么使用 diff 来生成 patch 文件.我们知道 diff 不论是对于单个文件还是整个源码目录,使用diff都很简单.

(1. 单个文件创建补丁
用下面形式:
diff [选项] 源文件 目标文件  

diff -u original.pl new.pl > original.patch

(2. 为整个项目源码树创建补丁
先要有二个文件树,我们先复制一份源码树:

cp -R original new

在目录 new/ 里进行必要的修改,然后用下面的命令创建补丁:

diff -rupN original/ new/ > original.patch

下面看个 diff 的例子
 有二个文件, original.pl new.pl  注意文件内部的分别

[root@develop test]# cat original.pl new.pl
#!/usr/bin/perl
1
2
3
4
5
6

#!/usr/bin/perl
1
2

3
4
6

然后 diff 对比

[root@develop test]# diff -u original.pl  new.pl
--- original.pl 2010-05-27 10:20:23.000000000 +0800
+++ new.pl      2010-05-27 10:20:51.000000000 +0800
@@ -1,8 +1,8 @@
 #!/usr/bin/perl
 1
 2
+
 3
 4
-5
 6

很显示的可以看到 + 和 – 来表示二个文件的差异. -u 主要是指定使用标准统一的输出格式.

 

 

 

patch 命令应用补丁

(1. 单个文件应用补丁

进入文件所在的目录并调用 patch 命令:

patch < original.patch

这个命令需要源文件指定了参数  -u ,也就是讲,是使用了标准统一的输出格式.不然在 < 内需要指定文件名
这些命令假定补丁是以统一格式分发的,这种格式指明了补丁要应用到的文件.如果不是,你可以在命令行里指定文件:

patch new.pl < original.patch

(2  应用补丁到整个项目

这个有个不同的地放,是你必须注意设置 p 参数.在补丁文件里,需要打补丁的文件在你电脑上的路径名跟在创建补丁的电脑上不同.p 告诉 patch 命令忽略掉路径名的几个部分以正确的识别文件.通常p级别为1就够了,所以你使用:

patch -p1 < original.patch

对于从路径最开始删除的每个路径分隔符(斜线字符)加一,直到剩下的部分存在于你的工作目录中.最后得到的就是p级别.

要删除补丁,用-R参数,例如:

patch -p5 -R original.patch

 

 

备注: Diff 的其它参数

选项
下面是 GNU所接受的 diff 的所有选项的概要. 大多数的选项有两个相同的名字,一个是单个的跟在 - 后面字母, 另一个是由 引出的长名字. 多个单字母选项(除非它们产生歧义)能够组合为单行的命令行语法 -ac 是等同于 -a -c. 长命名的选项能被缩短到他们的名字的任何唯一的前缀. 用 ([]) 括起来显示选项产生歧义的选项
-行数(一个整数)
显示上下文 行数 (一个整数). 这个选项自身没有指定输出格式,这是没有效果的,除非和 -c 或者 -u 组合使用. 这是已废置的选项,对于正确的操作, 上下文至少要有两行.
-a
所有的文件都视为文本文件来逐行比较,甚至他们似乎不是文本文件.
-b
忽略空格引起的变化.
-B
忽略插入删除空行引起的变化.
–brief
仅报告文件是否相异,在乎差别的细节.
-c
使用上下文输出格式.
-C 行数(一个整数)
–context[=lines]
使用上下文输出格式,显示以指定 行数 (一个整数), 或者是三行(当 行数 没有给出时. 对于正确的操作, 上下文至少要有两行.
–changed-group-format=format
使用 format 输出一组包含两个文件的不同处的行,其格式是 if-then-else .
-d
改变算法也许发现变化的一个更小的集合.这会使 diff 变慢 (有时更慢).
-D name
合并 if-then-else 格式输出, 预处理宏(由name参数提供)条件.
-e
–ed
输出为一个有效的 ed 脚本.
–exclude=pattern
比较目录的时候,忽略和目录中与 pattern(样式) 相配的.
–exclude-from=file
比较目录的时候,忽略和目录中与任何包含在 file(文件) 的样式相配的文件和目录.
–expand-tabs
在输出时扩展tab为空格,保护输入文件的tab对齐方式
-f
产生一个很象 ed 脚本的输出,但是但是在他们在文件出现的顺序有改变
-F regexp
在上下文和统一格式中,对于每一大块的不同,显示出匹配 regexp. 的一些前面的行.
–forward-ed
产生象 ed 脚本的输出,但是它们在文件出现的顺序有改变.
-h
这选项现在已没作用,它呈现Unix的兼容性.
-H
使用启发规则加速操作那些有许多离散的小差异的大文件.
–horizon-lines=lines
比较给定行数的有共同前缀的最后行,和有共同或缀的最前行.
-i
忽略大小写.
-I regexp
忽略由插入,删除行(由regexp 参数提供参考)带来的改变.
–ifdef=name
合并 if-then-else 格式输出, 预处理宏(由name参数提供)条件.
–ignore-all-space
在比较行的时候忽略空白.
–ignore-blank-lines
忽略插入和删除空行
–ignore-case
忽略大小写.
–ignore-matching-lines=regexp
忽略插入删除行(由regexp 参数提供参考).
–ignore-space-change
忽略空白的数量.
–initial-tab
在文本行(无论是常规的或者格式化的前后文关系)前输出tab代替空格. 引起的原因是tab对齐方式看上去象是常规的一样.
-l
产生通过 pr 编码的输出.
-L label
–label=label
使用 label 给出的字符在文件头代替文件名输出.
–left-column
以并列方式印出两公共行的左边
–line-format=format
使用 format 输出所有的行,在 if-then-else 格式中.
–minimal
改变算法也许发现变化的一个更小的集合.这会使 diff 变慢 (有时更慢).
-n
输出 RC-格式 diffs; 除了每条指令指定的行数受影响外 象 -f 一样.
-N
–new-file
在目录比较中,如果那个文件只在其中的一个目录中找到,那么它被视为在另一个目录中是一个空文件.
–new-group-format=format
使用 format 以if-then-else 格式输出只在第二个文件中取出的一个行组
–new-line-format=format
使用 format 以if-then-else 格式输出只在第二个文件中取出的一行
–old-group-format=format
使用 format 以if-then-else 格式输出只在第一个文件中取出的一个行组
–old-line-format=format
使用 format 使用 format 以if-then-else 格式输出只在第一个文件中取出的一行
-p
显示带有c函数的改变.
-P
在目录比较中,如果那个文件只在其中的一个目录中找到,那么它被视为在另一个目录中是一个空文件.
–paginate
产生通过 pr 编码的输出.
-q
仅报告文件是否相异,不报告详细的差异.
-r
当比较目录时,递归比较任何找到的子目录.
–rcs
输出 RC-格式 diffs; 除了每条指令指定的行数受影响外 象 -f 一样.
–recursive
当比较目录时,递归比较任何找到的子目录.
–report-identical-files
-s
报告两个文件相同.
-S file
当比较目录时,由 file 开始. 这用于继续中断了的比较.
–sdiff-merge-assist
打印附加的信息去帮助 sdiff. sdiff 在运行 diff 时使用这些选项. 这些选项不是特意为使用者直接使用而准备的.
–show-c-function
显示带有c函数的改变.
–show-function-line=regexp
在上下文和统一的格式,对于每一大块的差别,显示出匹配 regexp. 的一些前面的行
–side-by-side
使用并列的输出格式.
–speed-large-files
使用启发规则加速操作那些有许多离散的小差异的大文件.
–starting-file=file
当比较目录时,由 file 开始. 这用于继续中断了的比较.
–suppress-common-lines
在并列格式中不印出公共行.
-t
在输出时扩展tab为空格,保护输入文件的tab对齐方式
-T
在文本行(无论是常规的或者格式化的前后文关系)前输出tab代替空格.引起的原因是tab对齐方式看上去象是常规的一样.
–text
所有的文件都视为文本文件来逐行比较,甚至他们似乎不是文本文件.
-u
使用统一的输出格式.
–unchanged-group-format=format
使用 format 输出两个文件的公共行组,其格式是if-then-else.
–unchanged-line-format=format
使用 format 输出两个文件的公共行,其格式是if-then-else.
–unidirectional-new-file
在目录比较中,如果那个文件只在其中的一个目录中找到,那么它被视为在另一个目录中是一个空文件.
-U lines
–unified[=lines]
使用前后关系格式输出,显示以指定 行数 (一个整数), 或者是三行(当 行数 没有给出时. 对于正确的操作, 上下文至少要有两行.
-v
–version
输出 diff 版本号.
-w
在比较行时忽略空格
-W columns
–width=columns
在并列格式输出时,使用指定的列宽.
-x pattern
比较目录的时候,忽略和目录中与 pattern(样式) 相配的.
-X file
比较目录的时候,忽略和目录中与任何包含在 file(文件) 的样式相配的文件和目录.
-y
使用并列格式输出

 

Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪 ViVi 365Key 网摘 天极网摘 和讯网摘 博拉网 POCO 网摘 饭否 QQ 书签 Digbuzz 我挖网 Mister Wong
Tags: , ,
No comments yet.