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是目录,则会递归对比a,b下每个文件
-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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!