In-depth analysis of Linux diff and patch

Source: Internet
Author: User

Diff output formats are classified into traditional and unified formats.

1) output in the traditional diff format.

######################################## ####
Cat before.txt
Output:
This is a line to be deleted
This is a line that will be changed
This is a line that will be unchanged

Cat after.txt
Output:
This is a line that has been changed
This is a line that will be unchanged
This is a line that has been added
######################################## ####
Diff before.txt after.txt
Output:
1, 2C1
<This is a line to be deleted
<This is a line that will be changed
---
> This is a line that has been changed
3a3
> This is a line that has been added
######################################## ####

Note:
Output in traditional format
1, 2C1 refers to the replacement of the 1st rows of the 2nd files to the 2nd rows of the 1st files. Here, 1 and 2 refer to the rows of the files, and C refer to replacement, the last 1 is the 2nd rows of the 1st files.
<No. indicates the row in which 1st files are modified or deleted.
--- The number is used to separate two files.
> Number is the number of rows added or deleted from the 2nd files.
3a3 refers to inserting 2nd rows of 3rd files into 3rd rows of the first file
That is to say, the 1st files:
<This is a line to be deleted
<This is a line that will be changed
Replaced with 2nd files:
> This is a line that has been changed
The 1st rows of the 3rd files are the same as those of the 2nd rows of the 2nd files, so no modification is made.
Because the 2nd lines of the 3rd files are not available to the 1st files, add the following lines in the last row of the 1st files:
> This is a line that has been added

2) Application of patch commands

Output in the traditional diff format:
#################################
Diff before.txt after.txt> mypatch.txt
#################################

Use the patchpolicbefore.txt file to make before.txtconsistent with after.txt.
#################################
Cat mypatch.txt | patch before.txt
Output:
Patching file before.txt
#################################

Compare the two files. Now they are consistent.
#################################
CMP before.txt after.txt
#################################

Use the patchcommand to restore before.txt.
#################################
Patch-r before.txt <mypatch.txt
Output:
Patching file before.txt
#################################

Note: The-r flag tells the patch to apply the difference or cancel the patch in the reverse direction.

Two more files are compared, and they are inconsistent now.
#################################
CMP before.txt after.txt
Output:
Before.txt after.txt differ: byte 17, line 1
#################################

3) diff unified format output.

#################################
Diff-u before.txt after.txt | tee mypatch. Diff
Output:
--- Before.txt 05:21:49. 000000000 + 0800
++ After.txt 04:03:16. 000000000 + 0800
@-1, 3 + 1, 3 @@
-This is a line to be deleted
-This is a line that will be changed
+ This is a line that has been changed
This is a line that will be unchanged
+ This is a line that has been added
#################################

Note:
The diff-u option is output in uniform format.
--- Before.txt 05:21:49. 000000000 + 0800
--- Before.txt refers to the old file
++ After.txt 04:03:16. 000000000 + 0800
++ After.txt is a new file.
@-1, 3 + 1, 3 @@
@-1 and 3 indicates that there are 3 rows in the 1st files, and + 1, 3 @ indicates that there are 3 rows in the 2nd files.
-This is a line to be deleted
-This is a line that will be changed
Is the row to be deleted
+ This is a line that has been changed
Is the added row
This is a line that will be unchanged
If there is no "-" or "signature", it means that the row does not change because both after.txtand before.txt have this line.
+ This is a line that has been added
Is the added row
The unified format comparison and output of diff are performed in order.

4) use the diff command in the directory.

Create the old and new directories. The old directory contains the initial content. The new directory contains the latest version of the file.
######################################## ##
Mkdir old New
Echo "this is one. It's unchanged." | tee old/one new/One
Echo "This is Two. It will change."> old/Two
Echo "This is Two. It changed."> New/Two
Echo "this is three. It's new"> New/three
######################################## ##

Create a patch file
######################################## ##
Diff-Nur old/new/> mypatch. Diff
######################################## ##
Note: The-r option recursively creates a patch file according to the file directory.
-U or unified mode
-N indicates that when diff encounters a file that only exists in one of the two trees, it skips the file by default and prints a warning to stderr.
This behavior can be changed through the-n option, which also results in diff believing that the lost file actually exists, but it is empty. This method is used,
A patch file can include the created file. Then, apply the patch to create a new file.

