Comparing and Merging Files Patch Diff Diff3 Sdiff CMP
Comparing and Merging Files Patch Diff Diff3 Sdiff CMP
Merging Files
But if diff notices the common line b instead, it produces this output:
1c1
<a
---
>c
3c3
<c
---
>a
It is also possible to find a as the common line. diff does not always
find an optimal matching between the files; it takes shortcuts to run
faster. But its output is usually close to the shortest possible. You can
adjust this tradeoff with the --minimal option (See diff Performance).
- Page 2 -
following two lines to be equivalent, where $ denotes the line end: Unlike diff, cmp cannot compare directories; it can only compare two
files.
Here lyeth muche rychnesse in lytell space. --
John Heywood$
Here lyeth muche rychnesse in lytell space. -- Binary Files and Forcing Text
John Heywood $ Comparisons
The -w and --ignore-all-space options are stronger than -b.
They ignore difference even if one file has white space where the other If diff thinks that either of the two files it is comparing is binary (a
file has none. White space characters include tab, newline, vertical tab, non-text file), it normally treats that pair of files much as if the summary
form feed, carriage return, and space; some locales may define additional output format had been selected (See Brief), and reports only that the
characters to be white space. With these options, diff considers the binary files are different. This is because line by line comparisons are
following two lines to be equivalent, where $ denotes the line end and usually not meaningful for binary files.
^M denotes a carriage return:
diff determines whether a file is text or binary by checking the first
Here lyeth muche rychnesse in lytell space.-- few bytes in the file; the exact number of bytes is system dependent, but
John Heywood$ it is typically several thousand. If every character in that part of the file
He relyeth much erychnes seinly tells pace. is non-null, diff considers the file to be text; otherwise it considers the
--John Heywood ^M$ file to be binary.
Suppressing Differences in Blank Lines Sometimes you might want to force diff to consider files to be text.
For example, you might be comparing text files that contain null
characters; diff would erroneously decide that those are non-text files.
The -B and --ignore-blank-lines options ignore insertions or Or you might be comparing documents that are in a format used by a
deletions of blank lines. These options normally affect only lines that word processing system that uses null characters to indicate special
are completely empty; they do not affect lines that look empty but formatting. You can force diff to consider all files to be text files,
contain space or tab characters. With these options, for example, a file and compare them line by line, by using the -a or --text option. If
containing
1. A point is that which has no part. the files you compare using this option do not in fact contain text, they
will probably contain few newline characters, and the diff output will
2. A line is breadthless length. consist of hunks showing differences between long lines of whatever
-- Euclid, The Elements, I characters the files contain.
is considered
1. A point identical
is thattowhich
a file containing
has no part.
2. A line is breadthless length. You can also force diff to consider all files to be binary files, and
report only whether they differ (but not how). Use the --brief option
for this.
-- Euclid, The Elements, I
In operating systems that distinguish between text and binary files, diff
normally reads and writes all data as text. Use the --binary option to
Suppressing Case Differences force diff to read and write binary data instead. This option has no
effect on a Posix-compliant system like GNU or traditional Unix.
However, many personal computer operating systems represent the end of
GNU diff can treat lowercase letters as equivalent to their uppercase a line with a carriage return followed by a newline. On such systems,
counterparts, so that, for example, it considers Funky Stuff, funky diff normally ignores these carriage returns on input and generates
STUFF, and fUNKy stuFf to all be the same. To request this, use the them at the end of each output line, but with the --binary option
-i or --ignore-case option. diff treats each carriage return as just another input character, and does
not generate a carriage return at the end of each output line. This can
Suppressing Lines Matching a Regular be useful when dealing with non-text files that are meant to be
interchanged with Posix-compliant systems.
Expression If you want to compare two files byte by byte, you can use the cmp
program with the -l option to show the values of each differing byte in
To ignore insertions and deletions of lines that match a regular the two files. With GNU cmp, you can also use the -c option to show
expression, use the -I regexp or the ASCII representation of those bytes. See Invoking cmp, for more
--ignore-matching-lines=regexp option. You should escape information.
regular expressions that contain shell metacharacters to prevent the shell
from expanding them. For example, diff -I ’^[0-9]’ ignores all If diff3 thinks that any of the files it is comparing is binary (a
changes to lines beginning with a digit. non-text file), it normally reports an error, because such comparisons are
usually not useful. diff3 uses the same test as diff to decide
However, -I only ignores the insertion or deletion of lines that contain whether a file is binary. As with diff, if the input files contain a few
the regular expression if every changed line in the hunk---every insertion non-text characters but otherwise are like text files, you can force diff3
and every deletion---matches the regular expression. In other words, for to consider all files to be text files and compare them line by line by
each nonignorable change, diff prints the complete set of changes in its using the -a or --text options.
vicinity, including the ignorable ones.
You can specify more than one regular expression for lines to ignore by
using more than one -I option. diff tries to match each line against
each regular expression, starting with the last one given.
You can also get a brief indication of whether two files differ by using
cmp. For files that are identical, cmp produces no output. When the
files differ, by default, cmp outputs the byte offset and line number
where the first difference occurs. You can use the -s option to suppress
that information, so that cmp produces no output and reports whether the
files differ using only its exit status (See Invoking cmp).
- Page 3 -
fct
diff Output Formats Replace the lines in range f of the first file with lines in range t
of the second file. This is like a combined add and delete, but
more compact. For example, 5,7c8,10 means change lines
diff has several mutually exclusive options for output format. The 5--7 of file 1 to read as lines 8--10 of file 2; or, if changing file
following sections describe each format, illustrating how diff reports 2 into file 1, change lines 8--10 of file 2 to read as lines 5--7 of
the differences between two sample input files. file 1.
rdl
Two Sample Input Files Delete the lines in range r from the first file; line l is where they
would have appeared in the second file had they not been deleted.
For example, 5,7d3 means delete lines 5--7 of file 1; or, if
Here are two sample files that we will use in numerous examples to changing file 2 into file 1, append lines 5--7 of file 1 after line 3
illustrate the output of diff and how various options can change it. of file 2.
This is the file lao:
An Example of Normal Format
The Way that can be told of is not the eternal Here is the output of the command diff lao tzu (See Sample diff
Way; Input, for the complete contents of the two files). Notice that it shows
The name that can be named is not the eternal only the lines that are different between the two files.
name.
The Nameless is the origin of Heaven and Earth; 1,2d0
The Named is the mother of all things. < The Way that can be told of is not the eternal
Therefore let there always be non-being, Way;
so we may see their subtlety, < The name that can be named is not the eternal
And let there always be being, name.
so we may see their outcome. 4c2,3
The two are the same, < The Named is the mother of all things.
But after they are produced, ---
they have different names. > The named is the mother of all things.
>
This is the file tzu: 11a11,13
> They both may be called deep and profound.
The Nameless is the origin of Heaven and Earth; > Deeper and more profound,
The named is the mother of all things. > The door of all subtleties!
Therefore let there always be non-being,
so we may see their subtlety,
And let there always be being,
Showing Differences in Their Context
so we may see their outcome.
The two are the same, Usually, when you are looking at the differences between files, you will
But after they are produced, also want to see the parts of the files near the lines that differ, to help
they have different names. you understand exactly what has changed. These nearby parts of the
They both may be called deep and profound. files are called the context.
Deeper and more profound,
The door of all subtleties! GNU diff provides two output formats that show context around the
differing lines: context format and unified format. It can optionally show
In this example, the first hunk contains just the first two lines of lao, in which function or section of the file the differing lines are found.
the second hunk contains the fourth line of lao opposing the second and
third lines of tzu, and the last hunk contains just the last three lines of If you are distributing new versions of files to other people in the form
tzu. of diff output, you should use one of the output formats that show
context so that they can apply the diffs even if they have made small
changes of their own to the files. patch can apply the diffs in this case
Showing Differences Without Context by searching in the files for the lines of context around the differing
lines; if those lines are actually a few lines away from where the diff
says they are, patch can adjust the line numbers accordingly and still
The ‘‘normal’’ diff output format shows each hunk of differences apply the diff correctly. See Imperfect, for more information on using
without any surrounding context. Sometimes such output is the clearest patch to apply imperfect diffs.
way to see how lines have changed, without the clutter of nearby
unchanged lines (although you can get similar results with the context or
unified formats by using 0 lines of context). However, this format is no Context Format
longer widely used for sending out patches; for that purpose, the context The context output format shows several lines of context around the lines
format (See Context Format) and the unified format (See Unified Format) that differ. It is the standard format for distributing updates to source
are superior. Normal format is the default for compatibility with older code.
versions of diff and the Posix standard.
To select this output format, use the -C lines, --context[=lines],
Detailed Description of Normal Format or -c option. The argument lines that some of these options take is the
number of lines of context to show. If you do not specify lines, it
The normal output format consists of one or more hunks of differences; defaults to three. For proper operation, patch typically needs at least
each hunk shows one area where the files differ. Normal format hunks two lines of context.
look like this:
There are three types of change commands. Each consists of a line You can change the header’s content with the -L label or
number or comma-separated range of lines in the first file, a single --label=label option; see See Alternate Names.
character indicating the kind of change to make, and a line number or
comma-separated range of lines in the second file. All line numbers are Next come one or more hunks of differences; each hunk shows one area
the original line numbers in each file. The types of change commands where the files differ. Context format hunks look like this:
are:
***************
lar *** from-file-line-range ****
Add the lines in range r of the second file after line l of the first from-file-line
file. For example, 8a12,15 means append lines 12--15 of file 2 from-file-line…
after line 8 of file 1; or, if changing file 2 into file 1, delete --- to-file-line-range ----
lines 12--15 of file 2. to-file-line
- Page 4 -
to-file-line…
Unified Format
The lines of context around the lines that differ start with two space
characters. The lines that differ between the two files start with one of The unified output format is a variation on the context format that is
the following indicator characters, followed by a space character: more compact because it omits redundant context lines. To select this
output format, use the -U lines, --unified[=lines], or -u option.
! The argument lines is the number of lines of context to show. When it
A line that is part of a group of one or more lines that changed is not given, it defaults to three.
between the two files. There is a corresponding group of lines
marked with ! in the part of this hunk for the other file. At present, only GNU diff can produce this format and only GNU
patch can automatically apply diffs in this format. For proper
+ operation, patch typically needs at least two lines of context.
An ‘‘inserted’’ line in the second file that corresponds to nothing
in the first file.
Detailed Description of Unified Format
- The unified output format starts with a two-line header, which looks like
A ‘‘deleted’’ line in the first file that corresponds to nothing in this:
the second file.
--- from-file from-file-modification-time
If all of the changes in a hunk are insertions, the lines of from-file are +++ to-file to-file-modification-time
omitted. If all of the changes are deletions, the lines of to-file are
omitted. You can change the header’s content with the -L label or
--label=label option; see See Alternate Names.
An Example of Context Format
Next come one or more hunks of differences; each hunk shows one area
Here is the output of diff -c lao tzu (See Sample diff Input, for the where the files differ. Unified format hunks look like this:
complete contents of the two files). Notice that up to three lines that are
not different are shown around each line that is different; they are the @@ from-file-range to-file-range @@
context lines. Also notice that the first two hunks have run together, line-from-either-file
because their contents overlap. line-from-either-file…
*** lao Sat Jan 26 23:30:39 1991 The lines common to both files begin with a space character. The lines
--- tzu Sat Jan 26 23:30:50 1991 that actually differ between the two files have one of the following
*************** indicator characters in the left column:
*** 1,7 ****
- The Way that can be told of is not the eternal +
Way; A line was added here to the first file.
- The name that can be named is not the eternal
name. -
The Nameless is the origin of Heaven and Earth; A line was removed here from the first file.
! The Named is the mother of all things.
Therefore let there always be non-being,
so we may see their subtlety, An Example of Unified Format
And let there always be being, Here is the output of the command diff -u lao tzu (See Sample diff
--- 1,6 ---- Input, for the complete contents of the two files):
The Nameless is the origin of Heaven and Earth;
! The named is the mother of all things. --- lao Sat Jan 26 23:30:39 1991
! +++ tzu Sat Jan 26 23:30:50 1991
Therefore let there always be non-being, @@ -1,7 +1,6 @@
so we may see their subtlety, -The Way that can be told of is not the eternal
And let there always be being, Way;
*************** -The name that can be named is not the eternal
*** 9,11 **** name.
--- 8,13 ---- The Nameless is the origin of Heaven and Earth;
The two are the same, -The Named is the mother of all things.
But after they are produced, +The named is the mother of all things.
they have different names. +
+ They both may be called deep and profound. Therefore let there always be non-being,
+ Deeper and more profound, so we may see their subtlety,
+ The door of all subtleties! And let there always be being,
@@ -9,3 +8,6 @@
An Example of Context Format with Less Context The two are the same,
But after they are produced,
Here is the output of diff --context=1 lao tzu (See Sample diff they have different names.
Input, for the complete contents of the two files). Notice that at most +They both may be called deep and profound.
one context line is reported here. +Deeper and more profound,
+The door of all subtleties!
*** lao Sat Jan 26 23:30:39 1991
--- tzu Sat Jan 26 23:30:50 1991
*************** Showing Which Sections Differences Are in
*** 1,5 ****
- The Way that can be told of is not the eternal Sometimes you might want to know which part of the files each change
Way; falls in. If the files are source code, this could mean which function was
- The name that can be named is not the eternal changed. If the files are documents, it could mean which chapter or
name. appendix was changed. GNU diff can show this by displaying the
The Nameless is the origin of Heaven and Earth; nearest section heading line that precedes the differing lines. Which lines
! The Named is the mother of all things. are ‘‘section headings’’ is determined by a regular expression.
Therefore let there always be non-being,
--- 1,4 ----
The Nameless is the origin of Heaven and Earth; Showing Lines That Match Regular Expressions
! The named is the mother of all things.
! To show in which sections differences occur for files that are not source
Therefore let there always be non-being, code for C or similar languages, use the -F regexp or
*************** --show-function-line=regexp option. diff considers lines that
*** 11 **** match the argument regexp to be the beginning of a section of the file.
--- 10,13 ---- Here are suggested regular expressions for some common languages:
they have different names.
+ They both may be called deep and profound. ^[A-Za-z_]
+ Deeper and more profound, C, C++, Prolog
+ The door of all subtleties! ^(
Lisp
- Page 5 -
^@\(chapter\|appendix\|unnumbered\|chapheading\) Normally, an output line is incomplete if and only if the lines that it
Texinfo contains are incomplete; See Incomplete Lines. However, when an output
line represents two differing lines, one might be incomplete while the
This option does not automatically select an output format; in order to other is not. In this case, the output line is complete, but its the gutter
use it, you must select the context format (See Context Format) or is marked \ if the first line is incomplete, / if the second line is.
unified format (See Unified Format). In other output formats it has no
effect. Side by side format is sometimes easiest to read, but it has limitations.
It generates much wider output than usual, and truncates lines that are
The -F and --show-function-line options find the nearest too long to fit. Also, it relies on lining up output more heavily than
unchanged line that precedes each hunk of differences and matches the usual, so its output looks particularly bad if you use varying width fonts,
given regular expression. Then they add that line to the end of the line nonstandard tab stops, or nonprinting characters.
of asterisks in the context format, or to the @@ line in unified format. If
no matching line exists, they leave the output for that hunk unchanged. You can use the sdiff command to interactively merge side by side
If that line is more than 40 characters long, they output only the first 40 differences. See Interactive Merging, for more information on merging
characters. You can specify more than one regular expression for such files.
lines; diff tries to match each line against each regular expression,
starting with the last one given. This means that you can use -p and
-F together, if you wish. Controlling Side by Side Format
Showing C Function Headings The -y or --side-by-side option selects side by side format.
Because side by side output lines contain two input lines, they are wider
To show in which functions differences occur for C and similar than usual. They are normally 130 columns, which can fit onto a
languages, you can use the -p or --show-c-function option. This traditional printer line. You can set the length of output lines with the
option automatically defaults to the context output format (See Context -W columns or --width=columns option. The output line is split
Format), with the default number of lines of context. You can override into two halves of equal length, separated by a small gutter to mark
that number with -C lines elsewhere in the command line. You can differences; the right half is aligned to a tab stop so that tabs line up.
override both the format and the number with -U lines elsewhere in Input lines that are too long to fit in half of an output line are truncated
the command line. for output.
The -p and --show-c-function options are equivalent to The --left-column option prints only the left column of two
-F’^[_a-zA-Z$]’ if the unified format is specified, otherwise -c common lines. The --suppress-common-lines option suppresses
-F’^[_a-zA-Z$]’ (See Specified Headings). GNU diff provides common lines entirely.
them for the sake of convenience.
An Example of Side by Side Format
Showing Alternate File Names Here is the output of the command diff -y -W 72 lao tzu (See
Sample diff Input, for the complete contents of the two files).
If you are comparing two files that have meaningless or uninformative
names, you might want diff to show alternate names in the header of The Way that can be told of is n <
the context and unified output formats. To do this, use the -L label The name that can be named is no <
or --label=label option. The first time you give this option, its The Nameless is the origin of He The Nameless is
argument replaces the name and date of the first file in the header; the the origin of He
second time, its argument replaces the name and date of the second file. The Named is the mother of all t | The named is the
If you give this option more than twice, diff reports an error. The -L mother of all t
option does not affect the file names in the pr header when the -l or >
--paginate option is used (See Pagination). Therefore let there always be no Therefore let
there always be no
Here are the first two lines of the output from diff -C2 -Loriginal so we may see their subtlety, so we may see their
-Lmodified lao tzu: subtlety,
And let there always be being, And let there
*** original always be being,
--- modified so we may see their outcome. so we may see their
outcome.
The two are the same, The two are the same,
Showing Differences Side by Side But after they are produced, But after they are
produced,
they have different names. they have different
diff can produce a side by side difference listing of two files. The names.
files are listed in two columns with a gutter between them. The gutter > They both may be called deep and
contains one of the following markers: > Deeper and more profound,
> The door of all subtleties!
white space
The corresponding lines are in common. That is, either the lines
are identical, or the difference is ignored because of one of the
--ignore options (See White Space).
Making Edit Scripts
| Several output modes produce command scripts for editing from-file to
The corresponding lines differ, and they are either both complete produce to-file.
or both incomplete.
< ed Scripts
The files differ and only the first file contains the line.
diff can produce commands that direct the ed text editor to change the
> first file into the second file. Long ago, this was the only output mode
The files differ and only the second file contains the line. that was suitable for editing one file into another automatically; today,
with patch, it is almost obsolete. Use the -e or --ed option to select
( this output format.
Only the first file contains the line, but the difference is ignored.
Like the normal format (See Normal), this output format does not show
) any context; unlike the normal format, it does not include the information
Only the second file contains the line, but the difference is necessary to apply the diff in reverse (to produce the first file if all you
ignored. have is the second file and the diff).
\ If the file d contains the output of diff -e old new, then the
The corresponding lines differ, and only the first line is command (cat d && echo w) | ed - old edits old to make it a
incomplete. copy of new. More generally, if d1, d2, …, dN contain the outputs of
diff -e old new1, diff -e new1 new2, …, diff -e newN-1
/ newN, respectively, then the command (cat d1 d2 … dN && echo
The corresponding lines differ, and only the second line is w) | ed - old edits old to make it a copy of newN.
incomplete.
- Page 6 -
d4 1
Detailed Description of ed Format a4 2
The ed output format consists of one or more hunks of differences. The The named is the mother of all things.
changes closest to the ends of the files come first so that commands that
change the number of lines do not affect how ed interprets line numbers a11 3
in succeeding commands. ed format hunks look like this: They both may be called deep and profound.
Deeper and more profound,
change-command The door of all subtleties!
to-file-line
to-file-line…
. Merging Files with If-then-else
Because ed uses a single period on a line to indicate the end of input,
GNU diff protects lines of changes that contain a single period on a You can use diff to merge two files of C source code. The output of
line by writing two periods instead, then writing a subsequent ed diff in this format contains all the lines of both files. Lines common
command to change the two periods into one. The ed format cannot to both files are output just once; the differing parts are separated by the
represent an incomplete line, so if the second file ends in a changed C preprocessor directives #ifdef name or #ifndef name, #else,
incomplete line, diff reports an error and then pretends that a newline and #endif. When compiling the output, you select which version to
was appended. use by either defining or leaving undefined the macro name.
There are three types of change commands. Each consists of a line To merge two files, use diff with the -D name or --ifdef=name
number or comma-separated range of lines in the first file and a single option. The argument name is the C preprocessor identifier to use in the
character indicating the kind of change to make. All line numbers are #ifdef and #ifndef directives.
the original line numbers in the file. The types of change commands are:
For example, if you change an instance of wait (&s) to waitpid
la (-1, &s, 0) and then merge the old and new files with the
Add text from the second file after line l in the first file. For --ifdef=HAVE_WAITPID option, then the affected part of your code
example, 8a means to add the following lines after line 8 of file might look like this:
1.
do {
rc #ifndef HAVE_WAITPID
Replace the lines in range r in the first file with the following if ((w = wait (&s)) < 0 && errno != EINTR)
lines. Like a combined add and delete, but more compact. For #else /* HAVE_WAITPID */
example, 5,7c means change lines 5--7 of file 1 to read as the if ((w = waitpid (-1, &s, 0)) < 0 && errno !=
text file 2. EINTR)
#endif /* HAVE_WAITPID */
rd return w;
Delete the lines in range r from the first file. For example, 5,7d } while (w != child);
means delete lines 5--7 of file 1.
You can specify formats for languages other than C by using line group
formats and line formats, as described in the next sections.
Example ed Script
Here is the output of diff -e lao tzu (See Sample diff Input, for the
complete contents of the two files): Line Group Formats
11a Line group formats let you specify formats suitable for many applications
They both may be called deep and profound. that allow if-then-else input, including programming languages and text
Deeper and more profound, formatting languages. A line group format specifies the output format for
The door of all subtleties! a contiguous group of similar lines.
.
4c For example, the following command compares the TeX files old and
The named is the mother of all things. new, and outputs a merged file in which old regions are surrounded by
\begin{em}-\end{em} lines, and new regions are surrounded by
. \begin{bf}-\end{bf} lines.
1,2d
diff \
Forward ed Scripts --old-group-format=’\begin{em}
%<\end{em}
’\
diff can produce output that is like an ed script, but with hunks in --new-group-format=’\begin{bf}
forward (front to back) order. The format of the commands is also %>\end{bf}
changed slightly: command characters precede the lines they modify, ’\
spaces separate line numbers in ranges, and no attempt is made to old new
disambiguate hunk lines consisting of a single period. Like ed format,
forward ed format cannot represent incomplete lines. The following command is equivalent to the above example, but it is a
little more verbose, because it spells out the default line group formats.
Forward ed format is not very useful, because neither ed nor patch
can apply diffs in this format. It exists mainly for compatibility with diff \
older versions of diff. Use the -f or --forward-ed option to --old-group-format=’\begin{em}
select it. %<\end{em}
’\
RCS Scripts --new-group-format=’\begin{bf}
%>\end{bf}
’\
The RCS output format is designed specifically for use by the Revision --unchanged-group-format=’%=’ \
Control System, which is a set of free programs used for organizing --changed-group-format=’\begin{em}
different versions and systems of files. Use the -n or --rcs option to %<\end{em}
select this output format. It is like the forward ed format (See Forward \begin{bf}
ed), but it can represent arbitrary changes to the contents of a file %>\end{bf}
because it avoids the forward ed format’s problems with lines consisting ’\
of a single period and with incomplete lines. Instead of ending text old new
sections with a line consisting of a single period, each command specifies
the number of lines it affects; a combination of the a and d commands Here is a more advanced example, which outputs a diff listing with
are used instead of c. Also, if the second file ends in a changed headers containing line numbers in a ‘‘plain English’’ style.
incomplete line, then the output also ends in an incomplete line.
diff \
Here is the output of diff -n lao tzu (See Sample diff Input, for the --unchanged-group-format=’’ \
complete contents of the two files): --old-group-format=’-------- %dn line%(n=1?:s)
deleted at %df:
d1 2 %<’ \
- Page 7 -
--new-group-format=’-------- %dN line%(N=1?:s) f + 1.
added after %de:
%>’ \ E, F, L, M, N
--changed-group-format=’-------- %dn Likewise, for lines in the new file.
line%(n=1?:s) changed at %df:
%<-------- to: The printf conversion specification can be %d, %o, %x, or %X,
%>’ \ specifying decimal, octal, lower case hexadecimal, or upper case
old new hexadecimal output respectively. After the % the following options
can appear in sequence: a - specifying left-justification; an integer
To specify a line group format, use diff with one of the options listed specifying the minimum field width; and a period followed by an
below. You can specify up to four line group formats, one for each optional integer specifying the minimum number of digits. For
kind of line group. You should quote format, because it typically example, %5dN prints the number of new lines in the group in a
contains shell metacharacters. field of width 5 characters, using the printf format "%5d".
--old-group-format=format (A=B?T:E)
These line groups are hunks containing only lines from the first If A equals B then T else E. A and B are each either a decimal
file. The default old group format is the same as the changed constant or a single letter interpreted as above. This format spec
group format if it is specified; otherwise it is a format that is equivalent to T if A’s value equals B’s; otherwise it is
outputs the line group as-is. equivalent to E.
--unchanged-group-format=format For example, the following command outputs text with a one-column
These line groups contain lines common to both files. The change indicator to the left of the text. The first column of output is -
default unchanged group format is a format that outputs the line for deleted lines, | for added lines, and a space for unchanged lines.
group as-is. The formats contain newline characters where newlines are desired on
output.
In a line group format, ordinary characters represent themselves;
conversion specifications start with % and have one of the following diff \
forms. --old-line-format=’-%l
’\
%< --new-line-format=’|%l
stands for the lines from the first file, including the trailing ’\
newline. Each line is formatted according to the old line format --unchanged-line-format=’ %l
(See Line Formats). ’\
old new
%>
stands for the lines from the second file, including the trailing To specify a line format, use one of the following options. You should
newline. Each line is formatted according to the new line format. quote format, since it often contains shell metacharacters.
%= --old-line-format=format
stands for the lines common to both files, including the trailing formats lines just from the first file.
newline. Each line is formatted according to the unchanged line
format. --new-line-format=format
formats lines just from the second file.
%%
stands for %. --unchanged-line-format=format
formats lines common to both files.
%c’C’
where C is a single character, stands for C. C may not be a --line-format=format
backslash or an apostrophe. For example, %c’:’ stands for a formats all lines; in effect, it sets all three above options
colon, even inside the then-part of an if-then-else format, which a simultaneously.
colon would normally terminate.
In a line format, ordinary characters represent themselves; conversion
%c’\O’ specifications start with % and have one of the following forms.
where O is a string of 1, 2, or 3 octal digits, stands for the
character with octal code O. For example, %c’\0’ stands for a %l
null character. stands for the the contents of the line, not counting its trailing
newline (if any). This format ignores whether the line is
Fn incomplete; See Incomplete Lines.
where F is a printf conversion specification and n is one of
the following letters, stands for n’s value formatted with F. %L
stands for the the contents of the line, including its trailing
e newline (if any). If a line is incomplete, this format preserves its
The line number of the line just before the group in the incompleteness.
old file.
%%
f stands for %.
The line number of the first line in the group in the old
file; equals e + 1. %c’C’
where C is a single character, stands for C. C may not be a
l backslash or an apostrophe. For example, %c’:’ stands for a
The line number of the last line in the group in the old colon.
file.
%c’\O’
m where O is a string of 1, 2, or 3 octal digits, stands for the
The line number of the line just after the group in the old character with octal code O. For example, %c’\0’ stands for a
file; equals l + 1. null character.
n Fn
The number of lines in the group in the old file; equals l - where F is a printf conversion specification, stands for the line
- Page 8 -
number formatted with F. For example, %.5dn prints the line #endif /* TWO */
number using the printf format "%.5d". See Line Group Therefore let there always be non-being,
Formats, for more about printf conversion specifications. so we may see their subtlety,
And let there always be being,
The default line format is %l followed by a newline character. so we may see their outcome.
The two are the same,
If the input contains tab characters and it is important that they line up But after they are produced,
on output, you should ensure that %l or %L in a line format is just after they have different names.
a tab stop (e.g. by preceding %l or %L with a tab character), or you #ifdef TWO
should use the -t or --expand-tabs option. They both may be called deep and profound.
Deeper and more profound,
Taken together, the line and line group formats let you specify many The door of all subtleties!
different formats. For example, the following command uses a format #endif /* TWO */
similar to diff’s normal format. You can tailor this command to get
fine control over diff’s output.
diff \
--old-line-format=’< %l
’ \
--new-line-format=’> %l
’ \
--old-group-format=’%df%(f=l?:,%dl)d%dE
%<’ \
--new-group-format=’%dea%dF%(F=L?:,%dL)
%>’ \
--changed-group-format=’%df%(f=l?:,%dl)c%dF%(F=L?:,%dL)
%<---
%>’ \
--unchanged-group-format=’’ \
old new
The old, new, and unchanged line formats specify the output format of
lines from the first file, lines from the second file, and lines common to
both files, respectively.
--old-group-format=’#ifndef name
%<#endif /* not name */
’ \
--new-group-format=’#ifdef name
%>#endif /* name */
’ \
--unchanged-group-format=’%=’ \
--changed-group-format=’#ifndef name
%<#else /* name */
%>#endif /* name */
’
You should carefully check the diff output for proper nesting. For
example, when using the the -D name or --ifdef=name option, you
should check that if the differing lines contain any of the C preprocessor
directives #ifdef, #ifndef, #else, #elif, or #endif, they are
nested properly and match. If they don’t, you must make corrections
manually. It is a good idea to carefully check the resulting code anyway
to make sure that it really does what you want it to; depending on how
the input files were produced, the output might contain duplicate or
otherwise incorrect code.
The patch -D name option behaves just like the diff -D name
option, except it operates on a file and a diff to produce a merged file;
See patch Options.
#ifndef TWO
The Way that can be told of is not the eternal
Way;
The name that can be named is not the eternal
name.
#endif /* not TWO */
The Nameless is the origin of Heaven and Earth;
#ifndef TWO
The Named is the mother of all things.
#else /* TWO */
The named is the mother of all things.
- Page 9 -
Comparing Directories Making diff Output Prettier
You can use diff to compare some or all of the files in two directory diff provides several ways to adjust the appearance of its output.
trees. When both file name arguments to diff are directories, it These adjustments can be applied to any output format.
compares each file that is contained in both directories, examining file
names in alphabetical order. Normally diff is silent about pairs of files
that contain no differences, but if you use the -s or Preserving Tabstop Alignment
--report-identical-files option, it reports pairs of identical
files. Normally diff reports subdirectories common to both directories The lines of text in some of the diff output formats are preceded by
without comparing subdirectories’ files, but if you use the -r or one or two characters that indicate whether the text is inserted, deleted,
--recursive option, it compares every corresponding pair of files in or changed. The addition of those characters can cause tabs to move to
the directory trees, as many levels deep as they go. the next tabstop, throwing off the alignment of columns in the line.
GNU diff provides two ways to make tab-aligned columns line up
For file names that are in only one of the directories, diff normally correctly.
does not show the contents of the file that exists; it reports only that the
file exists in that directory and not in the other. You can make diff The first way is to have diff convert all tabs into the correct number
act as though the file existed but was empty in the other directory, so of spaces before outputting them; select this method with the -t or
that it outputs the entire contents of the file that actually exists. (It is --expand-tabs option. diff assumes that tabstops are set every 8
output as either an insertion or a deletion, depending on whether it is in columns. To use this form of output with patch, you must give
the first or the second directory given.) To do this, use the -N or patch the -l or --ignore-white-space option (See Changed
--new-file option. White Space, for more information).
If the older directory contains one or more large files that are not in the The other method for making tabs line up correctly is to add a tab
newer directory, you can make the patch smaller by using the -P or character instead of a space after the indicator character at the beginning
--unidirectional-new-file option instead of -N. This option is of the line. This ensures that all following tab characters are in the same
like -N except that it only inserts the contents of files that appear in the position relative to tabstops that they were in the original files, so that
second directory but not the first (that is, files that were added). At the the output is aligned correctly. Its disadvantage is that it can make long
top of the patch, write instructions for the user applying the patch to lines too long to fit on one line of the screen or the paper. It also does
remove the files that were deleted before applying the patch. See Making not work with the unified output format, which does not have a space
Patches, for more discussion of making patches for distribution. character after the change type indicator character. Select this method
with the -T or --initial-tab option.
To ignore some files while comparing directories, use the -x pattern
or --exclude=pattern option. This option ignores any files or
subdirectories whose base names match the shell pattern pattern. Unlike
in the shell, a period at the start of the base of a file name matches a
Paginating diff Output
wildcard at the start of a pattern. You should enclose pattern in quotes
so that the shell does not expand it. For example, the option -x It can be convenient to have long output page-numbered and
’*.[ao]’ ignores any file whose name ends with .a or .o. time-stamped. The -l and --paginate options do this by sending the
diff output through the pr program. Here is what the page header
This option accumulates if you specify it more than once. For example, might look like for diff -lc lao tzu:
using the options -x ’RCS’ -x ’*,v’ ignores any file or subdirectory
whose base name is RCS or ends with ,v. Mar 11 13:37 1991 diff -lc lao tzu Page 1
If you need to give this option many times, you can instead put the
patterns in a file, one pattern per line, and use the -X file or
--exclude-from=file option.
If you have been comparing two directories and stopped partway through,
later you might want to continue where you left off. You can do this
by using the -S file or --starting-file=file option. This
compares only the file file and all alphabetically later files in the topmost
directory level.
- Page 10 -
diff Performance Tradeoffs Comparing Three Files
GNU diff runs quite efficiently; however, in some circumstances you Use the program diff3 to compare three files and show any differences
can cause it to run faster or produce a more compact set of changes. among them. (diff3 can also merge files; see See diff3 Merging).
There are two ways that you can affect the performance of GNU diff
by changing the way it compares files. The ‘‘normal’’ diff3 output format shows each hunk of differences
without surrounding context. Hunks are labeled depending on whether
Performance has more than one dimension. These options improve one they are two-way or three-way, and lines are annotated by their location
aspect of performance at the cost of another, or they improve performance in the input files.
in some cases while hurting it in others.
See Invoking diff3, for more information on how to run diff3.
The way that GNU diff determines which lines have changed always
comes up with a near-minimal set of differences. Usually it is good
enough for practical purposes. If the diff output is large, you might A Third Sample Input File
want diff to use a modified algorithm that sometimes produces a
smaller set of differences. The -d or --minimal option does this; Here is a third sample file that will be used in examples to illustrate the
however, it can also cause diff to run more slowly than usual, so it is output of diff3 and how various options can change it. The first two
not the default behavior. files are the same that we used for diff (See Sample diff Input). This
is the third sample file, called tao:
When the files you are comparing are large and have small groups of
changes scattered throughout them, you can use the -H or The Way that can be told of is not the eternal
--speed-large-files option to make a different modification to the Way;
algorithm that diff uses. If the input files have a constant small The name that can be named is not the eternal
density of changes, this option speeds up the comparisons without name.
changing the output. If not, diff might produce a larger set of The Nameless is the origin of Heaven and Earth;
differences; however, the output will still be correct. The named is the mother of all things.
Normally diff discards the prefix and suffix that is common to both Therefore let there always be non-being,
files before it attempts to find a minimal set of differences. This makes so we may see their subtlety,
diff run faster, but occasionally it may produce non-minimal output. And let there always be being,
The --horizon-lines=lines option prevents diff from discarding so we may see their result.
the last lines lines of the prefix and the first lines lines of the suffix. The two are the same,
This gives diff further opportunities to find a minimal output. But after they are produced,
they have different names.
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.
diff3 Hunks
Groups of lines that differ in two or three of the input files are called
diff3 hunks, by analogy with diff hunks (See 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.
- Page 11 -
For example, suppose F contains the three lines a, b, f, G contains the
lines g, b, g, and H contains the lines a, b, h. diff3 F G H might Merging From a Common Ancestor
output the following:
====2 When two people have made changes to copies of the same file, diff3
1:1c can produce a merged output that contains both sets of changes together
3:1c with warnings about conflicts.
a
2:1c One might imagine programs with names like diff4 and diff5 to
g compare more than three files simultaneously, but in practice the need
==== rarely arises. You can use diff3 to merge three or more sets of
1:3c changes to a file by merging two change sets at a time.
f
2:3c diff3 can incorporate changes from two modified versions into a
g common preceding version. This lets you merge the sets of changes
3:3c represented by the two newer files. Specify the common ancestor version
h as the second argument and the two newer versions as the first and third
arguments, like this:
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, diff3 mine older yours
then a three-way hunk containing the last line of each file.
You can remember the order of the arguments by noting that they are in
alphabetical order.
An Example of diff3 Normal Format
You can think of this as subtracting older from yours and adding the
Here is the output of the command diff3 lao tzu tao (See Sample result to mine, or as merging into mine the changes that would turn older
diff3 Input, for the complete contents of the files). Notice that it shows into yours. This merging is well-defined as long as mine and older
only the lines that are different among the three files. 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
====2 conflict. When all three input files differ, we call the conflict an overlap.
1:1,2c
3:1,2c diff3 gives you several ways to handle overlaps and conflicts. You
The Way that can be told of is not the eternal can omit overlaps or conflicts, or select only overlaps, or mark conflicts
Way; with special <<<<<<< and >>>>>>> lines.
The name that can be named is not the eternal
name. diff3 can output the merge results as an ed script that that can be
2:0a applied to the first file to yield the merged output. However, it is
====1 usually better to have diff3 generate the merged output directly; this
1:4c bypasses some problems with ed.
The Named is the mother of all things.
2:2,3c
3:4,5c
The named is the mother of all things.
Selecting Which Changes to Incorporate
====3
1:8c You can select all unmerged changes from older to yours for merging
2:7c into mine with the -e or --ed option. You can select only the
so we may see their outcome. nonoverlapping unmerged changes with -3 or --easy-only, and you
3:9c can select only the overlapping changes with -x or --overlap-only.
so we may see their result.
==== The -e, -3 and -x options select only unmerged changes, i.e. changes
1:11a where mine and yours differ; they ignore changes from older to yours
2:11,13c where mine and yours are identical, because they assume that such
They both may be called deep and profound. changes have already been merged. If this assumption is not a safe one,
Deeper and more profound, you can use the -A or --show-all option (See Marking Conflicts).
The door of all subtleties!
3:13,14c Here is the output of the command diff3 with each of these three
-- The Way of Lao-Tzu, tr. Wing-tsit Chan options (See Sample diff3 Input, 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 11a
of diff3 -e lao tzu tao:
Output 8c
of diff3 -3 lao tzu tao:
so we may see their result.
.
Output 11a
of diff3 -x lao tzu tao:
Marking Conflicts
diff3 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
- Page 12 -
A conflict that comes from three files A, B and C is marked as follows: Deeper and more profound,
The door of all subtleties!
<<<<<<< A =======
lines from A
||||||| B -- The Way of Lao-Tzu, tr. Wing-tsit Chan
lines from B >>>>>>> tao
=======
lines from C
>>>>>>> C How diff3 Merges Incomplete Lines
The -A or --show-all option acts like the -e option, except that it With -m, incomplete lines (See Incomplete Lines) are simply copied to
brackets conflicts, and it outputs all changes from older to yours, not just the output as they are found; if the merged output ends in an conflict and
the unmerged changes. Thus, given the sample input files (See Sample one of the input files ends in an incomplete line, succeeding |||||||,
diff3 Input), diff3 -A lao tzu tao puts brackets around the conflict ======= or >>>>>>> brackets appear somewhere other than the start
where only tzu differs: of a line because they are appended to the incomplete line.
<<<<<<< tzu 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
The Way that can be told of is not the eternal present.
Way;
The name that can be named is not the eternal
name.
>>>>>>> tao
Saving the Changed File
And it outputs the three-way conflict as follows: Traditional Unix diff3 generates an ed script without the trailing w and
and q commands that save the changes. System V diff3 generates
<<<<<<< lao these extra commands. GNU diff3 normally behaves like traditional
||||||| tzu Unix diff3, but with the -i option it behaves like System V diff3
They both may be called deep and profound. and appends the w and q commands.
Deeper and more profound,
The door of all subtleties! The -i option requires one of the ed script options -AeExX3, and is
======= incompatible with the merged output option -m.
<<<<<<< lao
=======
For example, the command diff3 -m lao tzu tao (See Sample diff3
Input 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.
- Page 13 -
Interactive Merging with sdiff Merging with patch
patch takes comparison output produced by diff and applies the
With sdiff, you can merge two files interactively based on a differences to a copy of the original file, producing a patched version.
side-by-side -y format comparison (See Side by Side). Use -o file With patch, you can distribute just the changes to a set of files instead
or --output=file to specify where to put the merged text. See of distributing the entire file set; your correspondents can apply patch
Invoking sdiff, for more details on the options to sdiff. to update their copy of the files with your changes. patch
automatically determines the diff format, skips any leading or trailing
Another way to merge files interactively is to use the Emacs Lisp headers, and uses the headers to determine which file to patch. This lets
package emerge. See emerge, , emerge, emacs, The GNU Emacs your correspondents feed an article or message containing a difference
Manual, for more information. listing directly to patch.
patch detects and warns about common problems like forward patches.
Specifying diff Options to sdiff It saves the original version of the files it patches, and saves any patches
that it could not apply. It can also maintain a patchlevel.h file to
ensures that your correspondents apply diffs in the proper order.
The following sdiff options have the same meaning as for diff. See
diff Options, for the use of these options. patch accepts a series of diffs in its standard input, usually separated
by headers that specify which file to patch. It applies diff hunks (See
-a -b -d -i -t -v Hunks) one by one. If a hunk does not exactly match the original file,
-B -H -I regexp patch uses heuristics to try to patch the file as well as it can. If no
approximate match can be found, patch rejects the hunk and skips to
--ignore-blank-lines --ignore-case the next hunk. patch normally replaces each file f with its new
--ignore-matching-lines=regexp version, saving the original file in f.orig, and putting reject hunks (if
--ignore-space-change any) into f.rej.
--left-column --minimal --speed-large-files
--suppress-common-lines --expand-tabs See Invoking patch, for detailed information on the options to patch.
--text --version --width=columns See Backups, for more information on how patch names backup files.
See Rejects, for more information on where patch puts reject hunks.
For historical reasons, sdiff has alternate names for some options. The
-l option is equivalent to the --left-column option, and similarly
-s is equivalent to --suppress-common-lines. The meaning of
the sdiff -w and -W options is interchanged from that of diff: with
Selecting the patch Input Format
sdiff, -w columns is equivalent to --width=columns, and -W is
equivalent to --ignore-all-space. sdiff without the -o option patch normally determines which diff format the patch file uses by
is equivalent to diff with the -y or --side-by-side option (See examining its contents. For patch files that contain particularly confusing
Side by Side). leading text, you might need to use one of the following options to force
patch to interpret the patch file as a certain format of diff. The output
formats listed here are the only ones that patch can understand.
Merge Commands
-c
--context
Groups of common lines, with a blank gutter, are copied from the first context diff.
file to the output. After each group of differing lines, sdiff prompts
with % and pauses, waiting for one of the following commands. Follow -e
each command with RET. --ed
ed script.
e
Discard both versions. Invoke a text editor on an empty -n
temporary file, then copy the resulting file to the output. --normal
normal diff.
eb
Concatenate the two versions, edit the result in a temporary file, -u
then copy the edited result to the output. --unified
unified diff.
el
Edit a copy of the left version, then copy the result to the output.
er
Applying Imperfect Patches
Edit a copy of the right version, then copy the result to the
output. patch tries to skip any leading text in the patch file, apply the diff, and
then skip any trailing text. Thus you can feed a news article or mail
l message directly to patch, and it should work. If the entire diff is
Copy the left version to the output. indented by a constant amount of white space, patch automatically
ignores the indentation.
q
Quit. However, certain other types of imperfect input require user intervention.
For context diffs, and to a lesser extent normal diffs, patch can detect
when the line numbers mentioned in the patch are incorrect, and it Messages and Questions from patch
attempts to find the correct place to apply each hunk of the patch. As a
first guess, it takes the line number mentioned in the hunk, plus or minus patch can produce a variety of messages, especially if it has trouble
any offset used in applying the previous hunk. If that is not the correct decoding its input. In a few situations where it’s not sure how to
place, patch scans both forward and backward for a set of lines proceed, patch normally prompts you for more information from the
matching the context given in the hunk. keyboard. There are options to suppress printing non-fatal messages and
stopping for keyboard input.
First patch looks for a place where all lines of the context match. If it
cannot find such a place, and it is reading a context or unified diff, and The message Hmm... indicates that patch is reading text in the patch
the maximum fuzz factor is set to 1 or more, then patch makes another file, attempting to determine whether there is a patch in that text, and if
scan, ignoring the first and last line of context. If that fails, and the so, what kind of patch it is.
maximum fuzz factor is set to 2 or more, it makes another scan,
ignoring the first two and last two lines of context are ignored. It You can inhibit all terminal output from patch, unless an error occurs,
continues similarly if the maximum fuzz factor is larger. by using the -s, --quiet, or --silent option.
The -F lines or --fuzz=lines option sets the maximum fuzz factor There are two ways you can prevent patch from asking you any
to lines. This option only applies to context and unified diffs; it ignores questions. The -f or --force option assumes that you know what you
up to lines lines while looking for the place to install a hunk. Note that are doing. It assumes the following:
a larger fuzz factor increases the odds of making a faulty patch. The
default fuzz factor is 2; it may not be set to more than the number of • skip patches that do not contain file names in their headers;
lines of context in the diff, ordinarily 3.
• patch files even though they have the wrong version for the
If patch cannot find a place to install a hunk of the patch, it writes the Prereq: line in the patch;
hunk out to a reject file (See Rejects, for information on how reject files
are named). It writes out rejected hunks in context format no matter • assume that patches are not reversed even if they look like they
what form the input patch is in. If the input is a normal or ed diff, are.
many of the contexts are simply null. The line numbers on the hunks in
the reject file may be different from those in the patch file: they show The -t or --batch option is similar to -f, in that it suppresses
the approximate location where patch thinks the failed hunks belong in questions, but it makes somewhat different assumptions:
the new file rather than in the old one.
• skip patches that do not contain file names in their headers (the
As it completes each hunk, patch tells you whether the hunk succeeded same as -f);
or failed, and if it failed, on which line (in the new file) patch thinks
the hunk should go. If this is different from the line number specified • skip patches for which the file has the wrong version for the
in the diff, it tells you the offset. A single large offset may indicate that Prereq: line in the patch;
patch installed a hunk in the wrong place. patch also tells you if it
used a fuzz factor to make the match, in which case you should also be • assume that patches are reversed if they look like they are.
slightly suspicious.
patch exits with a non-zero status if it creates any reject files. When
patch cannot tell if the line numbers are off in an ed script, and can applying a set of patches in a loop, you should check the exit status, so
only detect wrong line numbers in a normal diff when it finds a change you don’t apply a later patch to a partially patched file.
or delete command. It may have the same problem with a context diff
using a fuzz factor equal to or greater than the number of lines of
context shown in the diff (typically 3). In these cases, you should
probably look at a context diff between your original and patched input
files to see if the changes make sense. Compiling without errors is a
pretty good indication that the patch worked, but not a guarantee.
patch usually produces the correct results, even when it must make
many guesses. However, the results are guaranteed only when the patch
is applied to an exact copy of the file that the patch was generated from.
Make sure you have specified the file names correctly, either in a cmp options… from-file [to-file]
context diff header or with an Index: line. If you are patching files in
a subdirectory, be sure to tell the patch user to specify a -p or The file name - is always the standard input. cmp also uses the
--strip option as needed. Take care to not send out reversed patches, standard input if one file name is omitted.
since these make people wonder whether they have already applied the
patch. An exit status of 0 means no differences were found, 1 means some
differences were found, and 2 means trouble.
To save people from partially applying a patch before other patches that
should have gone before it, you can make the first patch in the patch
file update a file with a name like patchlevel.h or version.c, Options to cmp
which contains a patch level or version number. If the input file
contains the wrong version number, patch will complain immediately. Below is a summary of all of the options that GNU cmp accepts. Most
options have two equivalent names, one of which is a single letter
An even clearer way to prevent this problem is to put a Prereq: line preceded by -, and the other of which is a long name preceded by --.
before the patch. If the leading text in the patch file contains a line that Multiple single letter options (unless they take an argument) can be
starts with Prereq:, patch takes the next word from that line combined into a single command line word: -cl is equivalent to -c -l.
(normally a version number) and checks whether the next input file
contains that word, preceded and followed by either white space or a -c
newline. If not, patch prompts you for confirmation before proceeding. Print the differing characters. Display control characters as a ^
This makes it difficult to accidentally apply patches in the wrong order. followed by a letter of the alphabet and precede characters that
have the high bit set with M- (which stands for ‘‘meta’’).
Since patch does not handle incomplete lines properly, make sure that
all the source files in your program end with a newline whenever you --ignore-initial=bytes
release a version. Ignore any differences in the the first bytes bytes of the input
files. Treat files with fewer than bytes bytes as if they are empty.
To create a patch that changes an older version of a package into a
newer version, first make a copy of the older version in a scratch -l
directory. Typically you do that by unpacking a tar or shar archive Print the (decimal) offsets and (octal) values of all differing bytes.
of the older version.
--print-chars
You might be able to reduce the size of the patch by renaming or Print the differing characters. Display control characters as a ^
removing some files before making the patch. If the older version of the followed by a letter of the alphabet and precede characters that
package contains any files that the newer version does not, or if any files have the high bit set with M- (which stands for ‘‘meta’’).
have been renamed between the two versions, make a list of rm and mv
commands for the user to execute in the old version directory before --quiet
applying the patch. Then run those commands yourself in the scratch -s
directory. --silent
Do not print anything; only return an exit status indicating
If there are any files that you don’t need to include in the patch because whether the files differ.
they can easily be rebuilt from other files (for example, TAGS and output
from yacc and makeinfo), replace the versions in the scratch directory --verbose
with the newer versions, using rm and ln or cp. Print the (decimal) offsets and (octal) values of all differing bytes.
Now you can create the patch. The de-facto standard diff format for -v
patch distributions is context format with two lines of context, produced --version
by giving diff the -C 2 option. Do not use less than two lines of Output the version number of cmp.
context, because patch typically needs at least two lines for proper
operation. Give diff the -P option in case the newer version of the
package contains any files that the older one does not. Make sure to
specify the scratch directory first and the newer directory second.
Add to the top of the patch a note telling the user any rm and mv
commands to run before applying the patch. Then you can remove the
scratch directory.
- Page 16 -
preprocessor macro name. See If-then-else.
Invoking diff -e
--ed
The format for running the diff command is: Make output that is a valid ed script. See ed Scripts.
- Page 17 -
--left-column --side-by-side
Print only the left column of two common lines in side by side Use the side by side output format. See Side by Side Format.
format. See Side by Side Format.
--speed-large-files
--line-format=format Use heuristics to speed handling of large files that have numerous
Use format to output all input lines in if-then-else format. See scattered small changes. See diff Performance.
Line Formats.
--starting-file=file
--minimal When comparing directories, start with the file file. This is used
Change the algorithm to perhaps find a smaller set of changes. for resuming an aborted comparison. See Comparing Directories.
This makes diff slower (sometimes much slower). See diff
Performance. --suppress-common-lines
Do not print common lines in side by side format. See Side by
-n Side Format.
Output RCS-format diffs; like -f except that each command
specifies the number of lines affected. See RCS. -t
Expand tabs to spaces in the output, to preserve the alignment of
-N tabs in the input files. See Tabs.
--new-file
In directory comparison, if a file is found in only one directory, -T
treat it as present but empty in the other directory. See Output a tab rather than a space before the text of a line in
Comparing Directories. normal or context format. This causes the alignment of tabs in
the line to look normal. See Tabs.
--new-group-format=format
Use format to output a group of lines taken from just the second --text
file in if-then-else format. See Line Group Formats. Treat all files as text and compare them line-by-line, even if they
do not appear to be text. See Binary.
--new-line-format=format
Use format to output a line taken from just the second file in -u
if-then-else format. See Line Formats. Use the unified output format. See Unified Format.
--old-group-format=format --unchanged-group-format=format
Use format to output a group of lines taken from just the first file Use format to output a group of common lines taken from both
in if-then-else format. See Line Group Formats. files in if-then-else format. See Line Group Formats.
--old-line-format=format --unchanged-line-format=format
Use format to output a line taken from just the first file in Use format to output a line common to both files in if-then-else
if-then-else format. See Line Formats. format. See Line Formats.
-p --unidirectional-new-file
Show which C function each change is in. See C Function When comparing directories, if a file appears only in the second
Headings. directory of the two, treat it as present but empty in the other.
See Comparing Directories.
-P
When comparing directories, if a file appears only in the second -U lines
directory of the two, treat it as present but empty in the other. --unified[=lines]
See Comparing Directories. Use the unified output format, showing lines (an integer) lines of
context, or three if lines is not given. See Unified Format. For
--paginate proper operation, patch typically needs at least two lines of
Pass the output through pr to paginate it. See Pagination. context.
-q -v
Report only whether the files differ, not the details of the --version
differences. See Brief. Output the version number of diff.
-r -w
When comparing directories, recursively compare any Ignore white space when comparing lines. See White Space.
subdirectories found. See Comparing Directories.
-W columns
--rcs --width=columns
Output RCS-format diffs; like -f except that each command Use an output width of columns in side by side format. See Side
specifies the number of lines affected. See RCS. by Side Format.
--recursive -x pattern
When comparing directories, recursively compare any When comparing directories, ignore files and subdirectories whose
subdirectories found. See Comparing Directories. basenames match pattern. See Comparing Directories.
--report-identical-files -X file
Report when two files are the same. See Comparing Directories. When comparing directories, ignore files and subdirectories whose
basenames match any pattern contained in file. See Comparing
-s Directories.
Report when two files are the same. See Comparing Directories.
-y
-S file Use the side by side output format. See Side by Side Format.
When comparing directories, start with the file file. This is used
for resuming an aborted comparison. See Comparing Directories.
--sdiff-merge-assist
Print extra information to help sdiff. sdiff uses this option
when it runs diff. This option is not intended for users to use
directly.
--show-c-function
Show which C function each change is in. See C Function
Headings.
--show-function-line=regexp
In context and unified format, for each hunk of differences, show
some of the last preceding line that matches regexp. See
Specified Headings.
- Page 18 -
Marking Conflicts.
Invoking diff3 --show-overlap
Like -e, except bracket lines from overlapping changes’ first and
The diff3 command compares three files and outputs descriptions of third files. See Marking Conflicts.
their differences. Its arguments are as follows:
-T
diff3 options… mine older yours 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
The files to compare are mine, older, and yours. At most one of these look normal. See Tabs.
three file names may be -, which tells diff3 to read the standard input
for that file. --text
Treat all files as text and compare them line-by-line, even if they
An exit status of 0 means diff3 was successful, 1 means some do not appear to be text. See Binary.
conflicts were found, and 2 means trouble.
-v
--version
Options to diff3 Output the version number of diff3.
-x
Below is a summary of all of the options that GNU diff3 accepts. Like -e, except output only the overlapping changes. See Which
Multiple single letter options (unless they take an argument) can be Changes.
combined into a single command line argument.
-X
-a Like -E, except output only the overlapping changes. In other
Treat all files as text and compare them line-by-line, even if they words, like -x, except bracket changes as in -E. See Marking
do not appear to be text. See Binary. Conflicts.
-A -3
Incorporate all changes from older to yours into mine, surrounding Like -e, except output only the nonoverlapping changes. See
all conflicts with bracket lines. See Marking Conflicts. Which Changes.
-e
Generate an ed script that incorporates all the changes from older
to yours into mine. See Which Changes.
-E
Like -e, except bracket lines from overlapping changes’ first and
third files. See Marking Conflicts. With -e, an overlapping
change looks like this:
<<<<<<< mine
lines from mine
=======
lines from yours
>>>>>>> yours
--ed
Generate an ed script that incorporates all the changes from older
to yours into mine. See Which Changes.
--easy-only
Like -e, except output only the nonoverlapping changes. See
Which Changes.
-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 Saving the Changed File.
--initial-tab
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. See Tabs.
-L label
--label=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
Marking Conflicts.
-m
--merge
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 Bypassing ed.
--overlap-only
Like -e, except output only the overlapping changes. See Which
Changes.
--show-all
Incorporate all unmerged changes from older to yours into mine,
surrounding all overlapping changes with bracket lines. See
- Page 19 -
example, the backups of a file named sink would be called,
Invoking patch successively, sink.~1~, sink.~2~, sink.~3~, etc.
patch can also create numbered backup files the way GNU Emacs -D name
does. With this method, instead of having a single backup of each file, Make merged if-then-else output using format. See If-then-else.
patch makes a new backup file name each time it patches a file. For
- Page 20 -
--debug=number --skip
Set internal debugging flags. Of interest only to patch patchers. Ignore this patch from the patch file, but continue looking for the
next patch in the file. See Multiple Patches.
-e
--ed --strip[=number]
Interpret the patch file as an ed script. See patch Input. Set the file name strip count to number. See patch Directories.
-E --suffix=backup-suffix
Remove output files that are empty after the patches have been Use backup-suffix as the backup extension instead of .orig or ~.
applied. See Empty Files. See Backups.
-f -t
Assume that the user knows exactly what he or she is doing, and Do not ask any questions. See patch Messages.
do not ask any questions. See patch Messages.
-u
-F lines --unified
Set the maximum fuzz factor to lines. See Inexact. Interpret the patch file as a unified diff. See patch Input.
--force -v
Assume that the user knows exactly what he or she is doing, and Output the revision header and patch level of patch.
do not ask any questions. See patch Messages.
-V backup-style
--forward Select the kind of backups to make. See Backups.
Ignore patches that patch thinks are reversed or already applied.
See also -R. See Reversed Patches. --version
Output the revision header and patch level of patch, then exit.
--fuzz=lines
Set the maximum fuzz factor to lines. See Inexact. --version=control=backup-style
Select the kind of backups to make. See Backups.
--help
Print a summary of the options that patch recognizes, then exit. -x number
Set internal debugging flags. Of interest only to patch patchers.
--ifdef=name
Make merged if-then-else output using format. See If-then-else.
--ignore-white-space
-l
Let any sequence of white space in the patch file match any
sequence of white space in the input file. See Changed White
Space.
-n
--normal
Interpret the patch file as a normal diff. See patch Input.
-N
Ignore patches that patch thinks are reversed or already applied.
See also -R. See Reversed Patches.
-o output-file
--output=output-file
Use output-file as the output file name. See patch Options.
-p[number]
Set the file name strip count to number. See patch Directories.
--prefix=backup-prefix
Use backup-prefix as a prefix to the backup file name. If this
option is specified, any -b option is ignored. See Backups.
--quiet
Work silently unless an error occurs. See patch Messages.
-r reject-file
Use reject-file as the reject file name. See Rejects.
-R
Assume that this patch was created with the old and new files
swapped. See Reversed Patches.
--reject-file=reject-file
Use reject-file as the reject file name. See Rejects.
--remove-empty-files
Remove output files that are empty after the patches have been
applied. See Empty Files.
--reverse
Assume that this patch was created with the old and new files
swapped. See Reversed Patches.
-s
Work silently unless an error occurs. See patch Messages.
-S
Ignore this patch from the patch file, but continue looking for the
next patch in the file. See Multiple Patches.
--silent
Work silently unless an error occurs. See patch Messages.
- Page 21 -
--minimal
Invoking sdiff Change the algorithm to perhaps find a smaller set of changes.
This makes sdiff slower (sometimes much slower). See diff
Performance.
The sdiff command merges two files and interactively outputs the
results. Its arguments are as follows: -o file
--output=file
sdiff -o outfile options… from-file to-file Put merged output into file. This option is required for merging.
-v
Options to sdiff --version
Output the version number of sdiff.
Below is a summary of all of the options that GNU sdiff accepts. -w columns
Each option has two equivalent names, one of which is a single letter --width=columns
preceded by -, and the other of which is a long name preceded by --. Use an output width of columns. See Side by Side Format.
Multiple single letter options (unless they take an argument) can be Note that for historical reasons, this option is -W in diff, -w in
combined into a single command line argument. Long named options sdiff.
can be abbreviated to any unique prefix of their name.
-W
-a Ignore horizontal white space when comparing lines. See White
Treat all files as text and compare them line-by-line, even if they Space. Note that for historical reasons, this option is -w in
do not appear to be text. See Binary. diff, -W in sdiff.
-b
Ignore changes in amount of white space. See White Space.
-B
Ignore changes that just insert or delete blank lines. See Blank
Lines.
-d
Change the algorithm to perhaps find a smaller set of changes.
This makes sdiff slower (sometimes much slower). See diff
Performance.
-H
Use heuristics to speed handling of large files that have numerous
scattered small changes. See diff Performance.
--expand-tabs
Expand tabs to spaces in the output, to preserve the alignment of
tabs in the input files. See Tabs.
-i
Ignore changes in case; consider upper- and lower-case to be the
same. See Case Folding.
-I regexp
Ignore changes that just insert or delete lines that match regexp.
See Specified Folding.
--ignore-all-space
Ignore white space when comparing lines. See White Space.
--ignore-blank-lines
Ignore changes that just insert or delete blank lines. See Blank
Lines.
--ignore-case
Ignore changes in case; consider upper- and lower-case to be the
same. See Case Folding.
--ignore-matching-lines=regexp
Ignore changes that just insert or delete lines that match regexp.
See Specified Folding.
--ignore-space-change
Ignore changes in amount of white space. See White Space.
-l
--left-column
Print only the left column of two common lines. See Side by
Side Format.
- Page 22 -
Incomplete Lines Future Projects
Here are some ideas for improving GNU diff and patch. The GNU
When an input file ends in a non-newline character, its last line is called project has identified some improvements as potential programming
an incomplete line because its last character is not a newline. All other projects for volunteers. You can also help by reporting any bugs that
lines are called full lines and end in a newline character. Incomplete you find.
lines do not match full lines unless differences in white space are
ignored (See White Space). If you are a programmer and would like to contribute something to the
GNU project, please consider volunteering for one of these projects. If
An incomplete line is normally distinguished on output from a full line you are seriously contemplating work, please write to
by a following line that starts with \. However, the RCS format (See [email protected] to coordinate with other volunteers.
RCS) outputs the incomplete line as-is, without any trailing newline or
following line. The side by side format normally represents incomplete
lines as-is, but in some cases uses a \ or / gutter marker; See Side by Suggested Projects for Improving GNU
Side. The if-then-else line format preserves a line’s incompleteness with
%L, and discards the newline with %l; See Line Formats. Finally, with diff and patch
the ed and forward ed output formats (See Output Formats) diff
cannot represent an incomplete line, so it pretends there was a newline One should be able to use GNU diff to generate a patch from any
and reports an error. pair of directory trees, and given the patch and a copy of one such tree,
use patch to generate a faithful copy of the other. Unfortunately, some
For example, suppose F and G are one-byte files that contain just f and changes to directory trees cannot be expressed using current patch
g, respectively. Then diff F G outputs formats; also, patch does not handle some of the existing formats.
These shortcomings motivate the following suggested projects.
1c1
<f
\ No newline at end of file Handling Changes to the Directory Structure
---
>g diff and patch do not handle some changes to directory structure.
\ No newline at end of file For example, suppose one directory tree contains a directory named D
with some subsidiary files, and another contains a file with the same
(The exact message may differ in non-English locales.) diff -n F G name D. diff -r does not output enough information for patch to
outputs the following without a trailing newline: transform the the directory subtree into the file.
d1 1 There should be a way to specify that a file has been deleted without
a1 1 having to include its entire contents in the patch file. There should also
g be a way to tell patch that a file was renamed, even if there is no way
for diff to generate such information.
diff -e F G reports two errors and outputs the following:
These problems can be fixed by extending the diff output format to
1c represent changes in directory structure, and extending patch to
g understand these extensions.
.
Files that are Neither Directories Nor Regular
Files
Some files are neither directories nor regular files: they are unusual files
like symbolic links, device special files, named pipes, and sockets.
Currently, diff treats symbolic links like regular files; it treats other
special files like regular files if they are specified at the top level, but
simply reports their presence when comparing directories. This means
that patch cannot represent changes to such files. For example, if you
change which file a symbolic link points to, diff outputs the difference
between the two files, instead of the change to the symbolic link.
Arbitrary Limits
GNU diff can analyze files with arbitrarily long lines and files that
end in incomplete lines. However, patch cannot patch such files. The
patch internal limits on line lengths should be removed, and patch
should be extended to parse diff reports of incomplete lines.
Then scan the two files sequentially again, checking each match to see
- Page 23 -
whether it is real. When a match is not real, mark both the ‘‘matching’’
lines as changed. Then build an edit script as usual.
It is not clear how general this feature can or should be, or what syntax
should be used for it.
Reporting Bugs
If you think you have found a bug in GNU cmp, diff, diff3,
sdiff, or patch, please report it by electronic mail to
[email protected]. Send as precise a description
of the problem as you can, including sample input files that produce the
bug, if applicable.
Because Larry Wall has not released a new version of patch since mid
1988 and the GNU version of patch has been changed since then,
please send bug reports for patch by electronic mail to both
[email protected] and [email protected].
- Page 24 -