diff 和 patch 命令

Table of Contents

在开发中 diff 和 patch 是非常常用的两个命令。

介绍两个命令之前,先准备两个示例代码。

/* filename: old.c */

#include <stdio.h>

int main(void) {
  printf("old");
  return 0;
}
/* filename: new.c */

#include <stdio.h>


int main(void) {
  printf("new");
  return 0;
}

1. diff

用于比较两个新旧文件之间的变化差异,用法:

diff 旧文件 新文件

注意新旧文件作为参数的顺序,顺序错误,生成的补丁也会引起不正确的改动。

比较两个文件的差异:

$ diff old.c new.c
4c4
<   printf("old");
---
>   printf("new");

把 diff 的结果作为补丁是非常常用的,只需用 -u 参数:

$ diff -u old.c new.c
--- old.c 2016-08-19 22:06:07.088790973 +0800 # “---”表示旧文件
+++ new.c 2016-08-19 22:06:23.101898395 +0800 # “+++”表示新文件
@@ -1,6 +1,6 @@ # 块,表示要修改的位置。“-”表示要删除的;“+”表示要增加的
 #include <stdio.h>

 int main(void) {
-  printf("old");
+  printf("new");
   return 0;
 }

可重定向来生成补丁文件:

$ diff -u old.c new.c > a.patch

生成的补丁文件用 patch 命令即可对旧的代码打补丁。

2. patch

用法:

patch -p0 < 补丁文件

-p0 表示从当前目录搜索改动的文件。

-p1 表示忽略第一层目录。

比如源文件路径是 old/module/a.c,改动后的是 new/module/a.c,那么 -p1 时,从当前目录下的 module 开始应用补丁。如果是 -p0,则是从当前目录下的 old 目录下开始应用。

接上例,执行:

patch -p0 < a.patch

old.c 中对应的行就被修改成了 new.c 对应的内容。

patch 是直接对原始文件进行写操作,如果打补丁打出问题,还可以撤销补丁:

patch -p0 -E < a.patch

-R 参数可以取消补丁的应用。