Linux编程中制作&打补丁:diff & patch

来源:互联网 发布:淘宝上买什么东西好 编辑:程序博客网 时间:2024/05/17 07:17

1 背景

    作为一个程序员,经常需要阅读并且修改代码,因此必须得懂得如何制作补丁和打补丁。

2 制作补丁——diff[1]

    制作补丁,一般使用diff工具,例如:

2.1 文件

diff –uN from_file  to_file > to_file.patch

   参数解析:

    -u, -U NUM, --unified[=NUM]:输出NUM (默认 3) 行合并格式说明信息,如下面的例子所示。diff支持3种格式,详见参考资料[4];

    -N, --new-file:若文件不存在,则当作是新文件,内容为空。

    统一格式说明

--- file_new.c2015-10-05 16:54:38.002595128 +0800+++ file_old.c2015-10-05 16:54:25.378595412 +0800@@ -1,8 +1,7 @@

    格式说明

    ---:旧文件[1]

    +++:新文件[1]                     

2.2 目录

diff –uNr from_dir to_dir > to_dir.patch 

    参数解析:    

    -r, --recursive:递归比较子目录的文件。

2.3 补丁文件结构[1]

2.3.1 补丁头

   补丁头是分别由---/+++开头的两行,用来表示要打补丁的文件。---开头表示旧文件,+++开头表示新文件

    一个补丁文件中可能包含以---/+++开头的很多节,每一节用来打一个补丁。所以在一个补丁文件中可以包含好多个补丁。

    具体实例如2.1小节所示。

2.3.2 块
    块是补丁中要修改的地方。它通常由一部分不用修改的东西开始和结束。他们只是用来表示要修改的位置。他们通常以@@开始,结束于另一个块的开始或者一个新的补丁头。
    块会缩进一列,这一列是用来表示这一行是要增加还是要删除的:
    +号表示这一行是要加上的;
    -号表示这一行是要删除的。
没有加号也没有减号表示这里只是引用的而不需要修改。

2.4 实例

2.4.1 file_old.c

#include <stdio.h>int main(void){    printf("hello world !\n");    printf("How are you ?\n");}

2.4.2 file_new.c

#include <stdio.h>int main(void){    //printf("hello world !\n");    printf("How are you ?\n");    printf("I am fine!\n");}

2.4.3 diff -uN file_old.c  file_new.c

liyihai@ubuntu:~/Documents/patch_example$ diff -u file_old.c file_new.c --- file_old.c2015-10-05 16:54:25.378595412 +0800+++ file_new.c2015-10-05 16:54:38.002595128 +0800@@ -1,7 +1,8 @@ #include <stdio.h> int main(void) {-printf("hello world !\n");+//printf("hello world !\n"); printf("How are you ?\n");+printf("I am fine!\n"); }

    说明:若使用上述内容作为补丁文件,则打补丁的时候是对file_old.c进行打补丁,使其内容和file_new.c一致。

2.4.4 diff -uN file_new.c  file_old.c

liyihai@ubuntu:~/Documents/patch_example$ diff -u file_new.c file_old.c --- file_new.c2015-10-05 16:54:38.002595128 +0800+++ file_old.c2015-10-05 16:54:25.378595412 +0800@@ -1,8 +1,7 @@ #include <stdio.h> int main(void) {-//printf("hello world !\n");+printf("hello world !\n"); printf("How are you ?\n");-printf("I am fine!\n"); }

 说明:若使用上述内容作为补丁文件,则打补丁的时候是对file_new.c进行打补丁,使其内容和file_old.c一致。

3 打/去除补丁——patch

3.1.文件[1]

    进入需要需要打补丁的文件所在的目录,执行下面的命令:

diff –uN old_file new_file > new.patch //生成补丁 【因为单个文件,所以不需要-r选项。选项顺序没有关系,即可以是-uN,也可以是-Nu】patch –p0 < new.patch //打补丁patch –R –p0 < new.patch //去除补丁

    参数解析

    -p0:忽略0层目录(即没有忽略)[1]。想要忽略几层目录,就将0改为相应的数字行了。

    -R, --reverse:反向操作。打补丁的反向操作就是去除补丁

3.2 目录[1]

diff –uNr old_dir new_dir > new.patch //生成补丁cd old_dirpatch –p1 < new.patch //打补丁patch –R –p1 < new.patch //去除补丁

    参数说明

    -p1:表示忽略1层目录。如果cd old_dir再执行patch,一般要使用这个参数,否则会在old_dir中再创建一个顶层的目录(就像Windows中使用rar解压工具解压文件时,如果指定“解压到xxx目录”,则会在xxx目录中创建一个与解压文件同名的目录,然后再将解压的内容保存到其中。这样子往往就多了一层目录,并非我们所需要的!)


参考资料

[1]使用diff命令打补丁详解

[2]使用diff和patch制作及打补丁

[3]diff和patch使用指南

[4]读懂diff

[5]如何使用git 生成patch

[6]git diff的用法

[7]如何用git-am来合并git format-patch生成的一系列的patch

[8]Git的Patch功能

0 0