[Previous] [Contents] [Next]

diff3

Show differences among three files (GNU)

Syntax:

diff3 [options...] mine older yours

Options:

-a
Treat all files as text and compare them line-by-line, even if they do not appear to be text.
-A
Incorporate all changes from older to yours into mine, surrounding all conflicts with bracket lines. See section "Marking conflicts".
-e
Generate an ed script that incorporates all the changes from older to yours into mine. See section "Selecting which changes to incorporate". (ed is not included with the QNX distribution)
-E
Like -e, but output unmerged changes, bracketing overlaps. See section "Marking conflicts".
-i
Generate w and q commands at the end of the ed script for System V compatibility. This option must be combined with one of the -AeExX3 options, and may not be combined with -m. See section "Saving the changed file". (ed is not included with the QNX distribution)
-L label
Use the label label for the brackets output by the -A, -E and -X options. This option may be given up to three times, one for each input file. The default labels are the names of the input files. Thus diff3 -L X -L Y -L Z -m A B C acts like diff3 -m A B C, except that the output looks like it came from files named X, Y and Z rather than from files named A, B and C. See section "Marking conflicts".
-m
Apply the edit script to the first file and send the result to standard output. Unlike piping the output from diff3 to ed, this works even for binary files and incomplete lines. -A is assumed if no edit script option is specified. See section "Generating the merged output directly".
-T
Output a tab rather than two spaces before the text of a line in normal format. This causes the alignment of tabs in the line to look normal.
-v
Output the version number of diff3.
-x
Like -e, except output only the overlapping changes. See section "Selecting which changes to incorporate".
-X
Like -E, except output only the overlapping changes. In other words, like -x, except bracket changes as in -E. See section "Marking conflicts".
-3
Like -e, except output only the nonoverlapping changes. See section "Selecting which changes to incorporate".
mine older yours
These are the pathnames of the files to be compared. At most one of these three file names may be a dash (-), which tells diff3 to read the standard input for that file.

Description:

The diff3 utility is used to compare three files and show any differences among them. (diff3 can also merge files; see section "Merging from a common ancestor").

The normal diff3 output format shows each hunk of differences without surrounding context. Hunks are labeled depending on whether they are two-way or three-way, and lines are annotated by their location in the input files.

Sample input files

Here are three sample files that we will use in numerous examples to illustrate the output of diff3 and how various options can change it.

Sample file #1 -- lao

This is the file lao:

The Way that can be told of is not the eternal Way;
The name that can be named is not the eternal name.
The Nameless is the origin of Heaven and Earth;
The Named is the mother of all things.
Therefore let there always be non-being,
  so we may see their subtlety,
And let there always be being,
  so we may see their outcome.
The two are the same,
But after they are produced,
  they have different names.

Sample file #2 -- tzu

This is the file tzu:

The Nameless is the origin of Heaven and Earth;
The named is the mother of all things.

Therefore let there always be non-being,
  so we may see their subtlety,
And let there always be being,
  so we may see their outcome.
The two are the same,
But after they are produced,
  they have different names.
They both may be called deep and profound.
Deeper and more profound,
The door of all subtleties!

Sample file #3 -- tao

This is the third sample file, called tao:

The Way that can be told of is not the eternal Way;
The name that can be named is not the eternal name.
The Nameless is the origin of Heaven and Earth;
The named is the mother of all things.

Therefore let there always be non-being,
  so we may see their subtlety,
And let there always be being,
  so we may see their result.
The two are the same,
But after they are produced,
  they have different names.

  -- The Way of Lao-Tzu, tr. Wing-tsit Chan

Detailed description of diff3 normal format

Each hunk begins with a line marked "====". Three-way hunks have plain "====" lines, and two-way hunks have "1", "2", or "3" appended to specify which of the three input files differ in that hunk. The hunks contain copies of two or three sets of input lines each preceded by one or two commands identifying where the lines came from.

Normally, two spaces precede each copy of an input line to distinguish it from the commands. But with the -T option, diff3 uses a tab instead of two spaces; this lines up tabs correctly.

Commands take the following forms:

