[Linux] diff and patch

Links: https://www.cnblogs.com/cocowool/p/6409643.html

Linux in the Diff and Patch

The main learning recording paper two commands: diff and patch. diff and patch a pair of tools, the use of this tool can get the difference update files and history files, and updates to the history file. In mathematics, said, diff is the difference between the two sets of operations, patch is a collection of two and operations.

Simple example

Use this example to illustrate how to compare and patch files.

There are two files original.txt and updated.txt, as follows:

#include <stdio.h>

function old(){
        printf("This is a file\n");

        return 0;
}
#include stdio.h

function new(){
        printf("This is b file\n");
        return 0;
}

Execution  diff original.txt updated.txtresult for

The following first appeared in the results of some of the symbols of some explanation. 1,4c1The contents of this output is actually to look at the patch, patch represents 1 Dao told the four lines in original.txt file should be replaced in the content updated.txt, replacing the content is updated.txt first row. There may appear three letters represent different meanings, namely, c represents the update, a represents an additional, d for delete.

c represents the original document m, the content of n lines to be replaced the contents of the updated file.
a represents an additional, then the number on the left is only a number, but not a range, represent an additional right side to the original digital file representing the content.
d represents deleted. The number on the left may be a range, representing the content to be deleted, the right is a number that is not deleted if what position should appear in the updated document. Some people may think that behind the numbers is superfluous, because the patch is to retain this number can be used in reverse.
<It represents the patch should delete the contents of the back of the sign.
>Represents the patch should be added behind this sign.

Learn the output of diff, which created a patch to the original file. The output is actually diff patch, we can directly save the output to a file, you can use the pipe symbol to do this, as follows:

diff original.txt updated.txt > mypatch.patch

Then we have a patch file, original file can be updated to the updated files.

patch original.txt -i my patch.patch -o updated-1.txt

This command will generate a new file, you can see that our previous update.txtw file exactly the same.

Context Patch

The results previously observed pattern diff given the need to replace the position, only gives the line number, if the file suddenly add a blank line when the patch application problem occurs. Alternatively, if the patch file to the source of the error on a file, if the file happens to have the same number of rows, then the patch can be applied successfully. And this is we do not want to see the results. Fortunately, diff provides a different result patterns to avoid these problems above.

diff -c original.txt updated.txt

Comparison of the results contained in the file name, so that when we apply the patch, do not enter the file name, saving time and avoiding the file name input errors possible. File modification time and went after the file name. Further down is 15 asterisk (*) represents the contents of the file to replace, update, delete, and so on. *And -digital or digital representation of the range that contains the line number, !beginning with the need to replace the contents of representation, -expressed the need to remove content, expressed the need to increase the content, patch file will be updated based on this context.

patch -i mypatch2.patch -o updated.txt

Note that here if you do not specify an output file, the source file will be updated (it's actually the role of the patch file). Usually we will apply the patch to the source file, usually requires multiple files for processing.

Comparing multiple files and apply the patch

Compare multiple files easiest way is to directly command followed by folder, for example, if it contains subfolders, remember to add -r parameter.

diff originaldirectory updateddirectory 

We can also look at the results of the comparison context

RousseaudeMacBook-Pro:diff rousseau$ diff -c original update
diff -c original/function.txt update/function.txt
*** original/function.txt     Fri Feb 17 09:41:26 2017
--- update/function.txt     Fri Feb 17 09:42:06 2017
***************
*** 1,5 ****
! #includ <stdio.h>

  function main(){
       return 1;
  }
--- 1,8 ----
! #include <stdio.h>
! #include <stdlib.h>

  function main(){
+      printf("This is function main\n");
+
       return 1;
  }
diff -c original/original.txt update/original.txt
*** original/original.txt     Fri Feb 17 09:40:29 2017
--- update/original.txt     Fri Feb 17 09:40:51 2017
***************
*** 1,9 ****
  #include <stdio.h>

! function old(){
!      printf("This is a file\n");

       return 0;
  }

- void 0;
--- 1,8 ----
  #include <stdio.h>

! function newd(){
!      printf("This is a new file\n");

       return 0;
  }

Let's look at how to apply the patch for multiple files, first generate a patch file, we still use context format.diff -c original update > directory.patch

在一个新的目录下拷贝 original 文件夹和补丁文件,执行 patch -i directory.patch,此时会提示找不到文件,因为patch会在当前文件夹查找文件(默认情况下patch会将文件名前的所有文件夹去掉)因为此时补丁文件在文件夹外面,所以我们应当告诉patch不要这么做,使用-p参数。

patch -p0 -i directory.patch

也许有人会问,如果我把补丁文件移动到文件夹中进行打补丁操作不就可以了嘛,注意千万不要这么做。如果文件夹中还有子文件夹,那么patch不会到子文件夹中寻找文件,这样就会对结果产生影响,特别是在不同文件夹中有相同名字的文件的时候。

还原补丁文件的操作

有时候版本需要进行回撤,这时可以使用 -R 参数。

patch -p0 -R -i directory.patch

Unified Format

GNU的diff和patch还提供了一种格式,称为 the unified format。这个格式更加精简,与上下文格式类似。但是不再将源文件和更新文件分开,而是组合在一起。并且没有特殊的替换标志,只有-+

diff -u original update

写在最后

对文本文件进行patch操作时,提前备份是一个好习惯,这可以避免你在弄错的情况下,面临一堆无法恢复的文件发愁。

参考资料:
1、Using Diff and patch
2、Diff比较两个文件夹
3、GNU Diff and patch


发布了140 篇原创文章 · 获赞 28 · 访问量 18万+

Guess you like

Origin blog.csdn.net/qq_16097611/article/details/80183573