######################################## ##
More mypatch. Diff
Output:
Diff-Nur old/three new/three
--- Old/three 08:00:00. 000000000 + 0800
++ New/three 06:55:34. 000000000 + 0800
@-+ 1 @@
+ This is three. It's new
Diff-Nur old/two new/Two
--- Old/Two 06:55:08. 000000000 + 0800
++ New/Two 06:55:21. 000000000 + 0800
@-1 + 1 @@
-This is Two. It will change.
+ This is Two. It changed.
######################################## ##
Note:
Diff-Nur old/three new/three indicates that the following two files are compared: Old/three new/three.
Because there is no old/three file, add + this is three. It's new in old/three.
Diff-Nur old/two new/Two indicates the following two files: Old/two new/Two.
Because the old/Two and new/two rows are inconsistent, deleting this is two. It will change. Add this is two. It changed.

Install patches in the old directory, create old/three, and change old/Two.
######################################## ##
Patch -- dir old <mypatch. Diff
Ls-l old/
Output:
One Three Two
######################################## ##

Restore the contents of the old directory, including deleting the old/three and restoring the old/Two file.
######################################## ##
Patch -- dir old-r <mypatch. Diff
Output:
Ls-l old/
One Two
######################################## ##

5) Check and merge changes

Use Vim to highlight the change of a single character to indicate the difference.

######################################## ##
Vim-D after.txt before.txt
######################################## ##

Use the GUI tool gvimdiff to display two files.

######################################## ##
Gvimdiff after.txt before.txt
######################################## ##

Create an orig. c file

######################################## ##
VI orig. c
Void Foo (void)
{
Printf ("This will be changed by me./N ");

Printf ("This will be unchanged,/N ");

Printf ("This will be changed by you./N ");
}
######################################## ##

Copy the file orig. C to me. C, and change the 4th behavior printf ("this was changed by me./N ");
######################################## ##
VI me. c
Void Foo (void)
{
Printf ("this was changed by me./N ");

Printf ("This will be unchanged,/N ");

Printf ("This will be changed by you./N ");
}
######################################## ##

Copy the file orig. C to you. C, and change the 7th behavior printf ("this was changed by you./N ");
######################################## ##
VI you. c
Void Foo (void)
{
Printf ("This will be changed by me./N ");

Printf ("This will be unchanged,/N ");

Printf ("this was changed by you./N ");
}
######################################## ##

Version tools such as CVS and subversion are called diff3.
######################################## ##
Diff3 me. c orig. c you. c
Output:
==== 1
1: 3C
Printf ("this was changed by me./N ");
2: 3C
3: 3C
Printf ("This will be changed by me./N ");
==== 3
1: 7c
2: 7c
Printf ("This will be changed by you./N ");
3: 7c
Printf ("this was changed by you./N ");

Note:
If no parameter exists, the output produced by diff3 indicates the change.
==== 1 and ==== 3 specify which file to modify is different from the original file.
The numbering method is based on the parameter sequence.
That is, 1st files and 3rd files are different from the original files.
1: 3C
Printf ("this was changed by me./N ");
3: 3C
Printf ("This will be changed by me./N ");
1: 3C indicates 1st rows of 3rd files and 3: 3C indicates 3rd rows of 3rd files.
Why not compare it with the original file. Because the 3rd lines of the 3rd files are the same as the source files (2nd files), it doesn't matter which file.

2: 7c
Printf ("This will be changed by you./N ");
3: 7c
Printf ("this was changed by you./N ");
2: 7C indicates that 2nd rows of 7th files are different from 3rd rows of 7th files in 3: 7c.

Diff3 will try to merge for us. The merge is based on the source file and is modified based on the two new files.
The source file is the second file. The first and third files can be exchanged, but they must have a common ancestor, that is, the second file.

#######################################
Diff3-m me. c orig. c you. c | cat-n
Output:
1 void Foo (void)
2 {
3 printf ("this was changed by me./N ");
4
5 printf ("This will be unchanged,/N ");
6
7 printf ("this was changed by you./N ");
8}
########################################

To test a more complex environment, create a file orig. C.1
The content is as follows:
########################################
VI orig. C.1
Void Foo (void)
{
Printf ("This will be changed by both of us./N ");
}
########################################

Compare the output again with diff3-m, as shown below:
########################################
Diff3-m me. c orig. C.1 you. c
Void Foo (void)
{
<Me. c
Printf ("this was changed by me./N ");

Printf ("This will be unchanged,/N ");

Printf ("This will be changed by you./N ");
| Orig. C.1
Printf ("This will be changed by both of us./N ");
========
Printf ("This will be changed by me./N ");

Printf ("This will be unchanged,/N ");

Printf ("this was changed by you./N ");
>>>>>>> You. c
}
########################################

Note: The preceding format is the same as that of CVS update, and the format of manually merged files is the same.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.