diff的使用及制作patch

VPS上的LANMP都是自己编译出来的,因为个人比较追求新的发布,所以一有新的版本发布,就会上down下来编译更新。之前都会对源码做些个人化的修改后再编译,就经常要对新的发布版本做一样的修改。经常性地这样手动更改很麻烦,所以就想到了制作patch补丁。

diff工具的使用

diff [OPTION]... FILES

FILES 表示多个文件或目录
说明:该命令告诉使用者,为了使文件,如FILES一致,需要修改它们的哪些行。如果用 “-“表示 FILES,则表示标准输入。如果 FILES 是目录,那么 diff 将使用该目录中的同名文件进行比较。

一般情况下diff命令输出由下述形式的行组成:

L1aL3,L4
< blablabla
> blablabla   
> blablabla  
L1,L2dL3
< blablabla
< blablabla
> blablabla  
L1,L2cL3,L4
< blablabla
< blablabla
----
> blablabla  
> blablabla  

字母(a、d和c)之前的行号(L1,L2)是针对第一个文件的,其后面的行号(L3, L4)是针对第二个文件的。字母 a、d 和 c 分别表示附加、删除和修改操作。
在上述形式的每一行的后面跟随受到影响的若干行,以 “<” 打头的行属于第一个文件,以 “>” 打头的行属于第二个文件。
diff 能区别块和字符设备文件以及 FIFO(管道文件),不会把它们与普通文件进行比较。
如果FILES都是目录,则 diff 会产生很多信息。如果一个目录中只有一个文件,则产生一条信息,指出该目录路径名和其中的文件名。
该命令的各选项作用:

  • -b 忽略行尾的空格,而字符串中的一个或多个空格符都视为相等。
  • -c 采用上下文输出格式(提供三行上下文)。
  • -C n 采用上下文输出格式(提供 n 行上下文)。
  • -e 产生一个合法的 ed 脚本作为输出。
  • -r 当 FILES 是目录时,递归作用到各文件和目录上。

patch文件的制作

所以一般情况我们会以[diff -Naur FILES]的选项来进行DIFF文件的制作。
比如执行[diff -Naur mysql51.sh mysql.sh ],就会输出以下一个Patch信息。

--- mysql51.sh	2011-07-17 05:54:15.000000000 +0000
+++ mysql.sh	2011-07-17 02:21:31.000000000 +0000
@@ -1,11 +1,11 @@
 #!/bin/bash
 
 pkgname=mysql
-pkgver=5.1.58
+pkgver=5.5.15
 url="http://www.mysql.com/"
-srcdir=$(pwd)/mysql51
-depends=('openssl' 'libssl-dev' 'zlib1g-dev' 'libncurses5-dev')
-source=("http://mysql.he.net/Downloads/MySQL-5.1/${pkgname}-${pkgver}.tar.gz")
+srcdir=$(pwd)/mysql
+depends=('cmake' 'openssl' 'libssl-dev' 'zlib1g-dev' 'libncurses5-dev' 'bison')
+source=("http://mysql.he.net/Downloads/MySQL-5.5/${pkgname}-${pkgver}.tar.gz")
 
 if [ -s ${srcdir}/${pkgname}-${pkgver}.tar.gz ]; then
     echo -e "\E[1;32m${pkgname}-${pkgver}.tar.gz [found]\E[m"

patch文件的结构

1、补丁头
补丁头是分别由—/+++开头的两行,用来表示要打补丁的文件,同时包含有文件修改时间等信息。
一个补丁文件中可以有多个补丁,所以一个补丁文件中可能包含以—/+++开头的很多节,每一节用来打一个补丁。
2、补丁块
块是补丁中要修改的地方。它通常由一部分不用修改的地方开始和结束。他们只是用来表示要修改的位置。他们通常以@@开始,结束于另一个块的开始或者一个新的补丁头。
块会缩进一列,而这一列是用来表示这一行是要增加还是要删除的。
3、补丁块的第一列
+ 表示这一行是要加上的。
– 表示这一行是要删除的。
没有”+”也没有”-“表示这里只是引用的而不需要修改。

Patch的使用

   patch -pN -i PATCHFILE
其中N为0或1,p0表示从当前目录开始查找,比如下面的patch头,就会从php-5.3.7这个目录开始查找。p1表示忽略当前目录,开始找下一层目录,比如下面的patch头就会忽略掉php-5.3.7这个目录,从ext目录开始查找

— patchs/ext/standard/info.c 2011-08-21 14:49:09.000000000 +0000
+++ php-5.3.7/ext/standard/info.c 2011-08-21 14:38:48.000000000 +0000