补丁(patch)的制作与应用

为什么80%的码农都做不了架构师?>>>   hot3.png

转自http://linux-wiki.cn/wiki/zh-hans/%E8%A1%A5%E4%B8%81(patch)%E7%9A%84%E5%88%B6%E4%BD%9C%E4%B8%8E%E5%BA%94%E7%94%A8

如果hack了开源代码,为了方便分享(如提交Bug)或自己留存使用,一般都要制作一个补丁(Patch)。在从源码安装软件时,也难免要应用些别人做好的补丁。本文介绍如何制作和应用补丁。[1]

Hint.gif
提示: 
本文目前的多数内容是对《Linux下patch的制作和应用》的修正、整理与重新排版。

目录

[隐藏]
  • 1 命令简介
    • 1.1 diff
    • 1.2 patch
    • 1.3 应用
  • 2 patch文件构成
  • 3 实例分析
    • 3.1 单文件补丁
    • 3.2 文件夹补丁
  • 4 参考资料

命令简介

用到的两个命令是diff和patch。

diff

diff可以比较两个东西,并可同时记录下二者的区别。制作补丁时的一般用法和常见选项为:

diff 【选项】 源文件(夹) 目的文件(夹)
-r 递归。设置后diff会将两个不同版本源代码目录中的所有对应文件全部都进行一次比较,包括子目录文件。 -N 选项确保补丁文件将正确地处理已经创建或删除文件的情况。 -u 输出每个修改前后的3行,也可以用-u5等指定输出更多上下文。 -E, -b, -w, -B, --strip-trailing-cr 忽略各种空白,可参见文档,按需选用。

patch

patch的作用则是将diff记录的结果(即补丁)应用到相应文件(夹)上。最常见的用法为:

patch -pNUM <patchfile>
-p Num 忽略几层文件夹,随后详解。 -E 选项说明如果发现了空文件,那么就删除它 -R 取消打过的补丁。

为了解释 -p 参数,需要看看如下patch文件片段:

--- old/modules/pcitable       Mon Sep 27 11:03:56 1999
+++ new/modules/pcitable       Tue Dec 19 20:05:41 2000

如果使用参数 -p0,那就表示从当前目录找一个叫做old的文件夹,再在它下面寻找 modules/pcitable 文件来执行patch操作。
而如果使用参数 -p1,那就表示忽略第一层目录(即不管old),从当前目录寻找 modules 的文件夹,再在它下面找pcitable。

应用

利用以上命令,处理单个文件补丁的方法:

# 产生补丁
diff -uN from-file to-file >to-file.patch# 打补丁
patch -p0 < to-file.patch# 取消补丁
patch -RE -p0 < to-file.patch

对整个文件夹打补丁的情况:

# 产生补丁
diff -uNr  from-docu  to-docu  >to-docu.patch# 打补丁
cd to-docu
patch -p1 < to-docu.patch# 取消补丁
patch -R -p1 <to-docu.patch

另外,使用版本控制工具时,可以直接用svn diffgit diff生成补丁文件。

值得一提的是,由于应用补丁时的目标代码和生成补丁时的代码未必相同,打补丁操作可能失败。补丁失败的文件会以.rej结尾,下面命令可以找出所有rej文件:

find . -name '*.rej'

patch文件构成

补丁文件里到底存储了哪些信息呢?看看这个例子:

--- test0       2006-08-18 09:12:01.000000000 +0800
+++ test1       2006-08-18 09:13:09.000000000 +0800
@@ -1,3 +1,4 @@
+222222111111
-111111
+222222111111
补丁头 补丁头是分别由---/+++开头的两行,用来表示要打补丁的文件。---开头表示旧文件,+++开头表示新文件。 一个补丁文件中的多个补丁 一个补丁文件中可能包含以---/+++开头的很多节,每一节用来打一个补丁。所以在一个补丁文件中可以包含好多个补丁。 块 块是补丁中要修改的地方。它通常由一部分不用修改的东西开始和结束。他们只是用来表示要修改的位置。他们通常以@ @开始 ,结束于另一个块的开始或者一个新的补丁头。 块的缩进 块会缩进一列,而这一列是用来表示这一行是要增加还是要删除的。 块的第一列 +号表示这一行是要加上的。-号表示这一行是要删除的。没有加号也没有减号表示这里只是引用的而不需要修改。

实例分析

单文件补丁

设当前目录有文件 test0

111111
111111
111111

和文件test1

222222
111111
222222
111111

使用diff创建补丁test1.patch

diff -uN test0 test1 > test1.patch

因为是单个文件,故不需要 -r 选项。此命令得到如下补丁:

--- test0       2006-08-18 09:12:01.000000000 +0800
+++ test1       2006-08-18 09:13:09.000000000 +0800
@@ -1,3 +1,4 @@
+222222111111
-111111
+222222111111

