\input texinfo
@c %**start of header
@setfilename wdiff.info
@documentencoding UTF-8
@include version.texi
@include flags.texi
@ifset EXPERIMENTAL
@settitle A word difference finder (and others)
@end ifset
@ifclear EXPERIMENTAL
@settitle A word difference finder
@end ifclear
@finalout
@c %**end of header

@dircategory Text creation and manipulation
@direntry
* Word differences: (wdiff).    GNU wdiff and diff related tools.
@end direntry

@dircategory Individual utilities
@direntry
* wdiff: (wdiff)wdiff invocation.               Word difference finder.
@ifset EXPERIMENTAL
* wdiff2: (wdiff)wdiff invocation.              Word difference finder.
* mdiff: (wdiff)mdiff invocation.               Line cluster finder.
* unify: (wdiff)unify invocation.               Diff format converter.
@end ifset
@end direntry

@copying
This file documents the @command{wdiff} command, which compares two files,
finding which words have been deleted or added to the first for getting
the second.
@ifset EXPERIMENTAL
It also documents some other @command{diff} related tools.
@end ifset

Copyright @copyright{} 1992--2026 Free Software Foundation, Inc.

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).

@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Foundation.
@end copying

@titlepage
@title GNU wdiff, version @value{VERSION}
@ifset EXPERIMENTAL
@subtitle A word difference finder (and others)
@end ifset
@ifclear EXPERIMENTAL
@subtitle A word difference finder
@end ifclear
@subtitle Edition @value{EDITION}, @value{UPDATED-MONTH}
@author Fran@,{c}ois Pinard
@author Martin von Gagern

@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage

@ifnottex
@comment =============================================================
@node Top
@top GNU wdiff
@comment =============================================================

@ifset EXPERIMENTAL
These Info pages document @command{wdiff}, a word difference finder, together
with some other @command{diff} related tools.
Note that some tools documented here are considered experimental and may
not be part of every @command{wdiff} installation.
@end ifset
@ifclear EXPERIMENTAL
These Info pages document @command{wdiff}, a word difference finder.
Experimental applications included in the same source package
haven't been enabled for your system, so their
documentation will be omitted as well.
@end ifclear
@xref{Experimental}.

This is for release @value{VERSION}.

@menu
* Overview::                    Overview
* wdiff::                       The word difference finder @c
@ifset EXPERIMENTAL
* mdiff::                       The line cluster finder
* unify::                       The diff format converter
* Compatibility::               How @command{mdiff} differs
* Experimental::                About experimental programs
@end ifset
@ifclear EXPERIMENTAL
* Experimental::                About experimental programs
@end ifclear

@detailmenu

--- The Detailed Node Listing ---

The word difference finder

* wdiff invocation::            Invoking @command{wdiff}
* wdiff Examples::              Actual examples of @command{wdiff} usage
@ifset EXPERIMENTAL
The multi-difference finder

* mdiff invocation::            Invoking @command{mdiff}
* Efficiency::                  Resource considerations and efficiency

The diff format converter

* unify invocation::            Invoking @command{unify}

How @command{mdiff} differs

* diff Compatibility::          Differences with @command{diff}
* wdiff Compatibility::         Differences with @command{wdiff}

Experimental programs

* Experimental History::        History of the experimental programs

@end ifset
@end detailmenu
@end menu

@end ifnottex

@contents

@comment =============================================================
@node Overview
@chapter Overview
@comment =============================================================

@command{wdiff} is a front end to @command{diff} for comparing files on
a word per word basis. It works by creating two temporary files, one
word per line, and then executes @command{diff} on these files. It collects the
@command{diff} output and uses it to produce a nicer display of word differences
between the original files.

@ifset EXPERIMENTAL

@command{mdiff} studies one or more input files altogether, and discovers
blocks of items which repeat at more than one place.  Items may be lines,
words, or units defined by user.  When in word mode, @command{mdiff} compares
two files, finding which words have been deleted or added to the first
in order to create the second, which is useful when two texts differ
only by a few words and paragraphs have been refilled.  The program has
many output formats and interacts well with terminals and pagers (notably
with @command{less}).

@command{unify} is able to convert context diffs to unidiff format, or the
other way around.  Some people just prefer one format and despise the
other, it is a religious issue.  This program brings peace back to Earth.

@command{wdiff2} is intended as a replacement to @command{wdiff}.
It aims at supporting the same set of options, but uses @command{mdiff}
instead of @command{diff} as its backend.

@command{wdiff}, @command{mdiff} and @command{wdiff2}
were written by Fran@,{c}ois Pinard, while
@command{unify} has been contributed by Wayne Davison.
@end ifset
@ifclear EXPERIMENTAL
@command{wdiff} was written by Fran@,{c}ois Pinard.
@end ifclear
Please report bugs to @email{wdiff-bugs@@gnu.org}.
Include the version number, which
you can find by running the program with @option{--version}.  Please include
in your message sufficient input to reproduce what you got, the output you
indeed expected, and careful explanations about the nature of the problem.

@comment =============================================================
@node wdiff
@chapter The word difference finder
@comment =============================================================

@ifset EXPERIMENTAL
There are actually two programs for comparing files on a word per word
basis.
@command{wdiff} is a front-end to @command{diff} as found in the
GNU diffutils package. It is quite mature.
Its planned successor, @command{wdiff2}, is a front end to @command{mdiff},
and as experimental as @command{mdiff} itself.
@xref{Experimental}.
@end ifset

