hgbook

diff en/tour-merge.tex @ 103:5b80c922ebdd

More merge content.
author Bryan O'Sullivan <bos@serpentine.com>
date Thu Oct 19 15:18:07 2006 -0700 (2006-10-19)
parents ff9dc8bc2a8b
children 34943a3d50d6
line diff
     1.1 --- a/en/tour-merge.tex	Wed Oct 18 15:47:04 2006 -0700
     1.2 +++ b/en/tour-merge.tex	Thu Oct 19 15:18:07 2006 -0700
     1.3 @@ -113,12 +113,126 @@
     1.4  \section{Merging conflicting changes}
     1.5  
     1.6  Most merges are simple affairs, but sometimes you'll find yourself
     1.7 -merging a change that you made with another, where both modify the
     1.8 -same portions of the same files.  Unless both modifications are
     1.9 -identical, this results in a \emph{conflict}, where you have to decide
    1.10 -how to reconcile the different changes into something coherent.
    1.11 -
    1.12 -\section{Using an extension to simplify merging}
    1.13 +merging changes where each modifies the same portions of the same
    1.14 +files.  Unless both modifications are identical, this results in a
    1.15 +\emph{conflict}, where you have to decide how to reconcile the
    1.16 +different changes into something coherent.
    1.17 +
    1.18 +\begin{figure}[ht]
    1.19 +  \centering
    1.20 +  \grafix{tour-merge-conflict}
    1.21 +  \caption{Conflicting changes to a document}
    1.22 +  \label{fig:tour-merge:conflict}
    1.23 +\end{figure}
    1.24 +
    1.25 +Figure~\ref{fig:tour-merge:conflict} illustrates an instance of two
    1.26 +conflicting changes to a document.  We started with a single version
    1.27 +of the file; then we made some changes; while someone else made
    1.28 +different changes to the same text.  Our task in resolving the
    1.29 +conflicting changes is to decide what the file should look like.
    1.30 +
    1.31 +Mercurial doesn't have a built-in facility for handling conflicts.
    1.32 +Instead, it runs an external program called \command{hgmerge}.  This
    1.33 +is a shell script that is bundled with Mercurial; you can change it to
    1.34 +behave however you please.  What it does by default is try to find one
    1.35 +of several different merging tools that are likely to be installed on
    1.36 +your system.  It first tries a few fully automatic merging tools; if
    1.37 +these don't succeed (because the resolution process requires human
    1.38 +guidance) or aren't present, the script tries a few different
    1.39 +graphical merging tools.
    1.40 +
    1.41 +It's also possible to get Mercurial to run another program or script
    1.42 +instead of \command{hgmerge}, by setting the \envar{HGMERGE}
    1.43 +environment variable to the name of your preferred program.
    1.44 +
    1.45 +\subsection{Using a graphical merge tool}
    1.46 +
    1.47 +My preferred graphical merge tool is \command{kdiff3}, which I'll use
    1.48 +to describe the features that are common to graphical file merging
    1.49 +tools.  You can see a screenshot of \command{kdiff3} in action in
    1.50 +figure~\ref{fig:tour-merge:kdiff3}.  The kind of merge it is
    1.51 +performing is called a \emph{three-way merge}, because there are three
    1.52 +different versions of the file of interest to us.  The tool thus
    1.53 +splits the upper portion of the window into three panes:
    1.54 +\begin{itemize}
    1.55 +\item At the left is the \emph{base} version of the file, i.e.~the
    1.56 +  most recent version from which the two versions we're trying to
    1.57 +  merge are descended.
    1.58 +\item In the middle is ``our'' version of the file, with the contents
    1.59 +  that we modified.
    1.60 +\item On the right is ``their'' version of the file, the one that
    1.61 +  from the changeset that we're trying to merge with.
    1.62 +\end{itemize}
    1.63 +In the pane below these is the current \emph{result} of the merge.
    1.64 +Our task is to replace all of the red text, which indicates unresolved
    1.65 +conflicts, with some sensible merger of the ``ours'' and ``theirs''
    1.66 +versions of the file.
    1.67 +
    1.68 +All four of these panes are \emph{locked together}; if we scroll
    1.69 +vertically or horizontally in any of them, the others are updated to
    1.70 +display the corresponding sections of their respective files.
    1.71 +
    1.72 +\begin{figure}[ht]
    1.73 +  \centering
    1.74 +  \grafix{kdiff3}
    1.75 +  \caption{Using \command{kdiff3} to merge versions of a file}
    1.76 +  \label{fig:tour-merge:kdiff3}
    1.77 +\end{figure}
    1.78 +
    1.79 +For each conflicting portion of the file, we can choose to resolve
    1.80 +thhe conflict using some combination of text from the base version,
    1.81 +ours, or theirs.  We can also manually edit the merged file at any
    1.82 +time, in case we need to make further modifications.
    1.83 +
    1.84 +There are \emph{many} file merging tools available, too many to cover
    1.85 +here.  They vary in which platforms they are available for, and in
    1.86 +their particular strengths and weaknesses.  Most are tuned for merging
    1.87 +files containing plain text, while a few are aimed at specialised file
    1.88 +formats (generally XML).
    1.89 +
    1.90 +\subsection{A worked example}
    1.91 +
    1.92 +In this example, we will reproduce the file modification history of
    1.93 +figure~\ref{fig:tour-merge:conflict} above.  Let's begin by creating a
    1.94 +repository with a base version of our document.
    1.95 +\interaction{tour-merge-conflict.wife}
    1.96 +We'll clone the repository and make a change to the file.
    1.97 +\interaction{tour-merge-conflict.cousin}
    1.98 +And another clone, to simulate someone else making a change to the
    1.99 +file.  (This hints at the idea that it's not all that unusual to merge
   1.100 +with yourself when you isolate tasks in separate repositories, and
   1.101 +indeed to find and resolve conflicts while doing so.)
   1.102 +\interaction{tour-merge-conflict.son}
   1.103 +Having created two different versions of the file, we'll set up an
   1.104 +environment suitable for running our merge.
   1.105 +\interaction{tour-merge-conflict.pull}
   1.106 +
   1.107 +In this example, I won't use Mercurial's normal \command{hgmerge}
   1.108 +program to do the merge, because it would drop my nice automated
   1.109 +example-running tool into a graphical user interface.  Instead, I'll
   1.110 +set \envar{HGMERGE} to tell Mercurial to use the non-interactive
   1.111 +\command{merge} command.  This is bundled with many Unix-like systems.
   1.112 +If you're following this example on your computer, don't bother
   1.113 +setting \envar{HGMERGE}.
   1.114 +\interaction{tour-merge-conflict.merge}
   1.115 +Because \command{merge} can't resolve the conflicting changes, it
   1.116 +leaves \emph{merge markers} inside the file that has conflicts,
   1.117 +indicating which lines have conflicts, and whether they came from our
   1.118 +version of the file or theirs.
   1.119 +
   1.120 +Mercurial can tell from the way \command{merge} exits that it wasn't
   1.121 +able to merge successfully, so it tells us what commands we'll need to
   1.122 +run if we want to redo the merging operation.  This could be useful
   1.123 +if, for example, we were running a graphical merge tool and quit
   1.124 +because we were confused or realised we had made a mistake.
   1.125 +
   1.126 +If automatic or manual merges fail, there's nothing to prevent us from
   1.127 +``fixing up'' the affected files ourselves, and committing the results
   1.128 +of our merge:
   1.129 +\interaction{tour-merge-conflict.commit}
   1.130 +
   1.131 +\section{Simplifying the pull-merge-commit 
   1.132 +  sequence}
   1.133  
   1.134  The process of merging changes as outlined above is straightforward,
   1.135  but requires running three commands in sequence.
   1.136 @@ -127,9 +241,9 @@
   1.137    hg merge
   1.138    hg commit -m 'Merged remote changes'
   1.139  \end{codesample2}
   1.140 -In the case of the final commit, you also need to come up with a
   1.141 -commit message, which is almost always going to be a piece of
   1.142 -uninteresting ``boilerplate'' text.
   1.143 +In the case of the final commit, you also need to enter a commit
   1.144 +message, which is almost always going to be a piece of uninteresting
   1.145 +``boilerplate'' text.
   1.146  
   1.147  It would be nice to reduce the number of steps needed, if this were
   1.148  possible.  Indeed, Mercurial is distributed with an extension called