diff和patch的使用一二

不重新整理一下,都快忘了,趁这个机会也贴上来吧。

 

diff

diff是生成源码补丁的必备工具。其命令格式为:

 diff [命令行选项] 原始文件 新文件

常用命令行选项如下:

   -r 递归处理目录     -u 输出统一格式(unified format)

   -N patch里包含新文件   -a patch里可以包含二进制文件

  它的输出在stdout上,所以你可能需要把它重定向到一个文件。diff的输出有“传统格式”和“统一格式”之分,现在大都使用统一格式:

  传统格式示例:

   [hahalee@builder]$ diff a.txt b.txt

   1a2

   > here we insert a new line

   3d3

   < why not this third line?

  统一格式示例:

   [hahalee@builder]$ diff -u a.txt b.txt

   --- a.txt Thu Apr 6 15:58:34 2000

   +++ b.txt Thu Apr 6 15:57:53 2000

   @@ -1,3 +1,3 @@

   This is line one

   +here we insert a new line

   and this is line two

   -why not this third line?

  通过比较可以看出,传统格式的patch文件比较小,除了要删除/插入的行外没有冗余信息。统一格式则保存了上下文(缺省是上下各三行,最少需要两行),这样,patch的时候可以允许行号不精确匹配的情况出现。另外,在patch文件的开头明确地用---和+++标示出原始文件和当前文件,也方便阅读。要选用统一格式,用u 开关。

  通常,我们需要对整个软件包做修改,并生成一个patch文件,下面是典型的操作过程。这里就要用到前面介绍的几个命令行开关了:

  tar xzvf software.tar.gz # 展开原始软件包,其目录为software

  cp _a software software-orig # 做个修改前的备份

  cd software

  [修改,测试……]

  cd ..

  diff _ruNa software-orig software > software-my.patch

  现在我们就可以保存software-my.patch做为这次修改的结果,至于原始软件包,可以不必保存。等到下次需要再修改的时候,可以用patch命令把这个补丁打进原始包,再继续工作。比如是在linux kernel上做的工作,就不必每次保存几十兆修改后的源码了。这是好处之一,好处之二是维护方便,由于unified patch格式有一定的模糊匹配能力,能减少原软件包升级带来的维护工作量(见后)

 

patch

  patch命令跟diff配合使用,把生成的补丁应用到现有代码上。常用命令行选项:

  patch [命令行选项] [待patch的文件[patch]]

  -pn patch level(n是数字) -b[后缀] 生成备份,缺省是.orig

为了说明什么是patch level,这里看一个patch文件的头标记。

  diff -ruNa xc.orig/config/cf/Imake.cf xc.bsd/config/cf/Imake.cf

  --- xc.orig/config/cf/Imake.cf Fri Jul 30 12:45:47 1999

  +++ xc.new/config/cf/Imake.cf Fri Jan 21 13:48:44 2000

  这个patch如果直接应用,它会去找xc.orig/config/cf目录下的Imake.cf文件,假如你的源码树的根目录是缺省的xc而不是xc.orig,除了mvxc xc.orig之外,有无简单的方法应用此patch呢?patch level就是为此而设:patch会把目标路径名砍去开头patch
level个节(由/分开的部分)。在本例中,可以用下述命令:

cd xc; patch _p1 < /pathname/xxx.patch
完成操作。注意,由于没有指定patch文件,patch程序默认从stdin读入,所以用了输入重定向。

  如果patch成功,缺省是不建备份文件的(注:FreeBSD下的patch工具缺省是保存备份),如果你需要,可以加上b开关。这样把修改前的文件以“原文件名.orig”的名字做备份。如果你喜欢其它后缀名,也可以用“b后缀”来指定。

  如果patch失败,patch会把成功的patch行给patch上,同时(无条件)生成备份文件和一个.rej文件。.rej文件里是没有成功提交的patch行,需要手工patch上去。这种情况在原码升级的时候有可能会发生。

  关于二进制文件的说明:binary文件可以原始方式存入patch文件。diff可以生成(加-a选项),patch也可以识别。如果觉得这样的patch文件太难看,解决方法之一是用uuencode处理该binary文件。


diff 以行为单位比较两个文本文件(或者是目录),并将不同之处输出到标准输出上,
patch可以读入这些输出,并按照一定的指令使源文件(目录)更新

diff 以行为单位比较两个文本文件(或者是目录),并将不同之处输出到标准输出上,
patch可以读入这些输出,并按照一定的指令使源文件(目录)更新
diffutils-2.7.2-2
patch-2.5.4-10

1, diff
options:
-r --recursive
-p --show-c-function //标识不同之处所在的函数名(只用于C程序)
-e --ed //ed 命令格式 diff -e test1 test2
 //混合ed命令格式(无参数) diff test1 test2
-f      //RCS命令简单格式       diff -f test1 test2        Revision Control
System
-c --context //旧版上下文格式   diff -c test1 test2
-u --unified //新版上下文格式   diff -u test1 test2
-N          //如果某个文件只在一个目录中出现,则假定在另一个目录中为空文件.

diff的输出格式有三种:列举方式,命令模式,上下文模式
命令模式有:ed命令模式和RCS(Revision Control System)
上下文模式有:旧版和新版
命令模式记录的是从test1更新到test2所需要执行的命令,而上下文模式可读性更好一些.
Linux内核源代码就是按照新版上下文模式用diff组织的,
eg. diff -Nur linux-2.4.15 linux

2. patch
patch [options] [originalfile] [patchfile]
如果patchfile为空,则从标准输入读取
一般使用下面的形式:
patch -p[num] < patchfile
如果不提供p参数将忽略所有的目录信息,
-p0表示使用全部的路径信息
-p1表示忽略第一"/"以前的目录,依次类推

patch可以直接操作上下文格式以及混合ed格式的diff输出文件,而将ed格式文件通过管道提交给ed程序,
不清楚如何处理RCS格式文件.

eg.
bzcat linux-2.6.1.patch.bz2 | patch -p0

如果希望恢复到原来的版本可以使用 -R (--reverse)参数
但是只对上下文格式的diff文件有效.
eg. patch -R < program-1.2.patch

3. diff-patch和CVS的配合使用
在这种情况下,注意不要把CVS目录包括进去
eg.
patch -Nur program-1.0 program-1.1 --exclude=CVS

 

应该是引用了某些大大的文章,但是不知道出处了,请见谅,呵呵

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值