|
|
patch的使用:
//patch manual建议两个目录处于同一层次
dev/gcc-2.7
dev/gcc-2.8
cd dev
创建patch:
// patch manual建议:
// export LC_ALL=C
// export TZ=UTC0
//大概是为了时间戳保持标准的记法。
// diff -Naur oldDir newDir # patch manual建议两个目录名都不要包含'/'
diff -Naur gcc-2.7 gcc-2.8 >gcc-2.7_2.8.patch
打patch:
cd gcc-2.7; patch -Np1 -i ../gcc-2.7_2.8.patch将2.7升到2.8
or
cd gcc-2.8; patch -Rp1 -i ../gcc-2.7_2.8 patch 将2.8降到2.7
-N 如果当前目录是新版本, 则忽略这个patch
-R 如果当前目录是新版本, 则降到旧版本 (reverse)
-pn 忽略掉patch文件中前几个目录分隔符, 比如/aa/bb在p1时就是aa/bb
(比如patch文件中两行:
+++ /u/aa/bb.txt ...
--- /u/aa-new/bb.txt
-p0则保持两个文件名不变
-p1则上两行的文件名变为u/aa/bb.txt和u/aa-new/bb.txt
-p2则上两行的文件名变为aa/bb.txt和aa-new/bb.txt
-p3则上两行的文件名变为bb.txt和bb.txt
到底指定多少要看当前所处目录层次和patch文件中的文件名目录层次是否匹配,
比如cd aa, 对于上面的两行, 应该用p3了)
-i patchfile 指定输入文件,也可以用重定向输入指定patchfile
==============
对p参数的附加说明:
diff (GNU diffutils) 2.8.1, patch (Larry Wall) 2.5.9
patch会自动判断p参数, 所以一般情况下只需要 patch -N <patchfile
试验, 以下情况p参数均未指定就能成功:
cd old;
(p1)
old/aa.txt
new/aa.txt
(p2)
xx/old/aa.txt
xx/new/aa.txt
(p2)
xx/old/aa.txt
yy/new/aa.txt
后面两个是我手工修改了patch文件.
============
//再次添加说明:
刚发现patch对目录名要求相当宽松, 估计是从后面往前面匹配的,
diff -Naur path_to_your_old_top_dir path_to_your_new_top_dir >p
cd path_to_your_old_top_dir; patch -N < path_to/p
# -N 只是保险起见, 如果在一个新版本上patch <p, 会提示是否Reverse.
or
cd path_to_your_new_top_dir; patch -R <path_to/p
==============
嗯, 又补充, 发现patch自动判断p参数时有误判:
+++ aa-old/cc/aa.txt ...
--- aa/cc/aa.txt ...
cd aa-old; patch -N<my.patch会出错,原因是patch把p参数设置成了p2。
当patch文件中第一笔记录的不包含路径名的文件名(上例中就是aa.txt)不在
运行patch的目录中(此处是aa)中时, patch会错误的将p参数设置成直到去掉
最后一个'/'(此处有aa.txt之前有两个'/',因此p参数为2,其实应该是1)。
我觉得这个p参数可以这样判断:
若命令行设置了,pold=pnew=parg;
若命令行没有设置, 则一次次增大pold(0~countOf('/', oldFile)), 判断
去掉了pold个'/'后在当前目录中存在这个文件名否, 如果存在则pold就是这个值,
而pnew就是就是在newFile中搜索上面这个文件名得到的索引值, 详细过程如下:
- pold = 0; pnew =0;
- if (命令行上没有-p选项) {
- readpatchfile(); oldFile = "aa-old/cc/aa.txt"; newFile = "aa/cc/aa.txt";
- int n = countOf('/', oldFile);
- while (pold <= n) {
- oldFile = 去掉第pold个'/'所处位置及之前字符后的字符串(比如pold=1, oldFile就是cc/aa.txt)
- if (oldfile不存在于当前目录中) {++pold; continue;} //只能按照pold递增的方式查找,
- //否则在aa-old/cc/aa.txt, aa-old/aa.txt的情况下会出错
- 比如pold=1, 在当前目录中找到cc/aa.txt了, 然后在newFile中查找cc/aa.txt
- 最后一次出现的位置, 得到的位置就是newfile中从0算起第3个位置, 统计一下之前
- 的'/'的个数, 此处pnew=1;
- 实际上pold和pnew可以分别记录在旧新版本的文件名中要忽略掉的前缀字符个数,
- 不用记录'/'的个数.
- }
复制代码
按照这种方式的话应该就可以废弃-p参数了.
呵呵,可以给patch打patch了.
一点笔记, 希望对大家有用, 参考了patch和diff的man, 以及LFS版的一篇帖子(搜索到的,
好多人问), 如有谬误, 欢迎指正 
===
第10次修改, 似乎一分钟看不完了  |
|