@ifclear EXPERIMENTAL
@command{wdiff} is a programs for comparing files on a word per word
basis.
It is a front-end to @command{diff} as found in the GNU diffutils package.
@end ifclear
A word is anything between whitespace.  This is useful for comparing two
texts in which a few words have been changed and for which paragraphs
have been refilled.

@menu
* wdiff invocation::            Invoking @command{wdiff}
* wdiff Examples::              Actual examples of @command{wdiff} usage
@end menu

@comment -------------------------------------------------------------
@node wdiff invocation
@section Invoking @command{wdiff}

@ifset EXPERIMENTAL
The programs @command{wdiff} and @command{wdiff2} aim at providing the
same set of command line options. They are described below.
@xref{wdiff Compatibility}, for a list of differences.
@end ifset
@ifclear EXPERIMENTAL
The format for running the @command{wdiff} program is:
@end ifclear

@example
wdiff @var{option} @dots{} @var{old_file} @var{new_file}
wdiff @var{option} @dots{} -d [@var{diff_file}]
@end example

@command{wdiff} compares files @var{old_file} and @var{new_file} and
produces an annotated copy of @var{new_file} on standard output.  The
empty string or the string @samp{-} denotes standard input, but standard
input cannot be used twice in the same invocation.  The complete path of
a file should be given, a directory name is not accepted.  @command{wdiff}
will exit with a status of 0 if no differences were found, a status of 1
if any differences were found, or a status of 2 for any error.

In this documentation, @dfn{deleted text} refers to text in
@var{old_file} which is not in @var{new_file}, while @dfn{inserted text}
refers to text on @var{new_file} which is not in @var{old_file}.

@command{wdiff} supports the following command line options:

@table @option
@item --help
@itemx -h
Print an informative help message describing the options.

@item --version
@itemx -v
Print the version number of @command{wdiff} on the standard error output.

@item --no-deleted
@itemx -1
Avoid producing deleted words on the output.  If neither @option{-1} or
@option{-2} is selected, the original right margin may be exceeded for
some lines.

@item --no-inserted
@itemx -2
Avoid producing inserted words on the output.  When this flag is given,
the whitespace in the output is taken from @var{old_file} instead of
@var{new_file}.  If neither @option{-1} or @option{-2} is selected, the
original right margin may be exceeded for some lines.

@item --no-common
@itemx -3
Avoid producing common words on the output.  When this option is not
selected, common words and whitespace are taken from @var{new_file},
unless option @option{-2} is given, in which case common words and
whitespace are rather taken from @var{old_file}.  When selected,
differences are separated from one another by lines of dashes.
Moreover, if this option is selected at the same time as @option{-1} or
@option{-2}, then none of the output will have any emphasis, i.e. no bold
or underlining.  Finally, if this option is not selected, but both
@option{-1} and @option{-2} are, then sections of common words between
differences are segregated by lines of dashes.

@item --ignore-case
@itemx -i
Do not consider case difference while comparing words.  Each lower case
letter is seen as identical to its upper case equivalent for the purpose
of deciding if two words are the same.

@item --statistics
@itemx -s
On completion, for each file, the total number of words, the number of
common words between the files, the number of words deleted or inserted
and the number of words that have changed is output.  (A changed word is
one that has been replaced or is part of a replacement.)  Except for the
total number of words, all of the numbers are followed by a percentage
relative to the total number of words in the file.

@item --auto-pager
@itemx -a
Some initiatives which were previously automatically taken in previous
versions of @command{wdiff} are now put under the control of this option.
By using it, a pager is interposed whenever the @command{wdiff} output is
directed to the user's terminal.  Without this option, no pager will be
called, the user is then responsible for explicitly piping @command{wdiff}
output into a pager, if required.

The pager is selected by the value of the @var{PAGER} environment
variable when @command{wdiff} is run.  If @var{PAGER} is not defined at
run time, then a default pager, selected at installation time, will be
used instead.  A defined but empty value of @var{PAGER} means no pager
at all.

When a pager is interposed through the use of this option,
one of the options @option{-l} or @option{-t} is also selected, depending on
whether the string @samp{less} appears in the pager's name or not.

It is often useful to define @samp{wdiff} as an alias for @samp{wdiff
-a}.  However, this @emph{hides} the normal @command{wdiff} behaviour.  The
default behaviour may be restored simply by piping the output from
@command{wdiff} through @command{cat}.  This dissociates the output from the
user's terminal.

@item --printer
@itemx -p
Use over-striking to emphasize parts of the output.  Each character of the
deleted text is underlined by writing an underscore @samp{_} first,
then a backspace and then the letter to be underlined.  Each character of the
inserted text is emboldened by writing it twice, with a backspace in
between.  This option is not selected by default.

@item --less-mode
@itemx -l
Use over-striking to emphasize parts of output.  This option works as
option @option{-p}, but also over-strikes whitespace associated with
inserted text.  @command{less} shows such whitespace using reverse video.
This option is not selected by default.  However, it is automatically
turned on whenever @command{wdiff} launches the pager @command{less}.  See
option @option{-a}.

This option is commonly used in conjunction with @command{less}:

@example
wdiff -l @var{old_file} @var{new_file} | less
@end example

@item --terminal
@itemx -t
Force the production of @code{termcap} strings for emphasising parts of
output, even if the standard output is not associated with a terminal.
The @env{TERM} environment variable must contain the name of a valid
@code{termcap} entry.  If the terminal description permits, underlining
is used for marking deleted text, while bold or reverse video is used
for marking inserted text.  This option is not selected by default.
However, it is automatically turned on whenever @command{wdiff} launches a
pager, and it is known that the pager is @emph{not} @command{less}.  See
option @option{-a}.