file:la
This hunk appears after line l of file file, and contains no lines in that file. To edit this file to yield the other files, one must append hunk lines taken from the other files. For example, "1:11a" means that the hunk follows line 11 in the first file and contains no lines from that file.
file:rc
This hunk contains the lines in the range r of file file. The range r is a comma-separated pair of line numbers, or just one number if the range is a singleton. To edit this file to yield the other files, one must change the specified lines to be the lines taken from the other files. For example, "2:11,13c" means that the hunk contains lines 11 through 13 from the second file.

If the last line in a set of input lines is incomplete, it is distinguished on output from a full line by a following line that starts with "\".

diff3 hunks

Groups of lines that differ in two or three of the input files are called diff3 hunks, by analogy with diff hunks. If all three input files differ in a diff3 hunk, the hunk is called a three-way hunk; if just two input files differ, it is a two-way hunk.

As with diff, several solutions are possible. When comparing the files A, B, and C, diff3 normally finds diff3 hunks by merging the two-way hunks output by the two commands diff A B and diff A C. This does not necessarily minimize the size of the output, but exceptions should be rare.

For example, suppose the file F contains the three lines "a", "b", "f", the file G contains the lines "g", "b", "g", and the file H contains the lines "a", "b", "h". In this case the command diff3 F G H might produce the following output:

====2
1:1c
3:1c
  a
2:1c
  g
====
1:3c
  f
2:3c
  g
3:3c
  h

because it found a two-way hunk containing "a" in the first and third files and "g" in the second file, then the single line "b" common to all three files, then a three-way hunk containing the last line of each file.

An example of diff3 normal format

Here is the output of the command diff3 lao tzu tao (see section "Sample input files", for the complete contents of the files). Notice that it shows only the lines that are different among the three files.

====2
1:1,2c
3:1,2c
  The Way that can be told of is not the eternal Way;
  The name that can be named is not the eternal name.
2:0a
====1
1:4c
  The Named is the mother of all things.
2:2,3c
3:4,5c
  The named is the mother of all things.
  
====3
1:8c
2:7c
    so we may see their outcome.
3:9c
    so we may see their result.
====
1:11a
2:11,13c
  They both may be called deep and profound.
  Deeper and more profound,
  The door of all subtleties!
3:13,14c
  
    -- The Way of Lao-Tzu, tr. Wing-tsit Chan

Merging from a common ancestor

When changes have been made to copies of the same file, diff3 can produce a merged output that contains both sets of changes together with warnings about conflicts.

One might imagine programs with names like diff4 and diff5 to compare more than three files simultaneously, but in practice the need rarely arises. You can use diff3 to merge three or more sets of changes to a file by merging two change sets at a time.

The diff3 utility can incorporate changes from two modified versions into a common preceding version. This lets you merge the sets of changes represented by the two newer files. Specify the common ancestor version as the second argument and the two newer versions as the first and third arguments, like this:

You can remember the order of the arguments by noting that they are in alphabetical order.

You can think of this as subtracting older from yours and adding the result to mine, or as merging into mine the changes that would turn older into yours. This merging is well-defined as long as mine and older match in the neighborhood of each such change. This fails to be true when all three input files differ or when only older differs; we call this a conflict. When all three input files differ, we call the conflict an overlap.

The diff3 utility gives you several ways to handle overlaps and conflicts. You can omit overlaps or conflicts, or select only overlaps, or mark conflicts with special "<<<<<<<" and ">>>>>>>" lines.

The diff3 utility can output the merge results as an ed script that that can be applied to the first file to yield the merged output. However, it is usually better to have diff3 generate the merged output directly; this bypasses some problems with ed. Note that ed is not included with the QNX distribution.

Selecting which changes to incorporate

You can select all unmerged changes from older to yours for merging into mine with the -e option. You can select only the nonoverlapping unmerged changes with -3, and you can select only the overlapping changes with -x.

The -e, -3 and -x options select only unmerged changes, i.e. changes where mine and yours differ; they ignore changes from older to yours where mine and yours are identical, because they assume that such changes have already been merged. If this assumption is not a safe one, you can use the -A option. (See section "Marking conflicts").

Here is the output of the command diff3 with each of these three options (see section "Sample input files", for the complete contents of the files). Notice that -e outputs the union of the disjoint sets of changes output by -3 and -x.

Output of diff3 -e lao tzu tao:

11a

  -- The Way of Lao-Tzu, tr. Wing-tsit Chan
.
8c
  so we may see their result.
.

Output of diff3 -3 lao tzu tao:

