diff and patch

简介:
 转两篇diff和patch的文章, 打补丁相关.
第一篇 : 
情景一:你正尝试从代码编译一个软件包,发现有人已经对代码进行了小小的修改以便在你的系统上编译。他们通过补丁的方式发布自己的成果,但是你却不知道该如何使用它。答案是你使用一个叫做patch(很贴切)的命令行工具将补丁应用到原始代码上。 

情景二:你下载了一个开源软件包的代码,花了一个小时左右稍作修改,成功的让它在你的系统上编译通过。你想把自己的成果分享给其他程序员,或者给软件包的作者。现在你就需要创建自己的补丁,你需要的工具是diff。 

这是一份diff和patch的快速指南,通过讲解它们最常见的用法来帮你解决上面问题。它告诉你的东西足够让你立刻开始使用。之后,你可以在闲暇的时候用manpage来学习diff和patch的前前后后。我总是乐意听到你们的问题和意见。用联系表单跟我取得联系。 

用patch命令应用补丁 

要对单个文件应用补丁,进入文件所在的目录并调用patch命令: 

patch < foo.patch 

这些命令假定补丁是以统一格式分发的,这种格式指明了补丁要应用到的文件。如果不是,你可以在命令行里指定文件: 

patch foo.txt < bar.patch 

应用补丁到整个目录(这种情况也许更常见)也是类似的,但是你必须注意设置p级别。就是说,在补丁文件里,需要打补丁的文件在你电脑上的路径名跟在创建补丁的电脑上可能不同。p级别告诉patch命令忽略掉路径名的几个部分以正确的识别文件。通常p级别为1就够了,所以你使用: 

patch -p1 < bar.patch 

运行该命令之前,你应该进入源代码目录的顶层目录。如果补丁级别1不能正确识别任何需要打补丁的文件,检查补丁文件里的文件名。如果你看到这样一个文件名: 

/users/stephen/package/src/net/http.c 

而你当前正工作在一个包含net/http.c的目录,使用: 

patch -p5 < bar.patch 

总的来说,对于从路径最开始删除的每个路径分隔符(斜线字符)加一,直到剩下的部分存在于你的工作目录中。最后得到的就是p级别。 

要删除补丁,用-R参数,例如: 

patch -p5 -R bar.patch 

使用diff创建补丁 

不论是对于单个文件还是整个源码目录,使用diff都很简单。为单个文件创建补丁,用下面形式: 

diff -u original.c new.c > original.patch 

为整个源码树创建补丁,复制一份源码树: 

cp -R original new 

在目录new/里进行必要的修改,然后用下面的命令创建补丁: 

diff -rupN original/ new/ > original.patch 

这就是diff和patch入门需要的所有知识。要获得更多的信息用: 

man diff 
man patch

第二篇 : 
diff和patch是一对工具,在数学上来说,diff是对两个集合的差运算,patch是对两个集合的和运算。

  diff比较两个文件或文件集合的差异,并记录下来,生成一个diff文件,这也是我们常说的patch文件,即补丁文件。

  patch能将diff文件运用于 原来的两个集合之一,从而得到另一个集合。举个例子来说文件A和文件B,经过diff之后生成了补丁文件C,那么着个过程相当于 A -B = C ,那么patch的过程就是B+C = A 或A-C =B。

  因此我们只要能得到A, B, C三个文件中的任何两个,就能用diff和patch这对工具生成另外一个文件。

  这就是diff和patch的妙处。下面分别介绍一下两个工具的用法:

  1. diff的用法

  diff后面可以接两个文件名或两个目录名。 如果是一个目录名加一个文件名,那么只作用在那么个目录下的同名文件。

  如果是两个目录的话,作用于该目录下的所有文件,不递归。如果我们希望递归执行,需要使用-r参数。

  命令diff A B >C ,一般A是原始文件,B是修改后的文件,C称为A的补丁文件。

  不加任何参数生成的diff文件格式是一种简单的格式,这种格式只标出了不一样的行数和内容。我们需要一种更详细的格式,可以标识出不同之处的上下文环境,这样更有利于提高patch命令的识别能力。这个时候可以用-c开关。

  2. patch的用法

  patch用于根据原文件和补丁文件生成目标文件。还是拿上个例子来说

  patch A C 就能得到B, 这一步叫做对A打上了B的名字为C的补丁。

  之一步之后,你的文件A就变成了文件B。如果你打完补丁之后想恢复到A怎么办呢?

  patch -R B C 就可以重新还原到A了。

  所以不用担心会失去A的问题。

  其实patch在具体使用的时候是不用指定原文件的,因为补丁文件中都已经记载了原文件的路径和名称。patch足够聪明可以认出来。但是有时候会有点小问题。比如一般对两个目录diff的时候可能已经包含了原目录的名字,但是我们打补丁的时候会进入到目录中再使用patch,着个时候就需要你告诉 patch命令怎么处理补丁文件中的路径。可以利用-pn开关,告诉patch命令忽略的路径分隔符的个数。举例如下:

  A文件在 DIR_A下,修改后的B文件在DIR_B下,一般DIR_A和DIR_B在同一级目录。我们为了对整个目录下的所有文件一次性diff,我们一般会到DIR_A和DIR_B的父目录下执行以下命令

  diff -rc DIR_A DIR_B >C

  这个时候补丁文件C中会记录了原始文件的路径为 DIR_A/A

  现在另一个用户得到了A文件和C文件,其中A文件所在的目录也是DIR_A。 一般,他会比较喜欢在DIR_A目录下面进行patch操作,它会执行

  patch

  但是这个时候patch分析C文件中的记录,认为原始文件是./DIR_A/A,但实际上是./A,此时patch会找不到原始文件。为了避免这种情况我们可以使用-p1参数如下

  patch -p1

  此时,patch会忽略掉第1个”/”之前的内容,认为原始文件是 ./A,这样就正确了。

  最后有以下几点注意:

  1. 一次打多个patch的话,一般这些patch有先后顺序,得按次序打才行。

  2. 在patch之前不要对原文件进行任何修改

  3. 如果patch中记录的原始文件和你得到的原始文件版本不匹配(很容易出现),那么你可以尝试使用patch, 如果幸运的话,可以成功。大部分情况下,会有不匹配的情况,此时patch会生成rej文件,记录失败的地方,你可以手工修改。