This option is commonly used when @command{wdiff} output is not redirected,
but sent directly to the user terminal, as in:

@example
wdiff -t @var{old_file} @var{new_file}
@end example

A common kludge uses @command{wdiff} together with the pager @command{more},
as in:

@example
wdiff -t @var{old_file} @var{new_file} | more
@end example

However, some versions of @command{more} use @code{termcap} emphasis for
their own purposes, so strange interactions are possible.

@item --start-delete @var{argument}
@itemx -w @var{argument}
Use @var{argument} as the @dfn{start delete} string.  This string will
be output prior to any sequence of deleted text, to mark where it
starts.  By default, no start delete string is used unless there is no
other means of distinguishing where such text starts; in this case the
default start delete string is @samp{[-}.

@item --end-delete @var{argument}
@itemx -x @var{argument}
Use @var{argument} as the @dfn{end delete} string.  This string will be
output after any sequence of deleted text, to mark where it ends.  By
default, no end delete string is used unless there is no other means of
distinguishing where such text ends; in this case the default end delete
string is @option{-]}.

@item --start-insert @var{argument}
@itemx -y @var{argument}
Use @var{argument} as the @dfn{start insert} string.  This string will
be output prior to any sequence of inserted text, to mark where it
starts.  By default, no start insert string is used unless there is no
other means of distinguishing where such text starts; in this case the
default start insert string is @samp{@{+}.

@item --end-insert @var{argument}
@itemx -z @var{argument}
Use @var{argument} as the @dfn{end insert} string.  This string will be
output after any sequence of inserted text, to mark where it ends.  By
default, no end insert string is used unless there is no other means of
distinguishing where such text ends; in this case the default end insert
string is @samp{+@}}.

@item --avoid-wraps
@itemx -n
Avoid spanning the end of line while showing deleted or inserted text.
Any single fragment of deleted or inserted text spanning many lines will
be considered as being made up of many smaller fragments not containing
a newline.  So deleted text, for example, will have an end delete string
at the end of each line, just before the new line, and a start delete
string at the beginning of the next line.  A long paragraph of inserted
text will have each line bracketed between start insert and end insert
strings.  This behaviour is not selected by default.

@item --diff-input
@itemx -d
Use single unified diff as input. If no input file is specified,
standard input is used instead. This can be used to post-process diffs
generated form other applications, like version control systems:

@example
svn diff | wdiff -d
@end example
@end table

Note that options @option{-p}, @option{-t}, and @option{-[wxyz]} are not
mutually exclusive.  If you use a combination of them, you will merely
accumulate the effect of each.  Option @option{-l} is a variant of option
@option{-p}.

@comment -------------------------------------------------------------
@node wdiff Examples
@section Actual examples of @command{wdiff} usage

This section presents a few examples of usage, most of them have been
contributed by @command{wdiff} users.

@itemize @bullet
@item Change bars example.

@itemize @bullet

@item
This example comes from a discussion with
@email{jbw@@cs.bu.edu, Joe Wells}.

The following command produces a copy of @var{new_file}, shifted right
one space to accommodate change bars since the last revision, ignoring
those changes coming only from paragraph refilling.  Any line with new
or changed text will get a @samp{|} in column 1.  However, deleted text
is not shown nor marked.

@example
wdiff -1n @var{old_file} @var{new_file} |
  sed -e 's/^/  /;/@{+/s/^ /|/;s/@{+//g;s/+@}//g'
@end example

Here is how it works.  Word differences are found, paying attention only
to additions, as requested by option @option{-1}.  For bigger changes
which span line boundaries, the insert bracket strings are repeated on
each output line, as requested by option @option{-n}.  This output is then
reformatted with a @command{sed} script which shifts the text right two
columns, turns the initial space into a bar only if there is some new
text on that line, then removes all insert bracket strings.

@end itemize

@item La@TeX{} example.

@itemize @bullet
@item

This example has been provided by
@email{fisk@@polar.bowdoin.edu, Steve Fisk}.

The following uses La@TeX{} to put deleted text in boxes, and new text
in double boxes:

@example
wdiff -w "\fbox@{" -x "@}" -y "\fbox@{\fbox@{" -z "@}@}" @dots{}
@end example

@noindent
works nicely.

@end itemize

@item @command{troff} example.

@itemize @bullet

@item
This example comes from @email{pgf@@cayman.com, Paul Fox}.

Using @command{wdiff}, with some @command{troff}-specific delimiters gives
@emph{much} better output.  The delimiters I used:

@example
wdiff -w'\s-5' -x'\s0' -y'\fB' -z'\fP' @dots{}
@end example

This makes the pointsize of deletions 5 points smaller than normal, and
emboldens insertions.  Fantastic!

I experimented with:

@example
wdiff -w'\fI' -x'\fP' -y'\fB' -z'\fP'
@end example

since that's more like the defaults you use for terminals or printers,
but since I actually use italics for emphasis in my documents, I thought
the point size thing was clearer.

I tried it on code, and it works surprisingly well there, too...

@item
@email{leisner@@eso.mc.xerox.com, Marty Leisner} says:

In the previous example, you had smaller text being taken out and bold
face inserted.  I had smaller text being taken out and larger text being
inserted, I'm using bold face for other things, so this is more clear.

@example
wdiff -w '\s-3' -x'\s0' -y'\s+3' -z'\s0'
@end example

@end itemize

@item Colored output example.

@itemize @bullet

@item
This example comes from @email{Martin.vGagern@@gmx.net, Martin von Gagern}.

