在Unix系统下,维护源码版本可以使用很多方法,其中最常用的当然是大名鼎鼎的CVS,但实际上,简单的版本维护工作并没有必要使用复杂的CVS等专门的版本维护工具,Unix标配中的diff和patch工具就完全可以完成代码的简单备份和升级工作。

diff以"行"为单位比较两个文本文件(也可以是目录比较),并将不同之处以某种格式输出到标准输出上;patch可以读入这种输出,并按照一定指令使源文件(目录)按照目标文件(目录)更新。Linux内核源码就是按照这种方式保持更新的,我们在www.kernel.org上可以下载到最新内核的patch文件的bzip2包。本文以gnudiffutils 2.7和patch 2.5为例介绍diff和patch工具的使用。

1.diff

diff既可以用来比较两个文件,也可以用来比较两个目录中每个文件。使用-r(--recursive)参数时还可以在目录中嵌套比较。比较目录时除比较同名文件外,对不同名的文件当成新文件处理。对于比较C程序文件,diff还提供了专门的参数(-p,--show-c- function)来标识不同之处所在的函数名。

diff的输出格式有三种:列举方式、命令模式和上下文模式,其中命令模式有分为两种:ed命令格式和RCS(Revision Control System,版本控制系统)命令格式,上下文模式也按格式分为老版和新版两种。看下面的例子就能基本清楚各个格式的区别:

命令格式记录的是从test1更新到test2所需要执行的命令,而上下文模式通常可读性更好一些,它所记录的主要是二者的差异,通常还记录所需修改部分的上下几行(可配置)内容以供比较。见下面的例子:

新版格式较之老版要紧凑一些,Linux内核源码的升级就是按照新版上下文格式用diff组织的,比如patch-2.4.16中所用的具体命令为:

diff -Nur linux-2.4.15 linux

参数N表示如果某个文件仅在一个目录中出现,则假定其在另一个目录中为空文件;u表示unified格式,r表示在目录中嵌套使用,linux-2.4.15显然是老核的目录名,而linux则为新核的目录名。


回页首

2.patch

尽管并没有指定patch和diff的关系,但通常patch都使用diff的结果来完成打补丁的工作,这和patch本身支持多种 diff输出文件格式有很大关系。patch通过读入patch命令文件(可以从标准输入),对目标文件进行修改。通常先用diff命令比较新老版本,patch命令文件则采用diff的输出文件,从而保持原版本与新版本一致。

patch的标准格式为

patch [options] [originalfile] [patchfile]

如果patchfile为空则从标准输入读取patchfile内容;如果originalfile也为空,则从 patchfile(肯定来自标准输入)中读取需要打补丁的文件名。因此,如果需要修改的是目录,一般都必须在patchfile中记录目录下的各个文件名。绝大多数情况下,patch都用以下这种简单的方式使用:

patch -p[num] <patchfile

patch命令可以忽略文件中的冗余信息,从中取出diff的格式以及所需要patch的文件名,文件名按照diff参数中的"源文件"、"目标文件"以及冗余信息中的"Index:"行中所指定的文件的顺序来决定。也就是说,对于如下diff结果文件(Linux内核源码 2.4.16升级包,部分):

diff -Nur linux-2.4.15/Makefile linux/Makefile--- linux-2.4.15/Makefile       Thu Nov 22 17:22:58 2001+++ linux/Makefile      Sat Nov 24 16:21:53 2001@@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4-SUBLEVEL = 15-EXTRAVERSION =-greased-turkey+SUBLEVEL = 16+EXTRAVERSION = KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)……

patch首先尝试当前目录(或者-d参数指定的目录)下的linux-2.4.15/Makefile文件是否存在,如果不存在则试图对linux/Makefile文件操作,仅当两者都不存在时(或者设置了POSIXLY_CORRECT环境变量)才会读取Index:的内容(此文件中没有标识)。

前面提到的-p参数决定了是否使用读出的源文件名的前缀目录信息,不提供-p参数,则忽略所有目录信息,-p0(或者-p 0)表示使用全部的路径信息,-p1将忽略第一个"/"以前的目录,依此类推。如/usr/src/linux-2.4.15/Makefile这样的文件名,在提供-p3参数时将使用linux-2.4.15/Makefile作为所要patch的文件。

对于刚才举的Linux内核源码2.4.16升级包的例子,假定源码目录位于/usr/src/linux中,则在当前目录为/usr /src时使用"patch -p0 <patch-2.4.16"可以工作,在当前目录为/usr/src/linux时,"patch -p1<patch-2.4.16"也可以正常工作。

patch可以直接操作上下文格式以及混合ed格式的diff输出文件,而将ed格式文件通过管道提交给ed程序操作(暂时不知RCS格式的文件如何处理)。


回页首

3.配合使用diff和patch升级源码

在此仅举一个简单的例子来说明如何用diff/patch工具维护源码升级。

假设program-1.0目录中为老版,现开发完成的新版位于program-2.0目录中,将两个目录置于同一父目录下,然后在该父目录上执行:

diff -Nur program-1.0 program-2.0 >program-2.0.patch

将生成一个program-2.0.patch的补丁文件,发布该补丁文件(当然可以先压缩成bzip2格式)。

假设拿到的是program-2.0.patch.bz2文件,则在program-1.0目录同级执行:

bzcat program-2.0.patch.bz2 | patch -p0

如此即完成了从1.0到2.0的升级。

