给代码打patch需要用到两个工具——diff和patch,它们都是linux系统上工具,我们可以很放心的使用。

        diff工具是用于生成补丁文件的。比如依赖库文件中文件A.cpp有bug,我们修改了bug并将文件另存为A_modify.cpp,这样通过下面命令生成补丁文件A_patch.cpp

diff -up A.cpp A_modify.cpp > A_patch.cpp

        

        在编译前,调用下面指令将补丁临时放到依赖库的A.cpp中

patch -p0 < A_patch.cpp

        

        这个时候A.cpp代码就已经没有bug了,我们执行编译。等编译结束后,我们可以使用下面指令,还原A.cpp到原始的内容,即去除补丁

patch -RE -p0 < A_patch.cpp

      

什么是patch

patch即补丁之意,记录文件中的不同,能够与文件进行整合,从而改变文件中的内容。

patch命令用于将补丁文件应用到源代码文件中,以实现对源代码的修改。补丁文件通常是由开发者或者社区提供的,用于修复源代码中的错误或者添加新功能。

语法
patch [选项] [补丁文件]

选项
-p<num>:指定路径剥离级别,用于去除补丁文件中的路径前缀。通常在patch补丁文件中会包含源代码文件的相对路径,使用该选项可以去除这些路径前缀。
-d <目录>:指定工作目录,用于在指定目录下执行补丁操作。
-N:允许添加新文件,即如果补丁文件中包含新文件,patch命令会将其添加到源代码中。
-R:撤销已应用的补丁,即将补丁文件中的修改恢复到源代码文件中。
-s:安静模式,即不显示详细的操作信息。
-i <文件>:指定补丁文件的路径。

如何制作patch

在Linux系统中提供了diff程序,可以使用diff程序,比较文件之间的不同从而制作出patch文件

  1. 在系统中(我用的是Ubuntu)创建diff文件夹,创建test1.txt,test2.txt
    mkdir diff
    vi test1.txt
    vi test2.txt

    test1.txt文件内容如下

    aaaa

    test2.txt文件内容如下

    aaaa
    bbbb
  2. 使用diff命令制作patch文件
  3. diff -Naur test1.txt test2.txt > test.patch

    之后在当前目录中会存在三个文件

    test1.txt test2.txt test.patch

    test.patch 文件的内容

    --- test1.txt   2018-08-01 13:17:33.530350672 +0800
    +++ test2.txt   2018-08-01 13:18:54.326350260 +0800
    @@ -1 +1,2 @@ 
     aaaa
    +bbbb

    diff参数解释
         -N 在比较目录时如果某个文件只出现了一次,那么在比较不同时会默认和空文件比较
              -a 将所有的文件都作为普通text(之比较文本文件)
             -u 以合并的方式显示文件内容的不同
             -r 如果是文件夹则进行递归进行比较

如何使用patch

1.准备好patch文件和原版本文件
创建patch文件夹,将test1.txt 和test.patch文件拷贝进去

mkdir patch
cp test1.txt test.patch../patch/

  2.执行patch命令

patch -p0 < test.patch

  3.test1.txt文件内容如下

aaa
bbb

  可以看到patch已经打进去了


-pX参数介绍:
  patch命令中最常用的就是-pX这个参数
  在上面我们注意到patch文件如下内容

--- test1.txt   2018-08-01 13:17:33.530350672 +0800

  此时我们的参数为-p0,此时patch 就会在当前目录下寻找test1.txt文件,如在在patch文件中是这样记录的

---a/b/test1.txt   2018-08-01 13:17:33.530350672 +0800

  那么-p0会在当前目录下寻找a目录,a目录下寻找b,之后在b中寻找test1.txt文件。
  如果是 -p1,patch命令就会舍弃a,先寻找b再寻找test1.txt
  如果是-p2 ,会舍弃a/b,直接寻找test1.txt
  所以-pX中 X代表就是所要舍弃的层级目录

补充: 

  -p0 选项要从当前目录查找目的文件(夹)

  -p1 选项要忽略掉patch文件第一行里面第一层目录,从当前目录开始查找。

  ************************************************************

  在这里以实例说明:

    ---old/modules/pcitable            Mon Sep 27 11:03:561999

    +++new/modules/pcitable       Tue Dec 19 20:05:412000

    如果使用参数-p0,那就表示从当前目录找一个叫做old的文件夹,在它下面寻找modules下的pcitable文件来执行patch操作。

    如果使用参数-p1,那就表示忽略第一层目录(即不管old),从当前目录寻找modules的文件夹,在它下面找pcitable。

    这样的前提是当前目录必须为modules所在的目录。而diff补丁文件则可以在任意位置,只要指明了diff补丁文件的路径就可以了。

    当然,可以用相对路径,也可以用绝对路径。不过我一般习惯用相对路径。

  ************************************************************

  -E  选项说明如果发现了空文件,那么就删除它

  -R  选项说明在补丁文件中的“新”文件和“旧”文件现在要调换过来了(实际上就是给新版本打补丁,让它变成老版本)

  简单的示例:

    方式一:$patch File0.cpp diff.patch

    方式二:$patch -p0 < diff.patch

  通过下面的命令,可以去除补丁,恢复旧版本

    $ patch -RE -p0 < diff.patch

  patch文件的结构

  (1)补丁头:

    补丁头是分别由---/+++开头的两行,用来表示要打补丁的文件。---开头表示旧文件,+++开头表示新文件。

  (2)块:

    块是补丁中要修改的地方。它通常由一部分不用修改的东西开始和结束。他们只是用来表示要修改的位置。他们通常以@@开始,结束于另一个块的开始或者一个新的补丁头。

  块的缩进:块会缩进一列,而这一列是用来表示这一行是要增加还是要删除的。

  块的第一列:

    +号表示这一行是要加上的。

    -号表示这一行是要删除的。

  没有加号也没有减号表示这里只是引用的而不需要修改。

--- File0.cpp    2013-08-01 13:40:35.579447633 +0800
+++ File1.cpp    2013-08-01 13:41:04.609447640 +0800
@@ -1 +1 @@
-The First file.
+The Second File.

  patch还有很多参数,但是-pX是最为常用的

  简单的说,patch就是利用diff制作的补丁来实现源文件(夹)和目的文件(夹)的转换。这样说就意味着你可以由源文件(夹)――>目的文件(夹),也可以由目的文件(夹)――>源文件(夹)。


原文链接:

https://blog.csdn.net/qq_21438461/article/details/131362485

https://www.cnblogs.com/xingboy/p/15954771.html

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