ediff: Merging and diff3

 
 7.9 Merging and diff3
 =====================
 
 Ediff supports three-way comparison via the functions ‘ediff-files3’ and
 ‘ediff-buffers3’.  The interface is the same as for two-way comparison.
 In three-way comparison and merging, Ediff reports if any two difference
 regions are identical.  For instance, if the current region in buffer A
 is the same as the region in buffer C, then the mode line of buffer A
 will display ‘[=diff(C)]’ and the mode line of buffer C will display
 ‘[=diff(A)]’.
 
    Merging is done according to the following algorithm.
 
    If a difference region in one of the buffers, say B, differs from the
 ancestor file while the region in the other buffer, A, doesn’t, then the
 merge buffer, C, gets B’s region.  Similarly when buffer A’s region
 differs from the ancestor and B’s doesn’t, A’s region is used.
 
    If both regions in buffers A and B differ from the ancestor file,
 Ediff chooses the region according to the value of the variable
 ‘ediff-default-variant’.  If its value is ‘default-A’ then A’s region is
 chosen.  If it is ‘default-B’ then B’s region is chosen.  If it is
 ‘combined’ then the region in buffer C will look like this:
 
      <<<<<<< variant A
      the difference region from buffer A
      >>>>>>> variant B
      the difference region from buffer B
      ####### Ancestor
      the difference region from the ancestor buffer, if available
      ======= end
 
    The above is the default template for the combined region.  The user
 can customize this template using the variable
 ‘ediff-combination-pattern’.
 
    The variable ‘ediff-combination-pattern’ specifies the template that
 determines how the combined merged region looks like.  The template is
 represented as a list of the form ‘(STRING1 Symbol1 STRING2 Symbol2
 STRING3 Symbol3 STRING4)’.  The symbols here must be atoms of the form
 ‘A’, ‘B’, or ‘Ancestor’.  They determine the order in which the
 corresponding difference regions (from buffers A, B, and the ancestor
 buffer) are displayed in the merged region of buffer C.  The strings in
 the template determine the text that separates the aforesaid regions.
 The default template is
 
      ("<<<<<<< variant A" A ">>>>>>> variant B" B
         "####### Ancestor" Ancestor "======= end")
 
 (this is one long line) and the corresponding combined region is shown
 above.  The order in which the regions are shown (and the separator
 strings) can be changed by changing the above template.  It is even
 possible to add or delete region specifiers in this template (although
 the only possibly useful such modification seems to be the deletion of
 the ancestor).
 
    In addition to the state of the difference, Ediff displays the state
 of the merge for each region.  If a difference came from buffer A by
 default (because both regions A and B were different from the ancestor
 and ‘ediff-default-variant’ was set to ‘default-A’) then ‘[=diff(A)
 default-A]’ is displayed in the mode line.  If the difference in buffer
 C came, say, from buffer B because the difference region in that buffer
 differs from the ancestor, but the region in buffer A does not (if
 merging with an ancestor) then ‘[=diff(B) prefer-B]’ is displayed.  The
 indicators default-A/B and prefer-A/B are inspired by Emerge and have
 the same meaning.
 
    Another indicator of the state of merge is ‘combined’.  It appears
 with any difference region in buffer C that was obtained by combining
 the difference regions in buffers A and B as explained above.
 
    In addition to the state of merge and state of difference indicators,
 while merging with an ancestor file or buffer, Ediff informs the user
 when the current difference region in the (normally invisible) ancestor
 buffer is empty via the _AncestorEmpty_ indicator.  This helps determine
 if the changes made to the original in variants A and B represent pure
 insertion or deletion of text: if the mode line shows _AncestorEmpty_
 and the corresponding region in buffers A or B is not empty, this means
 that new text was inserted.  If this indicator is not present and the
 difference regions in buffers A or B are non-empty, this means that text
 was modified.  Otherwise, the original text was deleted.
 
    Although the ancestor buffer is normally invisible, Ediff maintains
 difference regions there and advances the current difference region
 accordingly.  All highlighting of difference regions is provided in the
 ancestor buffer, except for the fine differences.  Therefore, if
 desired, the user can put the ancestor buffer in a separate frame and
 watch it there.  However, on a TTY, only one frame can be visible at any
 given time, and Ediff doesn’t support any single-frame window
 configuration where all buffers, including the ancestor buffer, would be
 visible.  However, the ancestor buffer can be displayed by typing ‘/’ to
 the control window.  (Type ‘C-l’ to hide it again.)
 
    Note that the state-of-difference indicators ‘=diff(A)’ and
 ‘=diff(B)’ above are not redundant, even in the presence of a
 state-of-merge indicator.  In fact, the two serve different purposes.
 
    For instance, if the mode line displays ‘=diff(B) prefer(B)’ and you
 copy a difference region from buffer A to buffer C then ‘=diff(B)’ will
 change to ‘diff-A’ and the mode line will display ‘=diff(A) prefer-B’.
 This indicates that the difference region in buffer C is identical to
 that in buffer A, but originally buffer C’s region came from buffer B.
 This is useful to know because you can recover the original difference
 region in buffer C by typing ‘r’.
 
    Ediff never changes the state-of-merge indicator, except in response
 to the ‘!’ command (see below), in which case the indicator is lost.  On
 the other hand, the state-of-difference indicator is changed
 automatically by the copying/recovery commands, ‘a’, ‘b’, ‘r’, ‘+’.
 
    The ‘!’ command loses the information about origins of the regions in
 the merge buffer (default-A, prefer-B, or combined).  This is because
 recomputing differences in this case means running ‘diff3’ on buffers A,
 B, and the merge buffer, not on the ancestor buffer.  (It makes no sense
 to recompute differences using the ancestor file, since in the merging
 mode Ediff assumes that you have not edited buffers A and B, but that
 you may have edited buffer C, and these changes are to be preserved.)
 Since some difference regions may disappear as a result of editing
 buffer C and others may arise, there is generally no simple way to tell
 where the various regions in the merge buffer came from.
 
    In three-way comparison, Ediff tries to disregard regions that
 consist entirely of white space.  For instance, if, say, the current
 region in buffer A consists of the white space only (or if it is empty),
 Ediff will not take it into account for the purpose of computing fine
 differences.  The result is that Ediff can provide a better visual
 information regarding the actual fine differences in the non-white
 regions in buffers B and C.  Moreover, if the regions in buffers B and C
 differ in the white space only, then a message to this effect will be
 displayed.
 
    In the merge mode, the share of the split between window C (the
 window displaying the merge-buffer) and the windows displaying buffers A
 and B is controlled by the variable ‘ediff-merge-window-share’.  Its
 default value is 0.5.  To make the merge-buffer window smaller, reduce
 this amount.
 
    We don’t recommend increasing the size of the merge-window to more
 than half the frame (i.e., to increase the value of
 ‘ediff-merge-window-share’) to more than 0.5, since it would be hard to
 see the contents of buffers A and B.
 
    You can temporarily shrink the merge window to just one line by
 typing ‘s’.  This change is temporary, until Ediff finds a reason to
 redraw the screen.  Typing ‘s’ again restores the original window size.
 
    With a positive prefix argument, the ‘s’ command will make the merge
 window slightly taller.  This change is persistent.  With “‘-’” or with
 a negative prefix argument, the command ‘s’ makes the merge window
 slightly shorter.  This change also persistent.
 
    Ediff lets you automatically ignore the regions where only one of the
 buffers A and B disagrees with the ancestor.  To do this, set the
 variable ‘ediff-show-clashes-only’ to non-‘nil’.
 
    You can toggle this feature interactively by typing ‘$$’.
 
    Note that this variable affects only the show next/previous
 difference commands.  You can still jump directly to any difference
 region directly using the command ‘j’ (with a prefix argument specifying
 the difference number).
 
    The variable ‘ediff-autostore-merges’ controls what happens to the
 merge buffer when Ediff quits.  If the value is ‘nil’, nothing is done
 to the merge buffer—it will be the user’s responsibility to save it.  If
 the value is ‘t’, the user will be asked where to save the buffer and
 whether to delete it afterwards.  It the value is neither ‘nil’ nor ‘t’,
 the merge buffer is saved _only_ if this merge session was invoked from
 a group of related Ediff session, such as those that result from
 ‘ediff-merge-directories’, ‘ediff-merge-directory-revisions’, etc.
 SeeSession Groups.  This behavior is implemented in the function
 ‘ediff-maybe-save-and-delete-merge’, which is a hook in
 ‘ediff-quit-merge-hook’.  The user can supply a different hook, if
 necessary.
 
    The variable ‘ediff-autostore-merges’ is buffer-local, so it can be
 set in a per-buffer manner.  Therefore, use ‘setq-default’ to globally
 change this variable.
 
    When merge buffers are saved automatically as directed by
 ‘ediff-autostore-merges’, Ediff attaches a prefix to each file, as
 specified by the variable ‘ediff-merge-filename-prefix’.  The default is
 ‘merge_’, but this can be changed by the user.