8c
  so we may see their result.
.

Output of diff3 -x lao tzu tao:

11a

  -- The Way of Lao-Tzu, tr. Wing-tsit Chan
.

Marking conflicts

The diff3 utility can mark conflicts in the merged output by bracketing them with special marker lines. A conflict that comes from two files A and B is marked as follows:

<<<<<<< A
lines from A
=======
lines from B
>>>>>>> B

A conflict that comes from three files A, B and C is marked as follows:

<<<<<<< A
lines from A
||||||| B
lines from B
=======
lines from C
>>>>>>> C

The -A option acts like the -e option, except that it brackets conflicts, and it outputs all changes from older to yours, not just the unmerged changes. Thus, given the sample input files (see section "Sample input files"), diff3 -A lao tzu tao puts brackets around the conflict where only tzu differs:

11a
||||||| tzu
They both may be called deep and profound.
Deeper and more profound,
The door of all subtleties!
=======

	-- The Way of Lao-Tzu, tr. Wing-tsit Chan
>>>>>>> tao
.
11a
<<<<<<< lao
.
8c
	so we may see their result.
.
2a
>>>>>>> tao
.
0a
<<<<<<< tzu
=======
.

The -E option outputs less information than the -A option, because it outputs only unmerged changes, and it never outputs the contents of the second file. Thus the -E option acts like the -e option, except that it brackets the first and third files from three-way overlapping changes. Similarly, -X acts like -x, except it brackets all its (necessarily overlapping) changes. For example, for the three-way overlapping change above, the -E and -X options output the following:

11a
||||||| tzu
They both may be called deep and profound.
Deeper and more profound,
The door of all subtleties!
=======

	-- The Way of Lao-Tzu, tr. Wing-tsit Chan
>>>>>>> tao
.
11a
<<<<<<< lao
.
8c
	so we may see their result.
.
2a
>>>>>>> tao
.
0a
<<<<<<< tzu
=======
.

If you are comparing files that have meaningless or uninformative names, you can use the -L label or --label=label option to show alternate names in the "<<<<<<<", "|||||||", and ">>>>>>>" brackets. This option can be given up to three times, once for each input file. Thus diff3 -A -L X -L Y -L Z A B C acts like diff3 -A A B C, except that the output looks like it came from files named X, Y and Z rather than from files named A, B and C.

Generating the merged output directly

With the -m option, diff3 outputs the merged file directly. This is more efficient than using ed to generate it, and works even with non-text files that ed would reject. If you specify -m without an ed script option, -A (--show-all) is assumed. (Note that ed is not included with the QNX distribution.)

For example, the command diff3 -m lao tzu tao (see section "Sample input files" for a copy of the input files) would output the following:

<<<<<<< tzu
=======
The Way that can be told of is not the eternal Way;
The name that can be named is not the eternal name.
>>>>>>> tao
The Nameless is the origin of Heaven and Earth;
The Named is the mother of all things.
Therefore let there always be non-being,
  so we may see their subtlety,
And let there always be being,
  so we may see their result.
The two are the same,
But after they are produced,
  they have different names.
<<<<<<< lao
||||||| tzu
They both may be called deep and profound.
Deeper and more profound,
The door of all subtleties!
=======

  -- The Way of Lao-Tzu, tr. Wing-tsit Chan
>>>>>>> tao

How diff3 merges incomplete lines

With -m, incomplete lines are simply copied to the output as they are found; if the merged output ends in an conflict and one of the input files ends in an incomplete line, succeeding "|||||||", "=======", or ">>>>>>>" brackets appear somewhere other than the start of a line because they are appended to the incomplete line.

Without -m, if an ed script option is specified and an incomplete line is found, diff3 generates a warning and acts as if a newline had been present.

Saving the changed file

Traditional Unix diff3 generates an ed script without the trailing w and q commands that save the changes. System V diff3 generates these extra commands. GNU diff3 normally behaves like traditional Unix diff3, but with the -i option it behaves like System V diff3 and appends the w and q commands.

The -i option requires one of the ed script options -AeExX3, and is incompatible with the merged output option -m.

Exit status:

0
diff3 was successful.
1
Some conflicts were found.
>1
An error occurred.

Contributing author:

GNU

See also:

cmp, comm, diff, rcsmerge


[Previous] [Contents] [Next]