patch命令用法

作为程序员,了解diffpatch命令是非常必要的。比如说发现某个项目有bug,而自己又没有提交权限,此时最合适的解决方法就是用diff命令做一个补丁发给组长。组长看到补丁后会立刻明白你的意图。
有人说直接传一个工程不就完了?不要忘了,补丁文件尺寸更小传输更快,而且可以明显看到都做了哪些修改。就算你把修改后的工程传过去,组长还需要用对比工具查看做了哪些修改,这样费时费力。

下面开始做实验。

创建实验目录和文件

创建一个实验目录demo

mkdir demo

进入demo

cd demo

模拟一个项目目录src

mkdir -p src/a/b/c/d

创建一个文件

vim src/a/b/c/d/file

内容是

line1
line2
line3

假设我们发现项目src需要修改,那么拷贝src并命名为src_new

cp -r src src_new

并且修改src_new/a/b/c/d/file的内容为

new_line1
new_line2
new_line3

此时,demo目录下用tree命令的结果是:
这里写图片描述

制作补丁

在demo目录下用diff命令打补丁,不要使用绝对路径,而应该使用相对路径。

 diff -Nur src src_new >src.patch

关于diff的用法,可以参考我的博文:
http://blog.csdn.net/longintchar/article/details/74139933

浏览一下补丁文件:

这里写图片描述

至此,补丁制作完成。

这时候在demo目录下用tree命令,得到
这里写图片描述

打补丁

在demo目录下,试试下面命令:

patch -p0 <src.patch

回车后终端显示

patching file src/a/b/c/d/file

这里的p0是什么含义呢?
看一下补丁文件中的路径信息:

--- src/a/b/c/d/file    2017-07-02 18:41:19.269641100 +0800
+++ src_new/a/b/c/d/file    2017-07-02 18:32:06.687035200 +0800

p0表示不跳过任何目录(使用完整路径)。即从当前目录中查找src/a/b/c/d/file.
因为是在demo目录下使用patch命令,src目录就在demo目录下,不必跳过任何目录,所以此时使用的是p0

此时查看src/a/b/c/d/file,你会发现内容已经修改成

new_line1
new_line2
new_line3

这时候如果再次使用patch命令,系统会问你是否想还原,输入y 还原:

patching file src/a/b/c/d/file
Reversed (or previously applied) patch detected! Assume -R? [n]

这时候src/a/b/c/d/file的内容已经还原成旧的了:

line1
line2
line3

如果你想指定还原文件, 可以使用-R参数:

patch -Rp0 <src.patch

已经明白了p0,那么p1、p2呢?
我们把路径切换到src目录下。

cd src

此时就应该是p1,而不是p0了; 另外引用src.patch文件的路径也要适当变一下,因为当前目录已经是src

patch -p1 <../src.patch 

再看看补丁文件中的路径信息:

--- src/a/b/c/d/file    2017-07-02 18:41:19.269641100 +0800
+++ src_new/a/b/c/d/file    2017-07-02 18:32:06.687035200 +0800

此时我们是在src目录下使用patch命令,p1表示忽略第一个斜杠及左边,即寻找a/b/c/d/file,而a就在当前目录下,所以使用p1.

为了继续测试,我们还原一下

patch -Rp1 <../src.patch

继续变换路径,测试p2参数:

cd a

然后

patch -p2 <../../src.patch 

因为补丁文件中的路径信息是

--- src/a/b/c/d/file    2017-07-02 18:41:19.269641100 +0800
+++ src_new/a/b/c/d/file    2017-07-02 18:32:06.687035200 +0800

此时我们是在a目录下使用patch命令,p2表示忽略第2个斜杠及左边,即寻找b/c/d/file,而b就在当前目录下,所以使用p2.

还原后继续实验,我们进入到d目录

patch -p5 <../../../../../src.patch

依然观察补丁文件中的路径信息:

--- src/a/b/c/d/file    2017-07-02 18:41:19.269641100 +0800
+++ src_new/a/b/c/d/file    2017-07-02 18:32:06.687035200 +0800

此时我们是在d目录下使用patch命令,p5表示忽略第5个斜杠及左边,即寻找file,而file就在当前目录下,所以使用p5.

有人会问,不使用p参数会有什么结果呢?
不使用p参数 时候,patch命令会忽略所有斜杠,直接使用文件,即本文中的file
所以在d目录下也可以用命令

patch  <../../../../../src.patch

为什么使用diff命令时最好不要使用绝对路径,而应该使用相对路径?

答:如果使用绝对路径,那么补丁文件里的路径信息会类似下面的样子:

--- /x/xx/xxx/src/a/b/c/d/file  2017-07-02 18:41:19.269641100 +0800
+++ /x/xx/xxx/src_new/a/b/c/d/file  2017-07-02 18:32:06.687035200 +0800

如此一来,当别人想应用你的补丁时,因为目录结构肯定有差异,所以就不得不费力判断到底使用p几。这样一来就容易出错.
相反,如果使用相对路径的话,大多数时候,p0或者p1就足够了,不易出错。

总结

假如补丁头是

--- src/a/b/c/d/file    2017-07-02 18:41:19.269641100 +0800
+++ src_new/a/b/c/d/file    2017-07-02 18:32:06.687035200 +0800

使用p0 表示在当前目录下查找src/a/b/c/d/file
使用p1 表示在当前目录下查找a/b/c/d/file
使用p2 表示在当前目录下查找b/c/d/file
使用p3 表示在当前目录下查找c/d/file
使用p4 表示在当前目录下查找d/file
使用p5 表示在当前目录下查找file
不使用pn表示忽略所有斜杠,在当前目录下查找file

打补丁的命令格式是

patch -pn < 补丁文件

还原的命令格式是

patch -Rpn < 补丁文件

(n=0,1,2,3…)

【参考资料】
[1] http://blog.csdn.net/wh_19910525/article/details/7515540

发布了246 篇原创文章 · 获赞 289 · 访问量 57万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览