要应用补丁,只需:

$ patch -p0 < test1.patch
patching file test0

此时test0就和test1一样了。

如果要取消补丁做出的更改,恢复旧版本:

$ patch -RE -p0 < test1.patch
patching file test0

文件夹补丁

设有如下环境:

--prj0/test0prj0name
--prj1/test1prj1name

prj0/prj0name内容为如下三行:

--------
prj0/prj0name
--------

prj1/prj1name内容为如下三行:

--------
prj1/prj1name
--------

用 diff -uNr 创建补丁,

diff -uNr prj0 prj1 > prj1.patch

得到的patch文件为:

diff -uNr prj0/prj0name prj1/prj0name
--- prj0/prj0name       2006-08-18 09:25:11.000000000 +0800
+++ prj1/prj0name       1970-01-01 08:00:00.000000000 +0800
@@ -1,3 +0,0 @@
---------
-prj0/prj0name
---------
diff -uNr prj0/prj1name prj1/prj1name
--- prj0/prj1name       1970-01-01 08:00:00.000000000 +0800
+++ prj1/prj1name       2006-08-18 09:26:36.000000000 +0800
@@ -0,0 +1,3 @@
+---------
+prj1/prj1name
+---------
diff -uNr prj0/test0 prj1/test0
--- prj0/test0  2006-08-18 09:23:53.000000000 +0800
+++ prj1/test0  1970-01-01 08:00:00.000000000 +0800
@@ -1,3 +0,0 @@
-111111
-111111
-111111
diff -uNr prj0/test1 prj1/test1
--- prj0/test1  1970-01-01 08:00:00.000000000 +0800
+++ prj1/test1  2006-08-18 09:26:00.000000000 +0800
@@ -0,0 +1,4 @@
+222222
+111111
+222222
+111111

如果要应用此补丁,则:

$ ls
prj0  prj1  prj1.patch
$ cd prj0
$ patch -p1 < ../prj1.patch
patching file prj0name
patching file prj1name
patching file test0
patching file test1

此时可用ls看到打补丁后的结果:

$ ls
prj1name  test1

类似的,如果要回滚补丁操作:

$ patch -R -p1 < ../prj1.patch
patching file prj0name
patching file prj1name
patching file test0
patching file test1
$ ls
prj0name  test0

参考资料

  1. ↑ Linux下patch的制作和应用

本文对您有帮助?分享给更多朋友!

 

转载于:https://my.oschina.net/mskk/blog/892666

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/541440.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php知识点汇总与解答_PHP操作员能力倾向问题与解答

php知识点汇总与解答This section contains Aptitude Questions and Answers on PHP Operators. 本节包含有关PHP运算符的 Aptitude问答。 1) Which of the following types of operators are used in PHP? Arithmetic OperatorsLogical OperatorsArray OperatorsString Oper…

csv导入mysql phpmyadmin_【转】从phpMyAdmin批量导入Excel内容到MySQL(亲测非常简洁有效)...

今天做项目遇到需要用phpMyAdmin批量导入Excel内容到MySQL数据库。分析了我的踏坑经历并且总结一最便捷的一套导入数据的方法&#xff0c;非常实用简洁&#xff1a;1、修改Excel表的数据&#xff0c;使得Excel中的字段与数据库字段要一一对应&#xff0c;并加上自增id。2、然后…

weakhashmap_Java WeakHashMap putAll()方法与示例

weakhashmapWeakHashMap类的putAll()方法 (WeakHashMap Class putAll() method) putAll() method is available in java.util package. putAll()方法在java.util包中可用。 putAll() method is used to copy all of the associations or mappings from the given map and assig…

c语言memcmp和java的_C语言memcmp()函数:比较m字节长的两个字符串s1和s2

函数名&#xff1a;memcmp头文件&#xff1a;函数原型&#xff1a; void* memcmp(void *s1,void *s2,unsigned m);功能&#xff1a;比较m字节长的两个字符串s1和s2参数&#xff1a; s1 和 s2 为要比较的字符串unsigned m 为要比较的前m个字节返回值&#xff1a;s1s1s2 返回等…

[下载地址] Subclipse 1.10.9(SVN) _附说明

http://pan.baidu.com/s/1bp6EFHt转载于:https://www.cnblogs.com/gscq073240/articles/6814429.html

hbase 伪分布安装 java_HBase基础和伪分布式安装配置

一、HBase(NoSQL)的数据模型1.1 表(table)&#xff0c;是存储管理数据的。1.2 行键(row key)&#xff0c;类似于MySQL中的主键&#xff0c;行键是HBase表天然自带的&#xff0c;创建表时不需要指定1.3 列族(column family)&#xff0c;列的集合。一张表中有多个行健&#xff0c…