If you like colored output, and your terminal supports ANSI escape
sequences, you can use this invocation:

@example
wdiff -n \
  -w $'\033[30;41m' -x $'\033[0m' \
  -y $'\033[30;42m' -z $'\033[0m' \
  @dots{} | less -R
@end example

This will print deleted text black on red, and inserted text black on
green, assuming that your normal terminal colors are white on black.
Of course you can choose different colors if you prefer.

The @samp{$'@dots{}'} notation is supported by GNU bash, and maybe other
shells as well. If your shell doesn't support it, you might need some
more tricks to generate these escape sequences as command line
arguments.

@end itemize

@end itemize

On a related note, GNU Emacs users might notice that the interactive
function @code{compare-windows} ignores changes in whitespace, if it is
given a numeric argument.  If the variable @code{compare-ignore-case}
is non-@code{nil}, it ignores differences in case as well.  So, in a way,
this offers a kind of incremental version of @command{wdiff}.

@ifset EXPERIMENTAL

@comment =============================================================
@node mdiff
@chapter The multi-difference finder
@comment =============================================================

The name @command{mdiff} stands for @emph{multi-}@command{diff}, and has the
purpose of encompassing the functionality of a few other @command{diff}-type
programs.  The prefix @emph{multi-} also stands for the fact the program
is often able to study more than two input files at once.

The theory of operation is simple.  The program splits all input files
into a sequence of items, which may be lines or words.  @command{mdiff} is
then said to operate either in @dfn{line mode} or in @dfn{word mode}.
It then tries to find sequences of items which are repeated in the
input files.  Such common sequences are called @dfn{clusters} of items,
and each occurrence of a repetition is called a cluster @dfn{member}.
What remains, once all cluster members are conceptually removed from all
input files, is a set of @dfn{differences}.  The role of @command{mdiff}
is to conveniently list either cluster members and differences.

When input files are very similar, it is likely that clusters will
encompass many items (lines or words) and differences will be small.  So,
most listing options inhibit the printing of cluster members.  However,
one may ask for the few beginning or ending items of cluster members
to be printed nevertheless, as a way to provide a kind of feedback
or @dfn{context} of the difference, those context items are sometimes
said to be at the @dfn{horizon} of the difference.  In merged listings,
cluster members may just not be printed, except maybe for a few context
items at the beginning of the member (just after a difference), and a
few context items at the end of the member (just before a difference).

When cluster members are short, or if you prefer, when the differences
are not far away from each other, it is quite possible that the required
context items often cover the full extent of the cluster members, which
then are not inhibited anymore when this happens.  A run of differences
intermixed with such non-suppressed members is called a @dfn{hunk}.
Some reports produced by @command{mdiff} are showned as a list of hunks,
and it is to be understood that common items are elided between hunks.
However, each hunk in itself has no item missing, and each item of the
hunk is analysed as pertaining either to only one of the input file or
to many of them.  Each hunk is preceded by a header, which explains the
line position of all input files prior to the hunk itself.  By comparing
a hunk header with the previous hunk header, the user can have a hint
about how much printing was spared.

When two input files are quite similar, clusters are usually presented in
the same order in all files.  If a cluster member @var{A} in the first
file corresponds to a cluster member @var{A} in the second file, it is
likely that another cluster member @var{B} which appears @emph{after}
@var{A} in the first file will correspond to a cluster member @var{B}
in the second file which appears @emph{after} @var{A} as well.  So, in
many cases, while producing merged listing of files, cluster members may
be made to naturally correspond to one another.  However, this is not
always true, in particular when the second file has been produced from
the first by moving a big chunk of code away from its original position.
In such cases, we say that members have @dfn{crossed}.  When members are
crossed and @command{mdiff} has to make a merged listing, it selects one
cluster member as being @emph{naturally} associated with its correspondent
(either the pair of @var{A}'s or the pair of @var{B}'s) and then consider
the other cluster as being part of a difference.  The crossed nature of
the member may still be analysed and reported, or it may be ignored.

The standard @command{diff} program is meant for when there are exactly two
input files, for which crossed members should be ignored.  @command{mdiff}
output format has been designed in such a way that it should resemble
@command{diff} output for this precise case.  However, @command{diff} formats are
not sufficient for representing all cases which @command{mdiff} may address,
and this is not mature yet.  That is why @command{mdiff}, in its current
state, still experiments with output formats, which are subject to change.

When the input files are not very similar, or rather different, merged
listings are not very significant nor useful, and may even be rather
confusing.  The best to do in such cases is using @command{mdiff} for making
an annotated relisting of all input files, in which cluster members are
properly identified and referred to one another.

Statistics.

@example
Read summary: 137 files, 41975 lines
Work summary: 439 clusters, 1608 members, 8837 duplicate lines
@end example

