diff 与 patch

diff命令

当前目录下有a b 两个文件,内容如下

[15:40:58 19B]> cat a
111
44
[15:41:00 19B]> cat b
333
111
444

diff a b的结果如下

[15:59:54 19B]> diff a b
0a1
> 333
2c3
< 44
---
> 444

解释:
显式的信息是为了:帮助a转变为b文件
0a1,表示在a个文件里的第0行后,*添加* b文件的第1行
> 333 是辅助显示 0a1 中b文件的第1行内容为333
2c3,表示将a的第2行,*改变成* b的第三行
< 44 是表a文件第2行内容为44
---
> 444 是表示b文件第3行内容为444

a append
c change

选项

常用选项:
-r 如果 a b是目录,则会递归对比ab下每个文件
-N 在a b是目录的前提下,如果文件不存在,则用空文件进行对比

-u 改变输出格式,是为了配合patch命令使用时的输出格式

例子:
dir2目录下有b/bb/file文件,file内容为123,dir1是空目录

[16:26:31 tmp]> diff -rNu dir1 dir2
diff -rNu dir1/bb/bbb/file dir2/bb/bbb/file
--- dir1/bb/bbb/file    1970-01-01 08:00:00.000000000 +0800
+++ dir2/bb/bbb/file    2023-05-11 14:58:51.219741320 +0800
@@ -0,0 +1 @@
+123

通常会将输出定向到文件中 diff -rNu dir1 dir2 > test.patch

patch命令

通过diff生成的patch文件,可以直接将a 转换成b文件

  • 单个文件打补丁
    假设现在有a b 文件,内容和diff中的例子一样
[16:29:55 19B]> diff -u a b > my_patch
[16:30:47 19B]> cat my_patch
--- a   2023-05-11 16:29:50.895225922 +0800
+++ b   2023-05-11 10:34:57.263809225 +0800
@@ -1,2 +1,3 @@
+333
 111
-44
+444

打补丁

[16:38:14 19B]> patch a < my_patch
patching file a
[16:38:24 19B]> cat a
333
111
444
  • 工程打补丁
    假设现在有dir1 dir2目录,内容和diff中的例子一样
[16:39:28 tmp]> diff -rNu dir1 dir2 > my_patch
[16:40:18 tmp]> cat my_patch
diff -rNu dir1/bb/bbb/file dir2/bb/bbb/file
--- dir1/bb/bbb/file    1970-01-01 08:00:00.000000000 +0800
+++ dir2/bb/bbb/file    2023-05-11 14:58:51.219741320 +0800
@@ -0,0 +1 @@
+123

打补丁

[16:43:51 tmp]> cd dir1
[16:44:01 dir1]> patch -p1 < ../my_patch
patching file bb/bbb/file

其中,-p1 表示跳过对比中的第1级目录
如果,不加 -p参数,则会不会创建b/bb目录,直接在dir1中添加file
如果,改-p1 为 -p0,则会在dir1目录下,创建dir1/bb/bbb/file,而不是预期的bb/bbb/file

如果 存在dir1中有而dir2中没有的文件,在其他目录下执行 patch -p0 < my_patch,并不会创建dir1中独有的文件,只会创建和修改,dir1中不同或缺少的文件

快速上手

场景1:给工程打patch
raw_project无修改工程,changed_project有修改工程
diff -purN raw_project changed_project > diff.patch
给无修改工程打patch
进入新工程目录下patch -p1  < diff.patch

场景2:给单个文件打patch
生成diff文件
diff raw_file changed_file > diff.patch
打patch
patch -d raw_file_dir -p0 raw_file < diff.patch


说明:
diff-p显示c函数变化 -a所有文件 -r递归 -N新文件也比较
patch -d切换工作目录 -p0/-p1忽略patch文件0层目录/1层目录

直接只使用:
diff -purN old new >diff.patch
patch -p file<diff.patch

重复补丁问题

强调,对于仅由重复打补丁造成的
Reversed (or previously applied) patch detected! Assume -R?
可以使用以下方法解决,如果是补丁文件和原文件对应不上提示的这个问题,需要检查补丁文件和源文件

1. 先使用-R选项,撤销之前的补丁,如果遇到
Unreversed patch detected!  Ignore -R? 键入n
会提示一些报错信息,和一些补丁文件,可以无视,
2. 然后再 正常打一次补丁
此次应该不会有补丁的提示信息
3. 删除补丁提示文件
find . -name "*.orig"  -delete
find . -name "*.rej"  -delete



例子:

生成patch打patch,(假设有多份老文件需要更新)

diff old  new > patch
patch old2 < patch
patch -R old2 < patch

生成patch打patch,(假设有多份老工程需要更新)

diff -rNu old_prj  new_prj > patch
cd old_prj
patch -p1  < patch
posted @   木瓜粉  阅读(111)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示