As you already know, Linux diff command compares two files.
However Linux diff3 utility compares three files and is also capable of merging the difference between two files into the third one. In this article, we will understand the usage of diff3 command through some examples.
The basic syntax of diff3 is :
diff3 [OPTION]... MYFILE OLDFILE YOURFILE
1. Basic Diff3 Output
For this example, lets use these three files: parent.txt, your.txt and mine.txt.
$ cat parent.txt Hello This is parent file. $ cat your.txt Hello, This is your file. $ cat mine.txt Hello This is my file.
Now if diff3 command is run over these three files :
$ diff3 parent.txt your.txt mine.txt ==== 1:1,2c Hello This is parent file. 2:1,2c Hello, This is your file. 3:1,2c Hello, This is my file.
We see that output contains comparison information of all these three files. In the above output:
- The very first line ‘====’ signifies that all the three files differ.
- Next, the line ‘1:1,2c’ means that for the first (1:) file given as argument to diff3 (parent.txt in our case), lines in the range of one to two (1,2) are different when compared with the other two files and need to be changed(c) and these two lines are also shown in the next two lines of the output.
- Similarly ‘2:1,2c’ and ‘3:1,2c’ can be comprehended.
Please note that apart from using diff3 utility, it is also helpful to understand how to use diff, colordiff, wdiff, or vimdiff for your typical two file comparision.
2. If two out of three files are similar
For this example, assume that the files mine.txt and parent.txt exactly same.
$ cat parent.txt Hello This is a file. $ cat your.txt Hello, This is your file. $ cat mine.txt Hello This is a file.
And diff3 is run over these three files now :
$ diff3 mine.txt parent.txt your.txt ====3 1:1,2c 2:1,2c Hello This is a file. 3:1,2c Hello, This is your file.
The very first line ‘====3’ signifies that this time the file number 3 ie your.txt is different from the other two. This is visible in the output too.
3. ‘c’ is for change while ‘a’ is for append
Till now, we have seen an alphabet ‘c’ in the output. This letter signifies ‘change’ required in the lines/text. If the alphabet ‘a’ appears then it signifies a line needs to be appended.
Lets take another example :
$ cat mine.txt Hi, $ cat parent.txt Hi, $ cat your.txt Hi, This is your file.
Now execute diff3 on these three files:
$ diff3 mine.txt parent.txt your.txt ====3 1:1a 2:1a 3:2c This is your file.
The output above signifies that the change in file3 (i.e your.txt) needs to be appended in file1 (mine.txt) and file2 (parent.txt) to make all the three file similar. Alternatively, the second line in your.txt can be changed(c) to make all the three files similar.
4. Output overlapping changes using -x option
The flag -x can be used to output the changes that cause overlaps. The order of file names given as argument to diff3 matters here. For example :
diff3 -x mine.txt parent.txt your.txt
means that you want to merge in mine.txt the changes that would turn parent.txt into your.txt
Lets take an example :
$ cat mine.txt Hi, This is your file. hello $ cat parent.txt Hi, This is your file. $ cat your.txt Hi, This is your file. bye
Execute diff3 now:
$ diff3 -x mine.txt parent.txt your.txt 3c bye .
So we see tha
t the output says that the third line of mine.txt has to changed to ‘bye’ in order to merge the changes that would turn parent.txt to your.txt
5. Output non merged changes using -e option
The option -e can be used to output non merged changes from parent.txt to your.txt into mine.txt.
Considering the same files as used the example above :
$ diff3 -e mine.txt parent.txt your.txt 3c bye . .
So we see that the output shows the non merged changes.
6. Output merged file using -m option
A merged file comprising of contents from all the three files can be produced using the -m option. For example, if following are the three files:
$ cat mine.txt Hi, This is your file. Hello $ cat parent.txt Hi, This is your file. $ cat your.txt Hi, This is your file.
Now if diff3 is run using the -m option :
$ diff3 -m mine.txt parent.txt your.txt Hi, This is your file. Hello
So the above output shows contents of merged file that has merged contents from all the three files supplied as arguments to diff3.
7. Understanding conflicts using -m option
Producing a merged file (from the three files) is not always a cake walk (as shown in the above example).
Consider the input file contents below :
$ cat parent.txt Hi, This is your file. hi $ cat your.txt Hi, This is your file. hello $ cat mine.txt Hi, This is your file. Hello
If diff3 is run over the files above, the following output is displayed :
$ diff3 -m mine.txt parent.txt your.txt Hi, This is your file. <<<<<<< mine.txt Hello ||||||| parent.txt hi ======= hello >>>>>>> your.txt
Here the first two lines are undisputed part of the merged file but the actual conflict is shown between <<<<<<< and >>>>>>> along with file names and contents.
8. Accept one argument from stdin using ‘-‘
A ‘-‘ can be used in place of any one of the file names to accept input from stdin for that argument.
$ diff3 mine.txt parent.txt - Hi, bye====3 1:1a 2:1a 3:2c bye
As we can see, when the command above was run, the content of third file was given through stdin. Note that after entering the contents of file from stdin, one needs to press the key combination ctrl+d to get the output of diff3.
9. diff3 uses diff tool to compare files
Though diff3 boasts of comparing 3 files but actually it uses diff tool internally to carry out the comparisons between two files. This can be confirmed by passing an executable as an input argument:
$ diff3 mine.txt parent.txt a.out diff3: subsidiary program `diff' failed
So we can see in the output above, the diff3 command error outs saying that the subsidiary program ‘diff’ failed.
10. Specify a diff program through –diff-program option
diff3 command provides the flexibility to provide a diff program as an argument so that the same can be used to compare files and provide the results which diff3 can use. This functionality is achieved by using the –diff-program option.
$ diff3 --diff-program=diff mine.txt parent.txt your.txt ==== 1:2a 2:3c c ya 3:3c TC
11. Treat all files as text using -a option
As you can see in the example 9 shown above, when we passed a non text file (an executable a.out) then diff3 returned error. But if we want to tell diff3 to compare even non text files, then an option -a can be used that tells diff3 to consider all input files as text files. For example :
$ diff3 -a mine.txt parent.txt a.out ==== 1:1,2c Hello This is file 2:1,3c Hello This is file c ya 3:1,4c ELF>@@@h@8 @@@@@@��88@8@@@�� ` @@`@`��TT@T@DDP�td@@@@@$$Q�tdR�td``��/lib64/ld-linux-x86-64.so.2GNUGNUKd�3�K!���� ��3�٥� __gmon_start__libc.so.6puts__libc_start_mainGLIBC_2.2.5ui 1```H��s���H���5� ... ... ...
So the output above shows that diff3 tried to compare even an executable file treating it as a text file.