@noindent
The summary lines, triggered by the @option{-s} option, say that about 8837
non-ignorable lines could be removed over the 41975 which has been read,
by using functions, @code{#include}, @code{#define}, or similar devices.

If one manages to execute @command{mdiff} within GNU Emacs so the output
described above is collected into the @code{*compilation*} buffer, the
command @kbd{C-`} (@samp{@w{M-x next-error}}) will proceed to the next
cluster member in the other window, and similarly for other compilation
mode commands.  This is a useful way for handling @command{mdiff} output.

Each line in the hunk, after the header, comes from the compared files,
but is shifted right so the first column (or the first few columns)
of each line gives information about where the line is coming from.
A space indicates a line which is common to all files.  In case there
are only two input files, a minus sign indicates a line from the first
file and a plus sign a line from the second file.  Else, a letter from
@samp{a} to @samp{z}, or more than one letter if there are more than
26 files, indicates to which file the line pertains.  If a line or a
block of line pertains to many files but not to all of them, the first
column holds a vertical bar, and the line or block of lines is bracketed
between @samp{@@/} and @samp{@@\} lines, which are kind of comments within
the hunk.  The initial bracket lists all file letters that are related
to the incoming line.

I initially wrote @command{mdiff} specifically to help cleaning a C++
project which was a bit large, and in which many big monolithic classes
were derived from each other most probably by rough copying followed by
local modifications.  I intended to fragment most common clusters and
segregate the parts into virtual methods in outer classes, and override
these methods, as appropriate, with less common variants within inner
classes.  @command{mdiff} was good at pointing me to exactly where I should
look at.  Of course, it never did the cleanup for me, but it helped doing
the research about what should be done.  Reusing @command{mdiff} over the
half-cleaned project gave me more fine grained analysis of what was left
to consider.

@menu
* mdiff invocation::            Invoking @command{mdiff}
* Efficiency::                  Resource considerations and efficiency
@end menu

@comment -------------------------------------------------------------
@node mdiff invocation
@section Invoking @command{mdiff}

The format for running the @command{mdiff} program is:

@example
mdiff @var{option} @dots{} @var{file} @dots{}
@end example

@command{mdiff} read all input @var{file}s and produces its results on
standard output.  Optionally, standard error might receive a progress
report or a few statistics.

@command{wdiff} compares files @var{old_file} and @var{new_file} and
produces an annotated copy of @var{new_file} on standard output.  The
empty string or the string @option{-} denotes standard input, but standard
input cannot be used twice in the same invocation.  The complete path of
a file should be given, a directory name is not accepted.  @command{wdiff}
will exit with a status of 0 if no differences were found, a status of 1
if any differences were found, or a status of 2 for any error.

In this documentation, @dfn{deleted text} refers to text in
@var{old_file} which is not in @var{new_file}, while @dfn{inserted text}
refers to text on @var{new_file} which is not in @var{old_file}.

@command{mdiff} supports the following command line options:

@table @option
@item --version
Merely prints the version numbers on standard output, and exits without
doing anything else.

@item --help
Merely prints a page of help on standard output, and exits without doing
anything else.

@item --no-deleted
@itemx -1
Avoid producing deleted words on the output.  If neither @option{-1} or
@option{-2} is selected, the original right margin may be exceeded for
some lines.

@item --no-inserted
@itemx -2
Avoid producing inserted words on the output.  When this flag is given,
the whitespace in the output is taken from @var{old_file} instead of
@var{new_file}.  If neither @option{-1} or @option{-2} is selected, the
original right margin may be exceeded for some lines.

@item --no-common
@itemx -3
Avoid producing common words on the output.  When this option is not
selected, common words and whitespace are taken from @var{new_file},
unless option @option{-2} is given, in which case common words and
whitespace are rather taken from @var{old_file}.  When selected,
differences are separated from one another by lines of dashes.
Moreover, if this option is selected at the same time as @option{-1} or
@option{-2}, then none of the output will have any emphasis, i.e. no bold
or underlining.  Finally, if this option is not selected, but both
@option{-1} and @option{-2} are, then sections of common words between
differences are segregated by lines of dashes.

@item --ignore-case
@itemx -i
Do not consider case difference while comparing words.  Each lower case
letter is seen as identical to its upper case equivalent for the purpose
of deciding if two words are the same.

@item --auto-pager
@itemx -A
Some initiatives which were previously automatically taken in previous
versions of @command{wdiff} are now put under the control of this option.
By using it, a pager is interposed whenever the @command{wdiff} output is
directed to the user's terminal.  Without this option, no pager will be
called, the user is then responsible for explicitly piping @command{wdiff}
output into a pager, if required.

The pager is selected by the value of the @var{PAGER} environment
variable when @command{wdiff} is run.  If @var{PAGER} is not defined at
run time, then a default pager, selected at installation time, will be
used instead.  A defined but empty value of @var{PAGER} means no pager
at all.

When a pager is interposed through the use of this option,
one of the options @option{-l} or @option{-t} is also selected, depending on
whether the string @samp{less} appears in the pager's name or not.

It is often useful to define @samp{wdiff} as an alias for @samp{wdiff
-a}.  However, this @emph{hides} the normal @command{wdiff} behaviour.  The
default behaviour may be restored simply by piping the output from
@command{wdiff} through @command{cat}.  This dissociates the output from the
user's terminal.

@item --printer
@itemx -p
Use over-striking to emphasize parts of the output.  Each character of the
deleted text is underlined by writing an underscore @samp{_} first,
then a backspace and then the letter to be underlined.  Each character of the
inserted text is emboldened by writing it twice, with a backspace in
between.  This option is not selected by default.

@item --less-mode
@itemx -l
Use over-striking to emphasize parts of output.  This option works as
option @option{-p}, but also over-strikes whitespace associated with
inserted text.  @command{less} shows such whitespace using reverse video.
This option is not selected by default.  However, it is automatically
turned on whenever @command{wdiff} launches the pager @command{less}.  See
option @option{-a}.

This option is commonly used in conjunction with @command{less}:

@example
wdiff -l @var{old_file} @var{new_file} | less
@end example

@item --terminal
@itemx -t
Force the production of @code{termcap} strings for emphasising parts of
output, even if the standard output is not associated with a terminal.
The @samp{TERM} environment variable must contain the name of a valid
@code{termcap} entry.  If the terminal description permits, underlining
is used for marking deleted text, while bold or reverse video is used
for marking inserted text.  This option is not selected by default.
However, it is automatically turned on whenever @command{wdiff} launches a
pager, and it is known that the pager is @emph{not} @command{less}.  See
option @option{-a}.

This option is commonly used when @command{wdiff} output is not redirected,
but sent directly to the user terminal, as in:

@example
wdiff -t @var{old_file} @var{new_file}
@end example

A common kludge uses @command{wdiff} together with the pager @command{more},
as in:

@example
wdiff -t @var{old_file} @var{new_file} | more
@end example

However, some versions of @command{more} use @code{termcap} emphasis for
their own purposes, so strange interactions are possible.

@item --start-delete @var{argument}
@itemx -w @var{argument}
Use @var{argument} as the @dfn{start delete} string.  This string will
be output prior to any sequence of deleted text, to mark where it
starts.  By default, no start delete string is used unless there is no
other means of distinguishing where such text starts; in this case the
default start delete string is @samp{[-}.

@item --end-delete @var{argument}
@itemx -x @var{argument}
Use @var{argument} as the @dfn{end delete} string.  This string will be
output after any sequence of deleted text, to mark where it ends.  By
default, no end delete string is used unless there is no other means of
distinguishing where such text ends; in this case the default end delete
string is @option{-]}.

@item --start-insert @var{argument}
@itemx -y @var{argument}
Use @var{argument} as the @dfn{start insert} string.  This string will
be output prior to any sequence of inserted text, to mark where it
starts.  By default, no start insert string is used unless there is no
other means of distinguishing where such text starts; in this case the
default start insert string is @samp{@{+}.

@item --end-insert @var{argument}
@itemx -z @var{argument}
Use @var{argument} as the @dfn{end insert} string.  This string will be
output after any sequence of inserted text, to mark where it ends.  By
default, no end insert string is used unless there is no other means of
distinguishing where such text ends; in this case the default end insert
string is @samp{+@}}.

@item --avoid-wraps
@itemx -n
Avoid spanning the end of line while showing deleted or inserted text.
Any single fragment of deleted or inserted text spanning many lines will
be considered as being made up of many smaller fragments not containing
a newline.  So deleted text, for example, will have an end delete string
at the end of each line, just before the new line, and a start delete
string at the beginning of the next line.  A long paragraph of inserted
text will have each line bracketed between start insert and end insert
strings.  This behaviour is not selected by default.

@end table

Some choices are hard-wired into the program, but might well become options
in later releases.  For example:

@itemize @bullet
@item
No cluster may span a file boundary, that is, start near the end of one
input file and continue at the beginning of the next file.

@item
A cluster may have many members from the same file.

@item
White space is ignored between the beginning of a line and the first
non-white character.

@item
White space is significant when embedded in a line, or when ending a line.

@item
Lines having no significant part (only white lines for now) are
@dfn{ignorable}.  Such ignorable lines are logically considered as not
being part of the input files for the sake of comparisons.

@item
Comments from the C language are not especially ignored.  Unless ignored
for other reasons (being white lines), they are indeed significant lines.

@item
No cluster member may ever directly start nor end with ignorable lines.
However, ignorable lines may still be embedded within a cluster member.

@item
In the generated output, clusters containing the biggest number of
ignorable lines are output first, while smaller clusters appear last.
All lines pertaining to a single cluster are output together.  Within a
cluster, members are listed in the order of the initial reading of
input files.

@end itemize

Note that options @option{-p}, @option{-t}, and @option{-[wxyz]} are not
mutually exclusive.  If you use a combination of them, you will merely
accumulate the effect of each.  Option @option{-l} is a variant of option
@option{-p}.

@comment -------------------------------------------------------------
@node Efficiency
@section Resource considerations and efficiency

@table @asis
@item Memory consumption

@command{mdiff} can easily handle medium-sized project.  For a 32 bits
architecture, the memory requirements may computed like this:

@itemize @bullet
@item
8 bytes per file
@item
8 bytes per line
@item
4 bytes per cluster
@item
8 bytes per cluster member
@end itemize

@item Time consumption

To evaluate the speed, consider the example shown above
(@pxref{mdiff}), and yielding these statistics:

@example
Read summary: 137 files, 41975 lines
Work summary: 439 clusters, 1608 members @dots{}
@end example

@noindent
Once many files in the memory cache, and redirecting the output to
@file{/dev/null}, the processing takes 3 seconds of real time on an
Intel 486/100, which looks good.  I was indeed afraid of some hidden
O(@var{n}^2) behaviour@footnote{@var{n} is the total number of lines.},
even if the program is mostly O(@var{n}*log(@var{n})).  Maybe one will
discover or construct cases putting @command{mdiff} on its knees.  So far,
@command{mdiff} seemingly behaves well for the little problems given to it.
If we devise and generate a more traditional @command{diff}-like output,
in which all input files are relisted, this will add some time to the
processing, but it will be only linear with regard with the total length
of input files.

There is a clever optimized sorting algorithm for @emph{all} substrings
of a file, which might be generalised to handle words or lines for
@command{mdiff}.  But since the program is already faster than we initially
expected, there is no emergency to resort to using such an algorithm.

@item Trading complexity for clarity

When lines repeat a lot, there are surprisingly many ways to relate blocks
of lines, and reporting them @emph{all} can make very hairy listings.
Any choice about reporting similarities, or not, is somewhat arbitrary,
but we ought to make some of such choices for the program to be practical.
Some of these choices are detailed here.

If all members of a given cluster @var{A} are proper subsets of all
members of another given cluster @var{B}, then cluster @var{A} is wholly
forgotten.  However, let's presume for example that there are more members
in @var{A} than in @var{B}.  Then, some members of @var{A} necessarily
appear unrelated to any member of @var{B}.  In such case, it has been
decided more useful to report @emph{all} occurrences of @var{A} members,
even those embedded within occurrences of @var{B} members.  When only
interested in members @var{B}, annotations pertaining to @var{A} may be
perceived as clutter.  However, when interested in members of @var{A},
getting all of them is probably the most useful choice.

It sometimes happen that members of a very same cluster overlap.  In the
string @samp{@w{a a a}}, there are two overlapping members for the cluster
represented by the string @samp{@w{a a}}, one from the first two @samp{a},
another from the last two @samp{a}.  In such cases, one member of such
an overlap is automatically chopped so the overlap does not occur.

White lines and items containing only delimiters are the possible source of
a lot of complexity, if these are fully taken as significant.  Since this
does not add much to clarity, they are better ignored, usually, through
using @option{--ignore-blank-lines} (@option{-B}) or @option{--ignore-delimiters}
(@option{-j}).  Increasing the value of @option{--minimum-size=@var{items}}
(@samp{@w{-J @var{items}}}) option also cut off complexity in favor of
clarity, yet some small matches may then go unnoticed.  Exactly how to
best adjust the @var{items} value is left for the user to decide.

@end table

@comment =============================================================
@node unify
@chapter The diff format converter
@comment =============================================================

The program @command{unify} has the purpose of manipulating context diffs
and unified context diffs.  @command{unify} will accept either a regular
context diff (old- or new-style) or a unified context diff as input,
and generate either a unified diff or a new-style context diff as output.

Various other options allow you to echo the non-diff (comment) lines to
stderr, modify the diff by removing the comment lines, and/or tweak the
diff into a format that is good for releasing patches.

I think most people prefer unified context diffs in general.  But some
of us just have trouble reading unidiffs, unless they get very simple.
Usual context diffs show how the code was @emph{before}, and then, how
the code is @emph{after}.  Some people just prefer understanding twice
thoroughly, than once fuzzily.  The tool is useful for those who handle
a lot of diffs from various sources, and want them in a uniform format.

@menu
* unify invocation::            Invoking @command{unify}
@end menu

@comment -------------------------------------------------------------
@node unify invocation
@section Invoking @command{unify}

The format for running the @command{unify} program is:

@example
unify @var{option} @dots{} [@var{file}]
@end example

The program reads the diff to convert from @var{file}, or if the
source file is not mentioned, it will be read from the standard input.
The default is to output the diff in the opposite style of whatever was
input, that is, regular context diffs will become unified context diffs,
and unified context diffs will become unified context diffs, but this
can be overridden by options.

@command{unify} supports the following command line options:

@table @option
@item --version
Merely prints the version numbers on standard output, and exits without
doing anything else.

@item --help
Merely prints a page of help on standard output, and exits without doing
anything else.

@item --context-diffs
@itemx -c
Forces context diff output.

@item --echo-comments
@itemx -e
Echoes non-diff (comment) lines to stderr.  If a comment line is
being stripped via the @option{-p} option, it is echoed with a preceding
@samp{!!! }.  If all comments are being stripped (via the @option{-s}
option), no special designation is given.

@item --old-diffs
@itemx -o
Is used to force a context diff to be interpreted as being of the
old-style even if it has the extra trailing asterisks that normally mark
the new-style.  This is only needed if @command{unify} fails to work with
your version of @command{diff}.

@item --patch-format
@itemx -p
Turns on patch-output mode.  This will do two things:

@enumerate
@item
Transform a header like:

@example
*** orig/file	Sat May  5 02:59:37 1990
--- ./file	Sat May  5 03:00:08 1990
@end example

@noindent
into a line of @samp{Index: file} --- we choose the shorter name and strip
a leading @samp{./} sequence if present.

@item
Strip lines that begin with @samp{@w{Only in }}, @samp{@w{Common subdir}},
@samp{@w{Binary files}} or @samp{@w{diff -}}.

@end enumerate

@item -P
Is the same as @option{-p}.

@item --strip-comments
@itemx -s
Strips non-diff lines (comments).

@item --unidiffs
@itemx -u
Forces unified diff output.

@item -U
Is the same as @option{-up}.

@item --use-equals
@itemx -=
Will use a @samp{=} prefix in a unified diff for lines that are common
to both files instead of using a leading space.  Though this is harder to
read, it is less likely to be mangled by trailing-space-stripping sites
when posted to Usenet.

@end table

@comment =============================================================
@node Compatibility
@chapter How @command{mdiff} differs
@comment =============================================================

The GNU project already has a @command{diff} program which is part of the
GNU diffutils package.  There also are various non-GNU @command{diff}
programs provided by various constructors.

There is also the well-established @command{wdiff} which uses
@command{diff} under the hood. It differs slightly from
@command{wdiff2}, its intended @command{mdiff}-based successor.

The following sections compare @command{mdiff} specifications with both GNU
@command{diff} and with @command{wdiff}.

@menu
* diff Compatibility::          Differences with @command{diff}
* wdiff Compatibility::         Differences with @command{wdiff}
@end menu

@comment -------------------------------------------------------------
@node diff Compatibility
@section Differences with @command{diff}

GNU @command{diff} is a program which matured for a long while, and for which
algorithms are based on computer science literature.  It is a fast program.
By comparison, @command{mdiff} is not more than a program kludged up rapidly
to satisfy a few precise needs.  It only tries not being inordinately slow.

Most @command{diff} options are accepted by @command{mdiff} under the same
short and long option names, and is able to produce resembling output,
for making @command{mdiff} easier to learn and less surprising to users.
Yet, some differences exist in option decoding and output format.  Since
@command{diff} and @command{mdiff} use different matching algorithms, it is
very likely that the differences will not be exactly analyzed identically.

@itemize @bullet
@item
A few @command{diff} options, which either accept no argument or require
a mandatory one, are implemented in @command{mdiff} as options accepting
an optional argument.  This may yield some surprises, for example,
@option{-c4bir} would be accepted by @command{diff} and rejected by
@command{mdiff}, yet it may rewritten @option{-birc4} for both.  See below.

@item
Options @option{-c} and @option{-u} in @command{diff} ask for regular context
and unified context output, respectively, without specifying the number
of lines in the context.  @command{diff} has @samp{@w{-C @var{number}}} and
@samp{@w{-U @var{number}}} options for asking for regular or unified context
diffs with @var{number} context lines.  If @option{-c4} asks for four lines
of context, the @samp{4} is not really an argument of @option{-c}, and this
is really interpreted as @samp{@w{-c -4}}, where @option{-@var{number}} is
meant to be a deprecated option for choosing the number of context lines,
option which @command{mdiff} does not implement.  In @command{mdiff}, @option{-c}
and @option{-u} are really two options which are allowed to receive an
optional argument, so the number of lines may, or may not be given, at
the choice of the user.  In @command{mdiff}, options @option{-C} and @option{-U}
are completely equivalent to @option{-c} and @option{-u}, and are provided
only for the sake of compatibility.

@item
Option @option{-v} in @command{diff} means @option{--version}, while it
means @option{--verbose} in @command{mdiff}.  There is no short form for
@option{--version} in @command{mdiff}.

@end itemize

@comment -------------------------------------------------------------
@node wdiff Compatibility
@section Differences with @command{wdiff}

Even if @command{mdiff} is meant to fully support @command{wdiff}, options have
been shuffled around so @command{mdiff} could better merge both @command{diff}
and @command{wdiff} options in a common scheme.  @command{diff} habits were
almost always favored in this option reorganisation.

@command{wdiff2} is now a mere front-end to @command{mdiff} that only
rewrites the options.  The following notes apply.

@itemize @bullet
@item
Some options are just transmitted unchanged, these are @option{-1},
@option{-2}, @option{-3} and @option{-i}.

@item
Option @option{-c} also gets turned into @option{-i}, to be compatible with
@command{wdiff} versions up to @samp{0.4}.

@item
Simple option @option{-a} in @command{wdiff} becomes @option{-A} in @command{mdiff},
@option{-l} becomes @option{-k}, @option{-n} becomes @option{-m}, @option{-p} becomes
@option{-o}, @option{-s} becomes @option{-v} and @option{-t} becomes @option{-z}.

@item
Options introducing strings, which are @option{-w}, @option{-x}, @option{-y}
and @option{-z} in @command{wdiff}, respectively become @option{-Y}, @option{-Z},
@option{-Q} and @option{-R} in @command{mdiff}.

@item
Options @option{-C}, @option{-h} and @option{-v} are processed directly by
@command{wdiff} and are not transmitted to @command{mdiff}.

@item
Further, the @option{-C} option of @command{wdiff} has no equivalent in
@command{mdiff}.

@item
A new option @option{-q} inhibits the message which explains how @command{mdiff}
might have been directly called.

@item
The option @option{--diff-input} (@option{-d}) from @command{wdiff}
isn't supported by @command{wdiff2} (yet).

@end itemize

@comment end ifset EXPERIMENTAL
@end ifset

@comment =============================================================
@node Experimental
@chapter Experimental programs
@comment =============================================================

The GNU wdiff source package contains sources for a number of tools
besides @command{wdiff} itself.
These are considered experimental: they might work for you, but they
might just as well fail.
The following programs are considered experimental:

@itemize @bullet
@item @command{mdiff}
@item @command{wdiff2}
@item @command{unify}
@end itemize

Building these applications can be configured at build time by passing
@option{--with-experimental} to the @file{configure} script.

@ifset EXPERIMENTAL
@emph{For this build, they have been enabled.}
If you encounter a bug in an experimental program, the maintainers would
still like to learn about it, but there is a greater chance that they
decide not to fix such issues unless you provide a patch as well.
@end ifset
@ifclear EXPERIMENTAL
@emph{For this build, they have been disabled.}
Therefore their documentation has been omitted here as well.
You can find the full documentation for all parts of GNU wdiff on the
@uref{https://www.gnu.org/software/wdiff/, GNU wdiff homepage}.
If you feel you'd like to give them a try, you could compile this
package from source yourself.
@end ifclear

@ifset EXPERIMENTAL
@menu
* Experimental History::   History of the experimental programs
@end menu

@comment -------------------------------------------------------------
@node Experimental History
@section History of the Experimental programs

Many users
suggested features, which were in turn inviting for the integration of
@command{wdiff} into GNU diffutils.  Collaboration proved to be rather
difficult.  After a few years, the @command{wdiff} author finally gave in
and created @command{mdiff} as a way to break out of the situation and for
becoming able to proceed with users' suggestions.

Before @command{mdiff} and the new @command{wdiff2} based on it were
officially released, the original author resigned maintainership.
The new maintainers had little experience with the code, and therefore
decided to mark it experimental. That way, the code wouldn't be lost,
but it would be clear that it wasn't as testes as the good old
@code{wdiff} command.

@end ifset

@bye