如果希望恢复到原版本,可以使用-R(--reverse)参数,但仅对上下文格式的diff文件有效。还有一个备份参数也可以使用,但简单应用中,整个目录备份可能更方便一些。

参考资料

  • Patch手册页
  • Diff手册页

关于作者

杨沙洲,目前在国防科技大学计算机学院攻读软件方向博士学位。您可以通过 pubb@163.net与他联系。

转载于:https://www.cnblogs.com/napoleon_liu/archive/2011/01/31/1948217.html

[转] 用Diff和Patch工具维护源码相关推荐

  1. H5类似易企秀/编辑器/页面制作/开发/生成工具/软件/源码/授权

    代码地址如下: http://www.demodashi.com/demo/14960.html 项目简介 H5DS (HTML5 Design software) 这是一款基于WEB的 H5制作工具 ...

  2. 一篇文章看懂TPCx-BB(大数据基准测试工具)源码

    TPCx-BB是大数据基准测试工具,它通过模拟零售商的30个应用场景,执行30个查询来衡量基于Hadoop的大数据系统的包括硬件和软件的性能.其中一些场景还用到了机器学习算法(聚类.线性回归等).为了 ...

  3. 免费开源!新学期必收藏的AI学习资源,从课件、工具到源码都齐了

    (图片付费下载于视觉中国) 整理 | Jane 出品 | AI科技大本营(ID:rgznai100) 2019 年 3 月 28 日,教育部公布了 2018 年度普通高等学校本科专业备案和审批结果,共 ...

  4. 可视化工具gephi源码探秘(二)---导入netbeans

    在上篇<可视化工具gephi源码探秘(一)>中主要介绍了如何将gephi的源码导入myeclipse中遇到的一些问题,此篇接着上篇而来,主要讲解当下通过myeclipse导入gephi源码 ...

  5. git工具 将源码clone到本地指定目录的三种方式

    git工具 将源码clone到本地指定目录的三种方式 CreationTime--2018年7月27日15点34分 Author:Marydon 1.情景展示 运行git-bash.exe,输入命令: ...

  6. apk源码查看工具_如何查看Linux命令工具的源码?

    点击上方「嵌入式大杂烩」,「星标公众号」第一时间查看精彩文章! 上一篇分享了两个使用的小工具:<如何同时输出调试信息到终端及文件?>.有位小伙伴留言问道tee工具的代码在哪: 这篇文章我们 ...

  7. 玖云个人导航API工具网站源码

    介绍: 玖云个人导航API工具网站源码,简洁个人导航网站主页,附带几个可用的API接口,随机背景图,带简单后台. 源码安装方法: 上传源码,配置config.php文件 导入数据库install.sq ...

  8. 最新鲁班H5页面生成工具系统源码+功能强大/仿易企秀

    正文: 最新鲁班H5页面生成工具系统源码+功能强大/仿易企秀,这系统的功能真的非常强大,都是主流很高级的一些技术开发的. Vue2.0开发,通过拖拽的形式,生成页面的工具,类似易企秀.百度H5等工具. ...

  9. 最新SEO外链自动发布外链工具网站源码开源

    正文: SEO外链自动发布外链工具网站源码开源无加密,解压至服务器压缩即可使用.使用Layui框架编写,搜集了9602条优秀链接.包括百度.爱站..等等. 网站自动化宣传机器/SEO外链工具. (新站 ...

最新文章

  1. 测试linux写文件系统,linux下各主要文件系统的读写性能测试
  2. 《JavaScript面向对象精要》——第1章 原始类型和引用类型1.1 什么是类型
  3. challenging and foundational
  4. IOS - IPhone或IPAD,如何恢复出厂操作系统?
  5. Google 插件总览
  6. mysql data transfer_MySQL主从同步加速 Transfer-- FAQ
  7. 互联网晚报 | 10月30日 星期六 | 微软市值超越苹果;华为前三季度销售收入4558亿元;《长津湖》成2021全球票房冠军...
  8. 帐篷篷房建筑建材产品营销型网站源码 dedecms织梦模板
  9. java向kafka推送数据_Java编写程序将数据存入Kafka中
  10. 导入虚拟机vmware,此主机支持Intel VT-x,但Intel VT-x处于禁用状态和黑屏
  11. 计算机与科学a,[第一单元] 计算机与计算机科学-课文A参考译文
  12. win7 注册表禁 com服务器,Win7系统注册表禁用USB和启用USB接口方法
  13. 《2022 中国开源贡献度报告》首次发布!
  14. 宇宙APP简单的性能测试
  15. html5_滑条等其他标签
  16. log4j在maven项目中的使用
  17. python视觉识别定位_机器视觉以及验证码识别
  18. Quick #UE4 Tip (第3周 2020.4.10)
  19. [Java] MVC 编写程序计算净现值 2020.2.25 Java
  20. 关于抖音网红推广,你想知道的50个问题都在这里!

热门文章

  1. C# 调用 Microsoft.VisualBasic.Collection
  2. 聚类、K-Means、例子、细节
  3. mui 与jquery 同时使用,$冲突解决办法。
  4. MySQL基础部分总结
  5. redis终端简单命令
  6. 【Android Studio安装部署系列】目录
  7. I00005 打印直角三角形字符图案
  8. 解密阿里云七武器之高性能消息服务ONS
  9. U-Mail邮件服务系统任意文件上传+执行漏洞(runtime缺陷与验证绕过)
  10. OSPF区域不能与area 0 相连的解决方法