java treemap_Java TreeMap firstEntry()方法及示例

java treemapTreeMap类的firstEntry()方法 (TreeMap Class firstEntry() method) firstEntry() method is available in java.util package. firstEntry()方法在java.util包中可用。 firstEntry() method is used to retrieve the key-value pairs linked with the lowest valu…

linux常用网络命令ping和arping

linux常用网络命令ping和arping ping 向目标主机发送icmp请求包 常用来测试当前主机与目标主机网络连接状况 常见选项 -c 设置发包的个数 -s 设置发的包的块大小&#xff0c;最大不超过65507 -W 设置接收回应超时时间 -i …

java printwriter实例_PrintWriter做过滤流+FileWriter案例分析

package com.mstf.ui;import java.io.*;public class TestWriter{public static void main(String args[]){//PrintWriter做过滤流FileWriter//doFilter1();//2、PrintWriter做过滤流OutputStreamWriter//doFilter2();//3、PrintWriter可以作为节点流//doNode();//4、PrintWrit…

treemap比较器_Java TreeMap比较器()方法与示例

treemap比较器TreeMap类的compare()方法 (TreeMap Class comparator() method) comparator() method is available in java.util package. 比较器()方法在java.util包中可用。 comparator() method is used to return the key element in this TreeMap based on the Comparator…

洛谷P1204 [USACO1.2]挤牛奶Milking Cows 前缀和

这题数据比较水 暴搜都能够过去 1 #include <cstdio>2 #include <cmath>3 #include <cstdlib>4 #include <algorithm>5 #include <string>6 #include <iostream>7 #include <iomanip>8 #include <cstring>9 using namespace s…

java script创建对象_JavaScript七种非常经典的创建对象方式

JavaScript创建对象的方式有很多&#xff0c;通过Object构造函数或对象字面量的方式也可以创建单个对象&#xff0c;显然这两种方式会产生大量的重复代码&#xff0c;并不适合量产。接下来介绍七种非常经典的创建对象的方式&#xff0c;他们也各有优缺点。一、工厂模式可以无数…

java 方法 示例_Java扫描仪具有示例的NextNextInt()方法

java 方法 示例扫描器类的hasNextInt()方法 (Scanner Class hasNextInt() method) Syntax: 句法&#xff1a; public boolean hasNextInt();public boolean hasNextInt(int rad);hasNextInt() method is available in java.util package. hasNextInt()方法在java.util包中可用…

axis2开发webservice之编写Axis2模块(Module)

axis2中的模块化开发。能够让开发者自由的加入自己所需的模块。提高开发效率&#xff0c;减少开发的难度。 Axis2能够通过模块&#xff08;Module&#xff09;进行扩展。Axis2模块至少须要有两个类&#xff0c;这两个类分别实现了Module和Handler接口。开发和使用一个Axis2模块…

java 看书浏览器官_JAVA读取文件流,设置浏览器下载或直接预览操作

最近项目需要在浏览器中通过url预览图片。但发现浏览器始终默认下载&#xff0c;而不是预览。研究了一下&#xff0c;发现了问题&#xff1a;// 设置response的header&#xff0c;注意这句&#xff0c;如果开启&#xff0c;默认浏览器会进行下载操作&#xff0c;如果注释掉&…

Java PriorityQueue poll()方法与示例

PriorityQueue类poll()方法 (PriorityQueue Class poll() method) poll() method is available in java.util package. poll()方法在java.util包中可用。 poll() method is used to return the first element with removing an element from this PriorityQueue. poll()方法用于…

scrapy抓取淘宝女郎

scrapy抓取淘宝女郎 准备工作 首先在淘宝女郎的首页这里查看&#xff0c;当然想要爬取更多的话&#xff0c;当然这里要查看翻页的url,不过这操蛋的地方就是这里的翻页是使用javascript加载的&#xff0c;这个就有点尴尬了&#xff0c;找了好久没有找到&#xff0c;这里如果有朋…

map在Java集合_java集合之Map

MapMap用于保存具有映射关系的数据。Map中key不允许重复&#xff0c;value可以重复&#xff0c;key和value之间存在单向一对一关系HashMap和Hashtable区别1 Hashtable线程安全、HashMap线程不安全&#xff0c;所以HashMap性能高一点2 Hashtable不允许用null做key和value&#x…

Java OutputStream close()方法与示例

OutputStream类close()方法 (OutputStream Class close() method) close() method is available in java.io package. close()方法在java.io包中可用。 close() method is used to close this OutputStream stream and free all system resources linked with this stream and …

怎样在fastboot 里面加入新的命令

fastboot 是android 默认的一种debug 方法。它的优点是在进入linux kernel 之前就可以操作。默认fastboot 支持的命令&#xff1a; usage: fastboot [ <option> ] <command>commands: update <filename> reflash device …