view en/tour-merge.tex @ 100:272146fab009

Add yet another illustration of the merge process.
author Bryan O'Sullivan <bos@serpentine.com>
date Wed, 18 Oct 2006 12:06:56 -0700
parents 06383f9e46e4
children 321732566ac1
line wrap: on
line source

\chapter{A tour of Mercurial: merging work}
\label{chap:tour-merge}

We've now covered cloning a repository, making changes in a
repository, and pulling or pushing changes from one repository into
another.  Our next step is \emph{merging} changes from separate
repositories.

\section{Merging streams of work}

Merging is a fundamental part of working with a distributed revision
control tool.
\begin{itemize}
\item Alice and Bob each have a personal copy of a repository for a
  project they're collaborating on.  Alice fixes a bug in her
  repository; Bob adds a new feature in his.  They want the shared
  repository to contain both the bug fix and the new feature.
\item I frequently work on several different tasks for a single
  project at once, each safely isolated in its own repository.
  Working this way means that I often need to merge one piece of my
  own work with another.
\end{itemize}

Because merging is such a common thing to need to do, Mercurial makes
it easy.  Let's walk through the process.  We'll begin by cloning yet
another repository (see how often they spring up?) and making a change
in it.
\interaction{tour.merge.clone}
We should now have two copies of \filename{hello.c} with different
contents.  The histories of the two repositories have also diverged,
as illustrated in figure~\ref{fig:tour-merge:sep-repos}.
\interaction{tour.merge.cat}

\begin{figure}[ht]
  \centering
  \grafix{tour-merge-sep-repos}
  \caption{Divergent recent histories of the \dirname{my-hello} and
    \dirname{my-new-hello} repositories}
  \label{fig:tour-merge:sep-repos}
\end{figure}

We already know that pulling changes from our \dirname{my-hello}
repository will have no effect on the working directory.
\interaction{tour.merge.pull}
However, the \hgcmd{pull} command says something about ``heads''.  

A head is a change that has no descendants, or children, as they're
also known.  The tip revision is thus a head, because the newest
revision in a repository doesn't have any children, but a repository
can contain more than one head.

\begin{figure}[ht]
  \centering
  \grafix{tour-merge-pull}
  \caption{Repository contents after pulling from \dirname{my-hello} into
    \dirname{my-new-hello}}
  \label{fig:tour-merge:pull}
\end{figure}

In figure~\ref{fig:tour-merge:pull}, you can see the effect of the
pull from \dirname{my-hello} into \dirname{my-new-hello}.  The history
that was already present in \dirname{my-new-hello} is untouched, but a
new revision has been added.  By referring to
figure~\ref{fig:tour-merge:sep-repos}, we can see that the
\emph{changeset ID} remains the same in the new repository, but the
\emph{revision number} has changed.  (This, incidentally, is a fine
example of why it's not safe to use revision numbers when discussing
changesets.)  We can view the heads in a repository using the
\hgcmd{heads} command.
\interaction{tour.merge.heads}
What happens if we try to use the normal \hgcmd{update} command to
update to the new tip?
\interaction{tour.merge.update}
Mercurial is telling us that the \hgcmd{update} command won't do a
merge; it won't update the working directory when it thinks we might
be wanting to do a merge, unless we force it to do so.  Instead, we
use the \hgcmd{merge} command to merge the two heads.
\interaction{tour.merge.merge}

\begin{figure}[ht]
  \centering
  \grafix{tour-merge-merge}
  \caption{Working directory and repository during merge, and
    following commit}
  \label{fig:tour-merge:merge}
\end{figure}

This updates the working directory so that it contains changes from
\emph{both} heads, which is reflected in both the output of
\hgcmd{parents} and the contents of \filename{hello.c}.
\interaction{tour.merge.parents}
Whenever we've done a merge, \hgcmd{parents} will display two parents
until we \hgcmd{commit} the results of the merge.
\interaction{tour.merge.commit}
We now have a new tip revision; notice that it has \emph{both} of
our former heads as its parents.  These are the same revisions that
were previously displayed by \hgcmd{parents}.
\interaction{tour.merge.tip}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "00book"
%%% End: