Linux补丁(patch)制作与应用

2790阅读 0评论2013-06-06 leon_yu
分类:LINUX

主要用到两个命令

diff:
可以比较两个单文件或目录内容,记录下两者不同

diff  []  from to

-r 递归,比较所有子目录下文件

-N 确保补丁文件将正确地处理已经创建或删除文件的情况

-u 输出每个修改前后的3行,也可以用-u6等指定输出上下文行数

 

patch

diff的结果(补丁)应用到相应文件/目录上

patch  -pN  dir/file  patchfile

-pN 忽略N层目录,比如-p1patch会忽略掉第一个“/”之前的内容

-R 取消打过的补丁

 

举例应用:

(1) 处理单个文件

产生补丁

diff -uN hello.c bye.c  > file.patch

补丁内容

点击(此处)折叠或打开

  1. --- hello.c 2013-06-06 11:38:55.972598077 +0800
  2. +++ bye.c 2013-06-06 11:39:45.256597688 +0800
  3. @@ -1,6 +1,6 @@
  4.  #include <stdio.h>
  5.  int main(void)
  6.  {
  7. - printf("hello,world!rn");
  8. + printf("bye,world!rn");
  9.         return 0;
  10.  }
  11. 打上补丁
  12. cp hello.c test.c
  13. test.c 内容:
  14. #include <stdio.h>
  15. int main(void)
  16. {
  17.         printf("hello,world!rn");
  18.         return 0;
  19. }
  20. patch -p0 test.c < file.patch
  21. #include <stdio.h>
  22. int main(void)
  23. {
  24.         printf("bye,world!rn");
  25.         return 0;
  26. }

取消补丁

patch -RE -p0 test.c < file.patch

test.c文件还原

 

(2) 处理目录

diff -uNr old/ new/  > dir.patch

cd old

patch -p1 <../dir.patch

取消目录

patch -R -p1 <../dir.patch

 

patch文件构成

以下是上例目录补丁的内容

点击(此处)折叠或打开

  1. diff -uNr old/hello.c new/hello.c
  2. --- old/hello.c 2013-06-06 10:11:32.724674000 +0800
  3. +++ new/hello.c 2013-06-06 10:39:21.032652591 +0800
  4. //补丁头,---表示旧文件,+++表示新文件
  5. @@ -4,10 +4,12 @@
  6. //old/hello.c 4~10行,new/hello.c 4~12行为改动区间
  7.         int i,j;
  8.         int ret;
  9.  
  10. - i = 5;
  11.         j = 6;
  12. + i = 7
  13.         ret = i + j;
  14.         printf("%d + %d =%drn",i,j,ret);
  15.  
  16. + printf("hello world!rn");
  17. +
  18.         return 0;
  19.  }
  20. //补丁块,-表示这一行是要删除的,+表示这一行是增加的,其他表示无修改
  21. diff -uNr old/test.c new/test.c
  22. --- old/test.c 2013-06-06 10:29:49.100659025 +0800
  23. +++ new/test.c 2013-06-06 10:46:04.732643907 +0800
  24. @@ -1,6 +1,9 @@
  25.  #include <stdio.h>
  26.  int main(void)
  27.  {
  28. - printf("testn");
  29. + printf("test0.rn");
  30. + printf("test.rn");
  31. + printf("test1.rn");
  32. + printf("test2.rn");
  33.         return 0;
  34.  }

最后有以下几点注意:

  1. 一次打多个patch的话,一般这些patch有先后顺序,得按次序打才行。

  2. 在patch之前不要对原文件进行任何修改

  3. 如果patch中记录的原始文件和你得到的原始文件版本不匹配(很容易出现),那么你可以尝试使用patch, 如果幸运的话,可以成功。大部分情况下,会有不匹配的情况,此时patch会生成rej文件,记录失败的地方,你可以手工修改。

 

使用版本控制工具时,可以svn diffgit diff生产补丁




上一篇:Linux内核设计与实现(4)---Timers and Time Management
下一篇:Linux内核设计与实现(5)---进程调度