[转3]
Quick-n-Dirty Guide to Creating and Applying diff-style Patches

1) DO YOU HAVE DIFF AND PATCH?
------------------------------

In a shell, type:

which diff
which patch

This should return the paths to diff and patch, probably /usr/bin/diff
and /usr/bin/patch, respectively. If it finds them, continue to Step
2. If it does not, you have a serious problem, as diff and patch are
two of the most fundamental utilities in a Unix system. Hopefully,
your $PATH environment variable just does not contain the proper paths
to the binaries. Try typing in a shell:

for i in /bin /usr/bin /usr/local; do
    find $i -name diff
    find $i name patch
done

If this returns a full path to diff and patch, note that path, then
add it to your $PATH by typing:

export PATH=$PATH:diff_path:patch_path

where diff_path is the path to the diff binary (take the /diff off
the end of what the find command reported for diff) and patch_path
is the path to the patch binary (take the /patch off the end of what
the find command reported for patch). Now, repeat this step, and the
'which' commands should find both diff and patch. If they do, continue
to Step 2. If not, try contacting your local LUG for help. *** Link to
the Help Me! QND ***


2) CREATING PATCHES WITH DIFF
-----------------------------

In a shell, change to the directory where the file you wish to make a
patch for is located. Copy the original file (before your edits) to
the same directory (you *did* make a backup copy of it before you
edited it, right?). Now, type in the shell:

diff -uN original_file new_file >patch.original_file

where original_file is the filename of the original file and new_file
is the filename of the new file (the one containing your edits).

This technique also works for creating a patch for a whole directory
tree (e.g. creating a Linux kernel patch). Just add the -r flag to
your diff command:

diff -uNr original_dir new_dir >patch.original_dir

Here is a concrete example of creating a patch against the vanilla
Linux kernel's source tree:

cd /usr/src
diff -uNr linux-2.4.19 linux-2.4.19-my_version \
          >patch.linux-2.4.19-my_version

That is all there is to creating patches with diff. Move on to Step 3
to see how to apply them with patch.


3) APPLYING PATCHES WITH PATCH
------------------------------

Copy the patch that you generated in Step 2 to the directory
containing the file to which you want to apply the patch. Now, type in
your shell:

patch <patch_file

where patch_file is the filename of the patch file. Note that the
filename of the file to be patched must be the same as it was in Step
2.

If you want to apply a patch to a whole directory tree, add a -p1 to
your patch command:

patch -p1 <patch_file

Here is a concrete example of applying a patch to your Linux kernel
source tree:

cd /usr/src
patch -p1 <patch.linux-2.4.19-my_version

Congratulations, you are finished.



REFERENCES
----------

For more information on diff and patch, see:

http://www.gnu.org/software/diffutils/diffutils.html
http://www.gnu.org/manual/diffutils/html_mono/diff.html
相关文章
|
开发工具 git
git diff 生成patch合入代码
git diff 生成patch合入代码
468 0
|
24天前
|
Linux
diff与patch的使用
diff与patch的使用
13 1
|
10月前
|
移动开发
diff和patch的使用简介
diff和patch的使用简介
|
前端开发 API
patch使用
+ put:对所有资源进行更新 + patch:对部分资源进行更新 put使用方法和post相同,但是put是幂等的。
|
开发工具 git
生成patch
生成patch
|
监控
Dispatch Source 应用
Dispatch Source 源是一个偏底层的函数集合,使用时CPU负荷非常小,尽量不占资源,开发过程中大多是配合定时器使用。
163 0
|
Linux Shell 开发工具
使用 diff 和 patch 命令协同开发
使用 diff 和 patch 命令协同开发
155 0
使用 diff 和 patch 命令协同开发
|
Linux Perl 开发工具
|
Android开发
一分钟学会使用9-patch
背景 之前项目开发一般都是写逻辑,UI方面的操作用的比较少。 图片也是直接使用设计师提供的。 因此一般情况下不需要用到9-patch图。 然而,最近项目中分配给我的功能用到了。
1451 0