如何给文件系统打补丁 - 主题更新 patch 实例

小助手读文章 00:00 / 00:00

比如 ArmxMod for Typecho 主题,存在较多子目录及文件,有时候小伙伴们会再这个基础上进行再次开发,担心在主题更新后,直接覆盖掉会忘了修改了什么地方,所以就在想,是否由办法通过打补丁(patch)的方式进行更新。

经过查询,Linux 下生成补丁和打补丁可以通过 diffpatch 两个命令来实现。

生成补丁

生成补丁很重要的一个基础,就是需要有一份未修改的源码,然后通过 diff 命令生成差异,参考如下代码:

[[email protected] themes]# diff -uprN armx/ armxnew/ >>0828-0905.patch

这一行命令实现的功能就是,对未修改的文件夹 armx 和修改后的文件夹 armxnew,递归文件夹输出差异行至 08228-0905.patch 文件中。

命令中的参数:

-u 显示有差异行的前后几行(上下文),默认是前后各 3 行,这样,patch中带有更多的信息;
-p 显示代码所在的 c 函数的信息;
-r 递归地对比一个目录和它的所有子目录(即整个目录树);
-N 如果某个文件缺少了,就当作是空文件来对比。如果不使用本选项,当 diff 发现旧代码或者新代码缺少文件时,只简单的提示缺少文件,如果使用本选项,会将新添加的文件全新打印出来作为新增的部分。

生成的补丁大概长这样:

......
diff -uprN armx/css/style.css armxnew/css/style.css
--- armx/css/style.css  2019-08-27 11:12:54.000000000 +0800
+++ armxnew/css/style.css       2019-09-05 11:41:14.000000000 +0800
@@ -2538,7 +2538,7 @@ padding: 0px;
 .tl-item div{
 margin-top: 0px!important;
 }
-#tabs-recom img:hover,#tabs-service img:hover,#tabs-recom .recdiv:hover,#tabs-service .recdiv:hover {
+#tabs-recom img:hover,#tabs-service img:hover, #tabs-recom .recdiv:hover,#tabs-service .recdiv:hover{
 box-shadow: 0 0 25px 8px rgba(0,0,0,.33);
 transform: scale(1.2);
 border-radius: 5px;
......

其中 @@ -2538,7 +2538,7 @@ 被称为 (c) 更改块的范围信息,其格式如下:

@@ -l,s +l,s @@

其中 l 是起始行号,s 是更改块在文件中的行数。 - 表示原始文件,+ 表示新文件,请注意,它不仅显示受影响的行,而且还显示上下行。

这一句的意思就是从第 2538 行开始,共显示 7 行。- 表示该行将被删除,+ 表示该行将会新增插入。

打补丁

打补丁的意义在于批量修改更新的文件,而不去动没有修改的文件。从上面生成补丁可以看到,补丁的重要参数是行数,因此如要成功打上补丁,行数要能对上才行。

生成的补丁中,路径信息包含了源码根目录的名称,但其他人的源码根目录可能是其它名字,所以打补丁时,要进入自己的源码根目录,并且告诉 patch,请忽略补丁中的路径的第一级目录(参数 -p1),参考如下代码:

[[email protected] armx]# patch -p1 <0828-0905.patch 
patching file comments.php
patching file css/style.css
patching file footer.php
patching file functions.php
patching file header.php
patching file index.php
patching file js/main.js
patching file js/script.js
patching file lib/online.txt
patching file lib/smaile.php

可以看到已经成功将差异部分更新到自己源码中了。

二进制补丁

在实际应用中,会发现,只有源代码成功被打补丁,新增的图片并没有更新到,查看补丁文件,可以发现错误信息:

......
Binary files armx/img/ravatar/0.jpg and armxnew/img/ravatar/0.jpg differ
Binary files armx/img/ravatar/1.jpg and armxnew/img/ravatar/1.jpg differ
Binary files armx/img/ravatar/2.jpg and armxnew/img/ravatar/2.jpg differ
......

可以确定在生成补丁时,并没有将图片纳入,故判断命令 diff -uprN 不支持非文本格式,经查询使用手册,我们可以加上 -a 来使其使用二进制的方式来支持非文本格式的修改,比如图片等等。

结论

所以最终生成补丁的命令是(注意执行目录是 themes/):

[[email protected] themes]# diff -auprN armx/ armxnew/ > 0828-0905.patch
[[email protected] themes]# mv 0828-0905.patch armx/

打补丁的命令是(注意执行目录是 themes/armx):

[[email protected] armx]# patch -p1 <0828-0905.patch 
patching file comments.php
patching file css/style.css
patching file footer.php
patching file functions.php
patching file header.php
patching file img/hw818_2.png
patching file img/ravatar/0.jpg
patching file img/ravatar/1.jpg
patching file img/ravatar/2.jpg
patching file img/ravatar/3.jpg
patching file img/ravatar/4.jpg
patching file img/ravatar/5.jpg
patching file img/ravatar/6.jpg
patching file img/ravatar/7.jpg
patching file img/ravatar/8.jpg
patching file img/ravatar/9.jpg
patching file index.php
patching file js/main.js
patching file js/script.js
patching file lib/online.txt
patching file lib/smaile.php

思考

使用 diffpatch 命令来完成生成补丁和打补丁动作,本质上其实跟 git 版本管理类似,由于补丁都是基于源文件进行的,因此如果源文件被修改,恰好这个文件又是有更新的,那么基于源文件的补丁将无法使用。

有一个折中的方法,就是先将修改过的部分做个补丁,标记出修改了什么地方,然后覆盖最新的源码,根据补丁再把修改的地方再做一遍,囧。。。


ArmxMod for Typecho
个性化、自适应、功能强大的响应式主题

推广

 继续浏览关于 linux教程typecho主题armxmod更新补丁 的文章

 本文最后更新于 2019/09/07 11:00:00,可能因经年累月而与现状有所差异

 引用转载请注明:VirCloud's Blog > 经验 > 如何给文件系统打补丁 - 主题更新 patch 实例

精选评论

  1. 欧文斯

    通过打补丁方式来更新,工作量少,可以较好实现版本控制。