changeset 435:7e52f0cc4516

changed es/hgext.tex changed es/hook.tex changed es/kdiff3.png changed es/license.tex changed es/mq-collab.tex changed es/mq-ref.tex changed es/mq.tex changed es/note.png changed es/tour-merge.tex changed es/undo-manual-merge.dot changed es/undo-non-tip.dot files needed to compile the pdf version of the book.
author jerojasro@localhost
date Sat, 18 Oct 2008 15:44:41 -0500
parents 7f0af73f53ab
children 0aa96b0ffb65
files en/examples/bisect.commits.out en/examples/bisect.help.out en/examples/bisect.init.out en/examples/bisect.search.bad-init.out en/examples/bisect.search.good-init.out en/examples/bisect.search.init.out en/examples/bisect.search.reset.out en/examples/bisect.search.rest.out en/examples/bisect.search.step1.out en/examples/bisect.search.step2.out en/examples/branch-repo.bugfix.out en/examples/branching.stable.out es/hgext.tex es/hook.tex es/kdiff3.png es/license.tex es/mq-collab.tex es/mq-ref.tex es/mq.tex es/note.png es/tour-merge.tex es/undo-manual-merge.dot es/undo-non-tip.dot
diffstat 23 files changed, 4067 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/en/examples/bisect.commits.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/bisect.commits.out	Sat Oct 18 15:44:41 2008 -0500
@@ -1,16 +1,3 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
 
 
 
@@ -21,25 +8,3 @@
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/bisect.help.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/bisect.help.out	Sat Oct 18 15:44:41 2008 -0500
@@ -21,4 +21,3 @@
 
 
 
-
--- a/en/examples/bisect.init.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/bisect.init.out	Sat Oct 18 15:44:41 2008 -0500
@@ -1,3 +1,2 @@
 
 
-
--- a/en/examples/bisect.search.bad-init.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/bisect.search.bad-init.out	Sat Oct 18 15:44:41 2008 -0500
@@ -1,2 +1,1 @@
 
-
--- a/en/examples/bisect.search.good-init.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/bisect.search.good-init.out	Sat Oct 18 15:44:41 2008 -0500
@@ -1,4 +1,3 @@
 
 
 
-
--- a/en/examples/bisect.search.init.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/bisect.search.init.out	Sat Oct 18 15:44:41 2008 -0500
@@ -1,25 +1,5 @@
-
-
-
-
-
-
-
-
 
 
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/bisect.search.reset.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/bisect.search.reset.out	Sat Oct 18 15:44:41 2008 -0500
@@ -1,2 +1,1 @@
 
-
--- a/en/examples/bisect.search.rest.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/bisect.search.rest.out	Sat Oct 18 15:44:41 2008 -0500
@@ -14,6 +14,3 @@
 
 
 
-
-
-
--- a/en/examples/bisect.search.step1.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/bisect.search.step1.out	Sat Oct 18 15:44:41 2008 -0500
@@ -9,4 +9,3 @@
 
 
 
-
--- a/en/examples/bisect.search.step2.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/bisect.search.step2.out	Sat Oct 18 15:44:41 2008 -0500
@@ -2,4 +2,3 @@
 
 
 
-
--- a/en/examples/branch-repo.bugfix.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/branch-repo.bugfix.out	Sat Oct 18 15:44:41 2008 -0500
@@ -5,7 +5,7 @@
 $ \textbf{echo 'I fixed a bug using only echo!' >> myfile}
 $ \textbf{hg commit -m 'Important fix for 1.0.1'}
 $ \textbf{hg push}
-pushing to /tmp/branch-repo4rF-PL/myproject-1.0.1
+pushing to 
 searching for changes
 adding changesets
 adding manifests
--- a/en/examples/branching.stable.out	Sat Oct 18 14:35:43 2008 -0500
+++ b/en/examples/branching.stable.out	Sat Oct 18 15:44:41 2008 -0500
@@ -5,7 +5,7 @@
 $ \textbf{echo 'This is a fix to a boring feature.' > myfile}
 $ \textbf{hg commit -m 'Fix a bug'}
 $ \textbf{hg push}
-pushing to /tmp/branchingfJgZac/stable
+pushing to 
 searching for changes
 adding changesets
 adding manifests
--- a/es/hgext.tex	Sat Oct 18 14:35:43 2008 -0500
+++ b/es/hgext.tex	Sat Oct 18 15:44:41 2008 -0500
@@ -0,0 +1,429 @@
+\chapter{Adding functionality with extensions}
+\label{chap:hgext}
+
+While the core of Mercurial is quite complete from a functionality
+standpoint, it's deliberately shorn of fancy features.  This approach
+of preserving simplicity keeps the software easy to deal with for both
+maintainers and users.
+
+However, Mercurial doesn't box you in with an inflexible command set:
+you can add features to it as \emph{extensions} (sometimes known as
+\emph{plugins}).  We've already discussed a few of these extensions in
+earlier chapters.
+\begin{itemize}
+\item Section~\ref{sec:tour-merge:fetch} covers the \hgext{fetch}
+  extension; this combines pulling new changes and merging them with
+  local changes into a single command, \hgxcmd{fetch}{fetch}.
+\item In chapter~\ref{chap:hook}, we covered several extensions that
+  are useful for hook-related functionality: \hgext{acl} adds access
+  control lists; \hgext{bugzilla} adds integration with the Bugzilla
+  bug tracking system; and \hgext{notify} sends notification emails on
+  new changes.
+\item The Mercurial Queues patch management extension is so invaluable
+  that it merits two chapters and an appendix all to itself.
+  Chapter~\ref{chap:mq} covers the basics;
+  chapter~\ref{chap:mq-collab} discusses advanced topics; and
+  appendix~\ref{chap:mqref} goes into detail on each command.
+\end{itemize}
+
+In this chapter, we'll cover some of the other extensions that are
+available for Mercurial, and briefly touch on some of the machinery
+you'll need to know about if you want to write an extension of your
+own.
+\begin{itemize}
+\item In section~\ref{sec:hgext:inotify}, we'll discuss the
+  possibility of \emph{huge} performance improvements using the
+  \hgext{inotify} extension.
+\end{itemize}
+
+\section{Improve performance with the \hgext{inotify} extension}
+\label{sec:hgext:inotify}
+
+Are you interested in having some of the most common Mercurial
+operations run as much as a hundred times faster?  Read on!
+
+Mercurial has great performance under normal circumstances.  For
+example, when you run the \hgcmd{status} command, Mercurial has to
+scan almost every directory and file in your repository so that it can
+display file status.  Many other Mercurial commands need to do the
+same work behind the scenes; for example, the \hgcmd{diff} command
+uses the status machinery to avoid doing an expensive comparison
+operation on files that obviously haven't changed.
+
+Because obtaining file status is crucial to good performance, the
+authors of Mercurial have optimised this code to within an inch of its
+life.  However, there's no avoiding the fact that when you run
+\hgcmd{status}, Mercurial is going to have to perform at least one
+expensive system call for each managed file to determine whether it's
+changed since the last time Mercurial checked.  For a sufficiently
+large repository, this can take a long time.
+
+To put a number on the magnitude of this effect, I created a
+repository containing 150,000 managed files.  I timed \hgcmd{status}
+as taking ten seconds to run, even when \emph{none} of those files had
+been modified.
+
+Many modern operating systems contain a file notification facility.
+If a program signs up to an appropriate service, the operating system
+will notify it every time a file of interest is created, modified, or
+deleted.  On Linux systems, the kernel component that does this is
+called \texttt{inotify}.
+
+Mercurial's \hgext{inotify} extension talks to the kernel's
+\texttt{inotify} component to optimise \hgcmd{status} commands.  The
+extension has two components.  A daemon sits in the background and
+receives notifications from the \texttt{inotify} subsystem.  It also
+listens for connections from a regular Mercurial command.  The
+extension modifies Mercurial's behaviour so that instead of scanning
+the filesystem, it queries the daemon.  Since the daemon has perfect
+information about the state of the repository, it can respond with a
+result instantaneously, avoiding the need to scan every directory and
+file in the repository.
+
+Recall the ten seconds that I measured plain Mercurial as taking to
+run \hgcmd{status} on a 150,000 file repository.  With the
+\hgext{inotify} extension enabled, the time dropped to 0.1~seconds, a
+factor of \emph{one hundred} faster.
+
+Before we continue, please pay attention to some caveats.
+\begin{itemize}
+\item The \hgext{inotify} extension is Linux-specific.  Because it
+  interfaces directly to the Linux kernel's \texttt{inotify}
+  subsystem, it does not work on other operating systems.
+\item It should work on any Linux distribution that was released after
+  early~2005.  Older distributions are likely to have a kernel that
+  lacks \texttt{inotify}, or a version of \texttt{glibc} that does not
+  have the necessary interfacing support.
+\item Not all filesystems are suitable for use with the
+  \hgext{inotify} extension.  Network filesystems such as NFS are a
+  non-starter, for example, particularly if you're running Mercurial
+  on several systems, all mounting the same network filesystem.  The
+  kernel's \texttt{inotify} system has no way of knowing about changes
+  made on another system.  Most local filesystems (e.g.~ext3, XFS,
+  ReiserFS) should work fine.
+\end{itemize}
+
+The \hgext{inotify} extension is not yet shipped with Mercurial as of
+May~2007, so it's a little more involved to set up than other
+extensions.  But the performance improvement is worth it!
+
+The extension currently comes in two parts: a set of patches to the
+Mercurial source code, and a library of Python bindings to the
+\texttt{inotify} subsystem.
+\begin{note}
+  There are \emph{two} Python \texttt{inotify} binding libraries.  One
+  of them is called \texttt{pyinotify}, and is packaged by some Linux
+  distributions as \texttt{python-inotify}.  This is \emph{not} the
+  one you'll need, as it is too buggy and inefficient to be practical.
+\end{note}
+To get going, it's best to already have a functioning copy of
+Mercurial installed.
+\begin{note}
+  If you follow the instructions below, you'll be \emph{replacing} and
+  overwriting any existing installation of Mercurial that you might
+  already have, using the latest ``bleeding edge'' Mercurial code.
+  Don't say you weren't warned!
+\end{note}
+\begin{enumerate}
+\item Clone the Python \texttt{inotify} binding repository.  Build and
+  install it.
+  \begin{codesample4}
+    hg clone http://hg.kublai.com/python/inotify
+    cd inotify
+    python setup.py build --force
+    sudo python setup.py install --skip-build
+  \end{codesample4}
+\item Clone the \dirname{crew} Mercurial repository.  Clone the
+  \hgext{inotify} patch repository so that Mercurial Queues will be
+  able to apply patches to your cope of the \dirname{crew} repository.
+  \begin{codesample4}
+    hg clone http://hg.intevation.org/mercurial/crew
+    hg clone crew inotify
+    hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches
+  \end{codesample4}
+\item Make sure that you have the Mercurial Queues extension,
+  \hgext{mq}, enabled.  If you've never used MQ, read
+  section~\ref{sec:mq:start} to get started quickly.
+\item Go into the \dirname{inotify} repo, and apply all of the
+  \hgext{inotify} patches using the \hgxopt{mq}{qpush}{-a} option to
+  the \hgxcmd{mq}{qpush} command.
+  \begin{codesample4}
+    cd inotify
+    hg qpush -a
+  \end{codesample4}
+  If you get an error message from \hgxcmd{mq}{qpush}, you should not
+  continue.  Instead, ask for help.
+\item Build and install the patched version of Mercurial.
+  \begin{codesample4}
+    python setup.py build --force
+    sudo python setup.py install --skip-build
+  \end{codesample4}
+\end{enumerate}
+Once you've build a suitably patched version of Mercurial, all you
+need to do to enable the \hgext{inotify} extension is add an entry to
+your \hgrc.
+\begin{codesample2}
+  [extensions]
+  inotify =
+\end{codesample2}
+When the \hgext{inotify} extension is enabled, Mercurial will
+automatically and transparently start the status daemon the first time
+you run a command that needs status in a repository.  It runs one
+status daemon per repository.
+
+The status daemon is started silently, and runs in the background.  If
+you look at a list of running processes after you've enabled the
+\hgext{inotify} extension and run a few commands in different
+repositories, you'll thus see a few \texttt{hg} processes sitting
+around, waiting for updates from the kernel and queries from
+Mercurial.
+
+The first time you run a Mercurial command in a repository when you
+have the \hgext{inotify} extension enabled, it will run with about the
+same performance as a normal Mercurial command.  This is because the
+status daemon needs to perform a normal status scan so that it has a
+baseline against which to apply later updates from the kernel.
+However, \emph{every} subsequent command that does any kind of status
+check should be noticeably faster on repositories of even fairly
+modest size.  Better yet, the bigger your repository is, the greater a
+performance advantage you'll see.  The \hgext{inotify} daemon makes
+status operations almost instantaneous on repositories of all sizes!
+
+If you like, you can manually start a status daemon using the
+\hgxcmd{inotify}{inserve} command.  This gives you slightly finer
+control over how the daemon ought to run.  This command will of course
+only be available when the \hgext{inotify} extension is enabled.
+
+When you're using the \hgext{inotify} extension, you should notice
+\emph{no difference at all} in Mercurial's behaviour, with the sole
+exception of status-related commands running a whole lot faster than
+they used to.  You should specifically expect that commands will not
+print different output; neither should they give different results.
+If either of these situations occurs, please report a bug.
+
+\section{Flexible diff support with the \hgext{extdiff} extension}
+\label{sec:hgext:extdiff}
+
+Mercurial's built-in \hgcmd{diff} command outputs plaintext unified
+diffs.
+\interaction{extdiff.diff}
+If you would like to use an external tool to display modifications,
+you'll want to use the \hgext{extdiff} extension.  This will let you
+use, for example, a graphical diff tool.
+
+The \hgext{extdiff} extension is bundled with Mercurial, so it's easy
+to set up.  In the \rcsection{extensions} section of your \hgrc,
+simply add a one-line entry to enable the extension.
+\begin{codesample2}
+  [extensions]
+  extdiff =
+\end{codesample2}
+This introduces a command named \hgxcmd{extdiff}{extdiff}, which by
+default uses your system's \command{diff} command to generate a
+unified diff in the same form as the built-in \hgcmd{diff} command.
+\interaction{extdiff.extdiff}
+The result won't be exactly the same as with the built-in \hgcmd{diff}
+variations, because the output of \command{diff} varies from one
+system to another, even when passed the same options.
+
+As the ``\texttt{making snapshot}'' lines of output above imply, the
+\hgxcmd{extdiff}{extdiff} command works by creating two snapshots of
+your source tree.  The first snapshot is of the source revision; the
+second, of the target revision or working directory.  The
+\hgxcmd{extdiff}{extdiff} command generates these snapshots in a
+temporary directory, passes the name of each directory to an external
+diff viewer, then deletes the temporary directory.  For efficiency, it
+only snapshots the directories and files that have changed between the
+two revisions.
+
+Snapshot directory names have the same base name as your repository.
+If your repository path is \dirname{/quux/bar/foo}, then \dirname{foo}
+will be the name of each snapshot directory.  Each snapshot directory
+name has its changeset ID appended, if appropriate.  If a snapshot is
+of revision \texttt{a631aca1083f}, the directory will be named
+\dirname{foo.a631aca1083f}.  A snapshot of the working directory won't
+have a changeset ID appended, so it would just be \dirname{foo} in
+this example.  To see what this looks like in practice, look again at
+the \hgxcmd{extdiff}{extdiff} example above.  Notice that the diff has
+the snapshot directory names embedded in its header.
+
+The \hgxcmd{extdiff}{extdiff} command accepts two important options.
+The \hgxopt{extdiff}{extdiff}{-p} option lets you choose a program to
+view differences with, instead of \command{diff}.  With the
+\hgxopt{extdiff}{extdiff}{-o} option, you can change the options that
+\hgxcmd{extdiff}{extdiff} passes to the program (by default, these
+options are ``\texttt{-Npru}'', which only make sense if you're
+running \command{diff}).  In other respects, the
+\hgxcmd{extdiff}{extdiff} command acts similarly to the built-in
+\hgcmd{diff} command: you use the same option names, syntax, and
+arguments to specify the revisions you want, the files you want, and
+so on.
+
+As an example, here's how to run the normal system \command{diff}
+command, getting it to generate context diffs (using the
+\cmdopt{diff}{-c} option) instead of unified diffs, and five lines of
+context instead of the default three (passing \texttt{5} as the
+argument to the \cmdopt{diff}{-C} option).
+\interaction{extdiff.extdiff-ctx}
+
+Launching a visual diff tool is just as easy.  Here's how to launch
+the \command{kdiff3} viewer.
+\begin{codesample2}
+  hg extdiff -p kdiff3 -o ''
+\end{codesample2}
+
+If your diff viewing command can't deal with directories, you can
+easily work around this with a little scripting.  For an example of
+such scripting in action with the \hgext{mq} extension and the
+\command{interdiff} command, see
+section~\ref{mq-collab:tips:interdiff}.
+
+\subsection{Defining command aliases}
+
+It can be cumbersome to remember the options to both the
+\hgxcmd{extdiff}{extdiff} command and the diff viewer you want to use,
+so the \hgext{extdiff} extension lets you define \emph{new} commands
+that will invoke your diff viewer with exactly the right options.
+
+All you need to do is edit your \hgrc, and add a section named
+\rcsection{extdiff}.  Inside this section, you can define multiple
+commands.  Here's how to add a \texttt{kdiff3} command.  Once you've
+defined this, you can type ``\texttt{hg kdiff3}'' and the
+\hgext{extdiff} extension will run \command{kdiff3} for you.
+\begin{codesample2}
+  [extdiff]
+  cmd.kdiff3 =
+\end{codesample2}
+If you leave the right hand side of the definition empty, as above,
+the \hgext{extdiff} extension uses the name of the command you defined
+as the name of the external program to run.  But these names don't
+have to be the same.  Here, we define a command named ``\texttt{hg
+  wibble}'', which runs \command{kdiff3}.
+\begin{codesample2}
+  [extdiff]
+  cmd.wibble = kdiff3
+\end{codesample2}
+
+You can also specify the default options that you want to invoke your
+diff viewing program with.  The prefix to use is ``\texttt{opts.}'',
+followed by the name of the command to which the options apply.  This
+example defines a ``\texttt{hg vimdiff}'' command that runs the
+\command{vim} editor's \texttt{DirDiff} extension.
+\begin{codesample2}
+  [extdiff]  
+  cmd.vimdiff = vim
+  opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'
+\end{codesample2}
+
+\section{Cherrypicking changes with the \hgext{transplant} extension}
+\label{sec:hgext:transplant}
+
+Need to have a long chat with Brendan about this.
+
+\section{Send changes via email with the \hgext{patchbomb} extension}
+\label{sec:hgext:patchbomb}
+
+Many projects have a culture of ``change review'', in which people
+send their modifications to a mailing list for others to read and
+comment on before they commit the final version to a shared
+repository.  Some projects have people who act as gatekeepers; they
+apply changes from other people to a repository to which those others
+don't have access.
+
+Mercurial makes it easy to send changes over email for review or
+application, via its \hgext{patchbomb} extension.  The extension is so
+namd because changes are formatted as patches, and it's usual to send
+one changeset per email message.  Sending a long series of changes by
+email is thus much like ``bombing'' the recipient's inbox, hence
+``patchbomb''.
+
+As usual, the basic configuration of the \hgext{patchbomb} extension
+takes just one or two lines in your \hgrc.
+\begin{codesample2}
+  [extensions]
+  patchbomb =
+\end{codesample2}
+Once you've enabled the extension, you will have a new command
+available, named \hgxcmd{patchbomb}{email}.
+
+The safest and best way to invoke the \hgxcmd{patchbomb}{email}
+command is to \emph{always} run it first with the
+\hgxopt{patchbomb}{email}{-n} option.  This will show you what the
+command \emph{would} send, without actually sending anything.  Once
+you've had a quick glance over the changes and verified that you are
+sending the right ones, you can rerun the same command, with the
+\hgxopt{patchbomb}{email}{-n} option removed.
+
+The \hgxcmd{patchbomb}{email} command accepts the same kind of
+revision syntax as every other Mercurial command.  For example, this
+command will send every revision between 7 and \texttt{tip},
+inclusive.
+\begin{codesample2}
+  hg email -n 7:tip
+\end{codesample2}
+You can also specify a \emph{repository} to compare with.  If you
+provide a repository but no revisions, the \hgxcmd{patchbomb}{email}
+command will send all revisions in the local repository that are not
+present in the remote repository.  If you additionally specify
+revisions or a branch name (the latter using the
+\hgxopt{patchbomb}{email}{-b} option), this will constrain the
+revisions sent.
+
+It's perfectly safe to run the \hgxcmd{patchbomb}{email} command
+without the names of the people you want to send to: if you do this,
+it will just prompt you for those values interactively.  (If you're
+using a Linux or Unix-like system, you should have enhanced
+\texttt{readline}-style editing capabilities when entering those
+headers, too, which is useful.)
+
+When you are sending just one revision, the \hgxcmd{patchbomb}{email}
+command will by default use the first line of the changeset
+description as the subject of the single email message it sends.
+
+If you send multiple revisions, the \hgxcmd{patchbomb}{email} command
+will usually send one message per changeset.  It will preface the
+series with an introductory message, in which you should describe the
+purpose of the series of changes you're sending.
+
+\subsection{Changing the behaviour of patchbombs}
+
+Not every project has exactly the same conventions for sending changes
+in email; the \hgext{patchbomb} extension tries to accommodate a
+number of variations through command line options.
+\begin{itemize}
+\item You can write a subject for the introductory message on the
+  command line using the \hgxopt{patchbomb}{email}{-s} option.  This
+  takes one argument, the text of the subject to use.
+\item To change the email address from which the messages originate,
+  use the \hgxopt{patchbomb}{email}{-f} option.  This takes one
+  argument, the email address to use.
+\item The default behaviour is to send unified diffs (see
+  section~\ref{sec:mq:patch} for a description of the format), one per
+  message.  You can send a binary bundle instead with the
+  \hgxopt{patchbomb}{email}{-b} option.  
+\item Unified diffs are normally prefaced with a metadata header.  You
+  can omit this, and send unadorned diffs, with the
+  \hgxopt{patchbomb}{email}{--plain} option.
+\item Diffs are normally sent ``inline'', in the same body part as the
+  description of a patch.  This makes it easiest for the largest
+  number of readers to quote and respond to parts of a diff, as some
+  mail clients will only quote the first MIME body part in a message.
+  If you'd prefer to send the description and the diff in separate
+  body parts, use the \hgxopt{patchbomb}{email}{-a} option.
+\item Instead of sending mail messages, you can write them to an
+  \texttt{mbox}-format mail folder using the
+  \hgxopt{patchbomb}{email}{-m} option.  That option takes one
+  argument, the name of the file to write to.
+\item If you would like to add a \command{diffstat}-format summary to
+  each patch, and one to the introductory message, use the
+  \hgxopt{patchbomb}{email}{-d} option.  The \command{diffstat}
+  command displays a table containing the name of each file patched,
+  the number of lines affected, and a histogram showing how much each
+  file is modified.  This gives readers a qualitative glance at how
+  complex a patch is.
+\end{itemize}
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- a/es/hook.tex	Sat Oct 18 14:35:43 2008 -0500
+++ b/es/hook.tex	Sat Oct 18 15:44:41 2008 -0500
@@ -0,0 +1,1413 @@
+\chapter{Handling repository events with hooks}
+\label{chap:hook}
+
+Mercurial offers a powerful mechanism to let you perform automated
+actions in response to events that occur in a repository.  In some
+cases, you can even control Mercurial's response to those events.
+
+The name Mercurial uses for one of these actions is a \emph{hook}.
+Hooks are called ``triggers'' in some revision control systems, but
+the two names refer to the same idea.
+
+\section{An overview of hooks in Mercurial}
+
+Here is a brief list of the hooks that Mercurial supports.  We will
+revisit each of these hooks in more detail later, in
+section~\ref{sec:hook:ref}.
+
+\begin{itemize}
+\item[\small\hook{changegroup}] This is run after a group of
+  changesets has been brought into the repository from elsewhere.
+\item[\small\hook{commit}] This is run after a new changeset has been
+  created in the local repository.
+\item[\small\hook{incoming}] This is run once for each new changeset
+  that is brought into the repository from elsewhere.  Notice the
+  difference from \hook{changegroup}, which is run once per
+  \emph{group} of changesets brought in.
+\item[\small\hook{outgoing}] This is run after a group of changesets
+  has been transmitted from this repository.
+\item[\small\hook{prechangegroup}] This is run before starting to
+  bring a group of changesets into the repository.
+\item[\small\hook{precommit}] Controlling. This is run before starting
+  a commit.
+\item[\small\hook{preoutgoing}] Controlling. This is run before
+  starting to transmit a group of changesets from this repository.
+\item[\small\hook{pretag}] Controlling. This is run before creating a tag.
+\item[\small\hook{pretxnchangegroup}] Controlling. This is run after a
+  group of changesets has been brought into the local repository from
+  another, but before the transaction completes that will make the
+  changes permanent in the repository.
+\item[\small\hook{pretxncommit}] Controlling. This is run after a new
+  changeset has been created in the local repository, but before the
+  transaction completes that will make it permanent.
+\item[\small\hook{preupdate}] Controlling. This is run before starting
+  an update or merge of the working directory.
+\item[\small\hook{tag}] This is run after a tag is created.
+\item[\small\hook{update}] This is run after an update or merge of the
+  working directory has finished.
+\end{itemize}
+Each of the hooks whose description begins with the word
+``Controlling'' has the ability to determine whether an activity can
+proceed.  If the hook succeeds, the activity may proceed; if it fails,
+the activity is either not permitted or undone, depending on the hook.
+
+\section{Hooks and security}
+
+\subsection{Hooks are run with your privileges}
+
+When you run a Mercurial command in a repository, and the command
+causes a hook to run, that hook runs on \emph{your} system, under
+\emph{your} user account, with \emph{your} privilege level.  Since
+hooks are arbitrary pieces of executable code, you should treat them
+with an appropriate level of suspicion.  Do not install a hook unless
+you are confident that you know who created it and what it does.
+
+In some cases, you may be exposed to hooks that you did not install
+yourself.  If you work with Mercurial on an unfamiliar system,
+Mercurial will run hooks defined in that system's global \hgrc\ file.
+
+If you are working with a repository owned by another user, Mercurial
+can run hooks defined in that user's repository, but it will still run
+them as ``you''.  For example, if you \hgcmd{pull} from that
+repository, and its \sfilename{.hg/hgrc} defines a local
+\hook{outgoing} hook, that hook will run under your user account, even
+though you don't own that repository.
+
+\begin{note}
+  This only applies if you are pulling from a repository on a local or
+  network filesystem.  If you're pulling over http or ssh, any
+  \hook{outgoing} hook will run under whatever account is executing
+  the server process, on the server.
+\end{note}
+
+XXX To see what hooks are defined in a repository, use the
+\hgcmdargs{config}{hooks} command.  If you are working in one
+repository, but talking to another that you do not own (e.g.~using
+\hgcmd{pull} or \hgcmd{incoming}), remember that it is the other
+repository's hooks you should be checking, not your own.
+
+\subsection{Hooks do not propagate}
+
+In Mercurial, hooks are not revision controlled, and do not propagate
+when you clone, or pull from, a repository.  The reason for this is
+simple: a hook is a completely arbitrary piece of executable code.  It
+runs under your user identity, with your privilege level, on your
+machine.
+
+It would be extremely reckless for any distributed revision control
+system to implement revision-controlled hooks, as this would offer an
+easily exploitable way to subvert the accounts of users of the
+revision control system.
+
+Since Mercurial does not propagate hooks, if you are collaborating
+with other people on a common project, you should not assume that they
+are using the same Mercurial hooks as you are, or that theirs are
+correctly configured.  You should document the hooks you expect people
+to use.
+
+In a corporate intranet, this is somewhat easier to control, as you
+can for example provide a ``standard'' installation of Mercurial on an
+NFS filesystem, and use a site-wide \hgrc\ file to define hooks that
+all users will see.  However, this too has its limits; see below.
+
+\subsection{Hooks can be overridden}
+
+Mercurial allows you to override a hook definition by redefining the
+hook.  You can disable it by setting its value to the empty string, or
+change its behaviour as you wish.
+
+If you deploy a system-~or site-wide \hgrc\ file that defines some
+hooks, you should thus understand that your users can disable or
+override those hooks.
+
+\subsection{Ensuring that critical hooks are run}
+
+Sometimes you may want to enforce a policy that you do not want others
+to be able to work around.  For example, you may have a requirement
+that every changeset must pass a rigorous set of tests.  Defining this
+requirement via a hook in a site-wide \hgrc\ won't work for remote
+users on laptops, and of course local users can subvert it at will by
+overriding the hook.
+
+Instead, you can set up your policies for use of Mercurial so that
+people are expected to propagate changes through a well-known
+``canonical'' server that you have locked down and configured
+appropriately.
+
+One way to do this is via a combination of social engineering and
+technology.  Set up a restricted-access account; users can push
+changes over the network to repositories managed by this account, but
+they cannot log into the account and run normal shell commands.  In
+this scenario, a user can commit a changeset that contains any old
+garbage they want.
+
+When someone pushes a changeset to the server that everyone pulls
+from, the server will test the changeset before it accepts it as
+permanent, and reject it if it fails to pass the test suite.  If
+people only pull changes from this filtering server, it will serve to
+ensure that all changes that people pull have been automatically
+vetted.
+
+\section{Care with \texttt{pretxn} hooks in a shared-access repository}
+
+If you want to use hooks to do some automated work in a repository
+that a number of people have shared access to, you need to be careful
+in how you do this.
+
+Mercurial only locks a repository when it is writing to the
+repository, and only the parts of Mercurial that write to the
+repository pay attention to locks.  Write locks are necessary to
+prevent multiple simultaneous writers from scribbling on each other's
+work, corrupting the repository.
+
+Because Mercurial is careful with the order in which it reads and
+writes data, it does not need to acquire a lock when it wants to read
+data from the repository.  The parts of Mercurial that read from the
+repository never pay attention to locks.  This lockless reading scheme
+greatly increases performance and concurrency.
+
+With great performance comes a trade-off, though, one which has the
+potential to cause you trouble unless you're aware of it.  To describe
+this requires a little detail about how Mercurial adds changesets to a
+repository and reads those changes.
+
+When Mercurial \emph{writes} metadata, it writes it straight into the
+destination file.  It writes file data first, then manifest data
+(which contains pointers to the new file data), then changelog data
+(which contains pointers to the new manifest data).  Before the first
+write to each file, it stores a record of where the end of the file
+was in its transaction log.  If the transaction must be rolled back,
+Mercurial simply truncates each file back to the size it was before the
+transaction began.
+
+When Mercurial \emph{reads} metadata, it reads the changelog first,
+then everything else.  Since a reader will only access parts of the
+manifest or file metadata that it can see in the changelog, it can
+never see partially written data.
+
+Some controlling hooks (\hook{pretxncommit} and
+\hook{pretxnchangegroup}) run when a transaction is almost complete.
+All of the metadata has been written, but Mercurial can still roll the
+transaction back and cause the newly-written data to disappear.
+
+If one of these hooks runs for long, it opens a window of time during
+which a reader can see the metadata for changesets that are not yet
+permanent, and should not be thought of as ``really there''.  The
+longer the hook runs, the longer that window is open.
+
+\subsection{The problem illustrated}
+
+In principle, a good use for the \hook{pretxnchangegroup} hook would
+be to automatically build and test incoming changes before they are
+accepted into a central repository.  This could let you guarantee that
+nobody can push changes to this repository that ``break the build''.
+But if a client can pull changes while they're being tested, the
+usefulness of the test is zero; an unsuspecting someone can pull
+untested changes, potentially breaking their build.
+
+The safest technological answer to this challenge is to set up such a
+``gatekeeper'' repository as \emph{unidirectional}.  Let it take
+changes pushed in from the outside, but do not allow anyone to pull
+changes from it (use the \hook{preoutgoing} hook to lock it down).
+Configure a \hook{changegroup} hook so that if a build or test
+succeeds, the hook will push the new changes out to another repository
+that people \emph{can} pull from.
+
+In practice, putting a centralised bottleneck like this in place is
+not often a good idea, and transaction visibility has nothing to do
+with the problem.  As the size of a project---and the time it takes to
+build and test---grows, you rapidly run into a wall with this ``try
+before you buy'' approach, where you have more changesets to test than
+time in which to deal with them.  The inevitable result is frustration
+on the part of all involved.
+
+An approach that scales better is to get people to build and test
+before they push, then run automated builds and tests centrally
+\emph{after} a push, to be sure all is well.  The advantage of this
+approach is that it does not impose a limit on the rate at which the
+repository can accept changes.
+
+\section{A short tutorial on using hooks}
+\label{sec:hook:simple}
+
+It is easy to write a Mercurial hook.  Let's start with a hook that
+runs when you finish a \hgcmd{commit}, and simply prints the hash of
+the changeset you just created.  The hook is called \hook{commit}.
+
+\begin{figure}[ht]
+  \interaction{hook.simple.init}
+  \caption{A simple hook that runs when a changeset is committed}
+  \label{ex:hook:init}
+\end{figure}
+
+All hooks follow the pattern in example~\ref{ex:hook:init}.  You add
+an entry to the \rcsection{hooks} section of your \hgrc.  On the left
+is the name of the event to trigger on; on the right is the action to
+take.  As you can see, you can run an arbitrary shell command in a
+hook.  Mercurial passes extra information to the hook using
+environment variables (look for \envar{HG\_NODE} in the example).
+
+\subsection{Performing multiple actions per event}
+
+Quite often, you will want to define more than one hook for a
+particular kind of event, as shown in example~\ref{ex:hook:ext}.
+Mercurial lets you do this by adding an \emph{extension} to the end of
+a hook's name.  You extend a hook's name by giving the name of the
+hook, followed by a full stop (the ``\texttt{.}'' character), followed
+by some more text of your choosing.  For example, Mercurial will run
+both \texttt{commit.foo} and \texttt{commit.bar} when the
+\texttt{commit} event occurs.
+
+\begin{figure}[ht]
+  \interaction{hook.simple.ext}
+  \caption{Defining a second \hook{commit} hook}
+  \label{ex:hook:ext}
+\end{figure}
+
+To give a well-defined order of execution when there are multiple
+hooks defined for an event, Mercurial sorts hooks by extension, and
+executes the hook commands in this sorted order.  In the above
+example, it will execute \texttt{commit.bar} before
+\texttt{commit.foo}, and \texttt{commit} before both.
+
+It is a good idea to use a somewhat descriptive extension when you
+define a new hook.  This will help you to remember what the hook was
+for.  If the hook fails, you'll get an error message that contains the
+hook name and extension, so using a descriptive extension could give
+you an immediate hint as to why the hook failed (see
+section~\ref{sec:hook:perm} for an example).
+
+\subsection{Controlling whether an activity can proceed}
+\label{sec:hook:perm}
+
+In our earlier examples, we used the \hook{commit} hook, which is
+run after a commit has completed.  This is one of several Mercurial
+hooks that run after an activity finishes.  Such hooks have no way of
+influencing the activity itself.
+
+Mercurial defines a number of events that occur before an activity
+starts; or after it starts, but before it finishes.  Hooks that
+trigger on these events have the added ability to choose whether the
+activity can continue, or will abort.  
+
+The \hook{pretxncommit} hook runs after a commit has all but
+completed.  In other words, the metadata representing the changeset
+has been written out to disk, but the transaction has not yet been
+allowed to complete.  The \hook{pretxncommit} hook has the ability to
+decide whether the transaction can complete, or must be rolled back.
+
+If the \hook{pretxncommit} hook exits with a status code of zero, the
+transaction is allowed to complete; the commit finishes; and the
+\hook{commit} hook is run.  If the \hook{pretxncommit} hook exits with
+a non-zero status code, the transaction is rolled back; the metadata
+representing the changeset is erased; and the \hook{commit} hook is
+not run.
+
+\begin{figure}[ht]
+  \interaction{hook.simple.pretxncommit}
+  \caption{Using the \hook{pretxncommit} hook to control commits}
+  \label{ex:hook:pretxncommit}
+\end{figure}
+
+The hook in example~\ref{ex:hook:pretxncommit} checks that a commit
+comment contains a bug ID.  If it does, the commit can complete.  If
+not, the commit is rolled back.
+
+\section{Writing your own hooks}
+
+When you are writing a hook, you might find it useful to run Mercurial
+either with the \hggopt{-v} option, or the \rcitem{ui}{verbose} config
+item set to ``true''.  When you do so, Mercurial will print a message
+before it calls each hook.
+
+\subsection{Choosing how your hook should run}
+\label{sec:hook:lang}
+
+You can write a hook either as a normal program---typically a shell
+script---or as a Python function that is executed within the Mercurial
+process.
+
+Writing a hook as an external program has the advantage that it
+requires no knowledge of Mercurial's internals.  You can call normal
+Mercurial commands to get any added information you need.  The
+trade-off is that external hooks are slower than in-process hooks.
+
+An in-process Python hook has complete access to the Mercurial API,
+and does not ``shell out'' to another process, so it is inherently
+faster than an external hook.  It is also easier to obtain much of the
+information that a hook requires by using the Mercurial API than by
+running Mercurial commands.
+
+If you are comfortable with Python, or require high performance,
+writing your hooks in Python may be a good choice.  However, when you
+have a straightforward hook to write and you don't need to care about
+performance (probably the majority of hooks), a shell script is
+perfectly fine.
+
+\subsection{Hook parameters}
+\label{sec:hook:param}
+
+Mercurial calls each hook with a set of well-defined parameters.  In
+Python, a parameter is passed as a keyword argument to your hook
+function.  For an external program, a parameter is passed as an
+environment variable.
+
+Whether your hook is written in Python or as a shell script, the
+hook-specific parameter names and values will be the same.  A boolean
+parameter will be represented as a boolean value in Python, but as the
+number 1 (for ``true'') or 0 (for ``false'') as an environment
+variable for an external hook.  If a hook parameter is named
+\texttt{foo}, the keyword argument for a Python hook will also be
+named \texttt{foo}, while the environment variable for an external
+hook will be named \texttt{HG\_FOO}.
+
+\subsection{Hook return values and activity control}
+
+A hook that executes successfully must exit with a status of zero if
+external, or return boolean ``false'' if in-process.  Failure is
+indicated with a non-zero exit status from an external hook, or an
+in-process hook returning boolean ``true''.  If an in-process hook
+raises an exception, the hook is considered to have failed.
+
+For a hook that controls whether an activity can proceed, zero/false
+means ``allow'', while non-zero/true/exception means ``deny''.
+
+\subsection{Writing an external hook}
+
+When you define an external hook in your \hgrc\ and the hook is run,
+its value is passed to your shell, which interprets it.  This means
+that you can use normal shell constructs in the body of the hook.
+
+An executable hook is always run with its current directory set to a
+repository's root directory.
+
+Each hook parameter is passed in as an environment variable; the name
+is upper-cased, and prefixed with the string ``\texttt{HG\_}''.
+
+With the exception of hook parameters, Mercurial does not set or
+modify any environment variables when running a hook.  This is useful
+to remember if you are writing a site-wide hook that may be run by a
+number of different users with differing environment variables set.
+In multi-user situations, you should not rely on environment variables
+being set to the values you have in your environment when testing the
+hook.
+
+\subsection{Telling Mercurial to use an in-process hook}
+
+The \hgrc\ syntax for defining an in-process hook is slightly
+different than for an executable hook.  The value of the hook must
+start with the text ``\texttt{python:}'', and continue with the
+fully-qualified name of a callable object to use as the hook's value.
+
+The module in which a hook lives is automatically imported when a hook
+is run.  So long as you have the module name and \envar{PYTHONPATH}
+right, it should ``just work''.
+
+The following \hgrc\ example snippet illustrates the syntax and
+meaning of the notions we just described.
+\begin{codesample2}
+  [hooks]
+  commit.example = python:mymodule.submodule.myhook
+\end{codesample2}
+When Mercurial runs the \texttt{commit.example} hook, it imports
+\texttt{mymodule.submodule}, looks for the callable object named
+\texttt{myhook}, and calls it.
+
+\subsection{Writing an in-process hook}
+
+The simplest in-process hook does nothing, but illustrates the basic
+shape of the hook API:
+\begin{codesample2}
+  def myhook(ui, repo, **kwargs):
+      pass
+\end{codesample2}
+The first argument to a Python hook is always a
+\pymodclass{mercurial.ui}{ui} object.  The second is a repository object;
+at the moment, it is always an instance of
+\pymodclass{mercurial.localrepo}{localrepository}.  Following these two
+arguments are other keyword arguments.  Which ones are passed in
+depends on the hook being called, but a hook can ignore arguments it
+doesn't care about by dropping them into a keyword argument dict, as
+with \texttt{**kwargs} above.
+
+\section{Some hook examples}
+
+\subsection{Writing meaningful commit messages}
+
+It's hard to imagine a useful commit message being very short.  The
+simple \hook{pretxncommit} hook of figure~\ref{ex:hook:msglen.go}
+will prevent you from committing a changeset with a message that is
+less than ten bytes long.
+
+\begin{figure}[ht]
+  \interaction{hook.msglen.go}
+  \caption{A hook that forbids overly short commit messages}
+  \label{ex:hook:msglen.go}
+\end{figure}
+
+\subsection{Checking for trailing whitespace}
+
+An interesting use of a commit-related hook is to help you to write
+cleaner code.  A simple example of ``cleaner code'' is the dictum that
+a change should not add any new lines of text that contain ``trailing
+whitespace''.  Trailing whitespace is a series of space and tab
+characters at the end of a line of text.  In most cases, trailing
+whitespace is unnecessary, invisible noise, but it is occasionally
+problematic, and people often prefer to get rid of it.
+
+You can use either the \hook{precommit} or \hook{pretxncommit} hook to
+tell whether you have a trailing whitespace problem.  If you use the
+\hook{precommit} hook, the hook will not know which files you are
+committing, so it will have to check every modified file in the
+repository for trailing white space.  If you want to commit a change
+to just the file \filename{foo}, but the file \filename{bar} contains
+trailing whitespace, doing a check in the \hook{precommit} hook will
+prevent you from committing \filename{foo} due to the problem with
+\filename{bar}.  This doesn't seem right.
+
+Should you choose the \hook{pretxncommit} hook, the check won't occur
+until just before the transaction for the commit completes.  This will
+allow you to check for problems only the exact files that are being
+committed.  However, if you entered the commit message interactively
+and the hook fails, the transaction will roll back; you'll have to
+re-enter the commit message after you fix the trailing whitespace and
+run \hgcmd{commit} again.
+
+\begin{figure}[ht]
+  \interaction{hook.ws.simple}
+  \caption{A simple hook that checks for trailing whitespace}
+  \label{ex:hook:ws.simple}
+\end{figure}
+
+Figure~\ref{ex:hook:ws.simple} introduces a simple \hook{pretxncommit}
+hook that checks for trailing whitespace.  This hook is short, but not
+very helpful.  It exits with an error status if a change adds a line
+with trailing whitespace to any file, but does not print any
+information that might help us to identify the offending file or
+line.  It also has the nice property of not paying attention to
+unmodified lines; only lines that introduce new trailing whitespace
+cause problems.
+
+\begin{figure}[ht]
+  \interaction{hook.ws.better}
+  \caption{A better trailing whitespace hook}
+  \label{ex:hook:ws.better}
+\end{figure}
+
+The example of figure~\ref{ex:hook:ws.better} is much more complex,
+but also more useful.  It parses a unified diff to see if any lines
+add trailing whitespace, and prints the name of the file and the line
+number of each such occurrence.  Even better, if the change adds
+trailing whitespace, this hook saves the commit comment and prints the
+name of the save file before exiting and telling Mercurial to roll the
+transaction back, so you can use
+\hgcmdargs{commit}{\hgopt{commit}{-l}~\emph{filename}} to reuse the
+saved commit message once you've corrected the problem.
+
+As a final aside, note in figure~\ref{ex:hook:ws.better} the use of
+\command{perl}'s in-place editing feature to get rid of trailing
+whitespace from a file.  This is concise and useful enough that I will
+reproduce it here.
+\begin{codesample2}
+  perl -pi -e 's,\\s+\$,,' filename
+\end{codesample2}
+
+\section{Bundled hooks}
+
+Mercurial ships with several bundled hooks.  You can find them in the
+\dirname{hgext} directory of a Mercurial source tree.  If you are
+using a Mercurial binary package, the hooks will be located in the
+\dirname{hgext} directory of wherever your package installer put
+Mercurial.
+
+\subsection{\hgext{acl}---access control for parts of a repository}
+
+The \hgext{acl} extension lets you control which remote users are
+allowed to push changesets to a networked server.  You can protect any
+portion of a repository (including the entire repo), so that a
+specific remote user can push changes that do not affect the protected
+portion.
+
+This extension implements access control based on the identity of the
+user performing a push, \emph{not} on who committed the changesets
+they're pushing.  It makes sense to use this hook only if you have a
+locked-down server environment that authenticates remote users, and
+you want to be sure that only specific users are allowed to push
+changes to that server.
+
+\subsubsection{Configuring the \hook{acl} hook}
+
+In order to manage incoming changesets, the \hgext{acl} hook must be
+used as a \hook{pretxnchangegroup} hook.  This lets it see which files
+are modified by each incoming changeset, and roll back a group of
+changesets if they modify ``forbidden'' files.  Example:
+\begin{codesample2}
+  [hooks]
+  pretxnchangegroup.acl = python:hgext.acl.hook
+\end{codesample2}
+
+The \hgext{acl} extension is configured using three sections.  
+
+The \rcsection{acl} section has only one entry, \rcitem{acl}{sources},
+which lists the sources of incoming changesets that the hook should
+pay attention to.  You don't normally need to configure this section.
+\begin{itemize}
+\item[\rcitem{acl}{serve}] Control incoming changesets that are arriving
+  from a remote repository over http or ssh.  This is the default
+  value of \rcitem{acl}{sources}, and usually the only setting you'll
+  need for this configuration item.
+\item[\rcitem{acl}{pull}] Control incoming changesets that are
+  arriving via a pull from a local repository.
+\item[\rcitem{acl}{push}] Control incoming changesets that are
+  arriving via a push from a local repository.
+\item[\rcitem{acl}{bundle}] Control incoming changesets that are
+  arriving from another repository via a bundle.
+\end{itemize}
+
+The \rcsection{acl.allow} section controls the users that are allowed to
+add changesets to the repository.  If this section is not present, all
+users that are not explicitly denied are allowed.  If this section is
+present, all users that are not explicitly allowed are denied (so an
+empty section means that all users are denied).
+
+The \rcsection{acl.deny} section determines which users are denied
+from adding changesets to the repository.  If this section is not
+present or is empty, no users are denied.
+
+The syntaxes for the \rcsection{acl.allow} and \rcsection{acl.deny}
+sections are identical.  On the left of each entry is a glob pattern
+that matches files or directories, relative to the root of the
+repository; on the right, a user name.
+
+In the following example, the user \texttt{docwriter} can only push
+changes to the \dirname{docs} subtree of the repository, while
+\texttt{intern} can push changes to any file or directory except
+\dirname{source/sensitive}.
+\begin{codesample2}
+  [acl.allow]
+  docs/** = docwriter
+
+  [acl.deny]
+  source/sensitive/** = intern
+\end{codesample2}
+
+\subsubsection{Testing and troubleshooting}
+
+If you want to test the \hgext{acl} hook, run it with Mercurial's
+debugging output enabled.  Since you'll probably be running it on a
+server where it's not convenient (or sometimes possible) to pass in
+the \hggopt{--debug} option, don't forget that you can enable
+debugging output in your \hgrc:
+\begin{codesample2}
+  [ui]
+  debug = true
+\end{codesample2}
+With this enabled, the \hgext{acl} hook will print enough information
+to let you figure out why it is allowing or forbidding pushes from
+specific users.
+
+\subsection{\hgext{bugzilla}---integration with Bugzilla}
+
+The \hgext{bugzilla} extension adds a comment to a Bugzilla bug
+whenever it finds a reference to that bug ID in a commit comment.  You
+can install this hook on a shared server, so that any time a remote
+user pushes changes to this server, the hook gets run.  
+
+It adds a comment to the bug that looks like this (you can configure
+the contents of the comment---see below):
+\begin{codesample2}
+  Changeset aad8b264143a, made by Joe User <joe.user@domain.com> in
+  the frobnitz repository, refers to this bug.
+
+  For complete details, see
+  http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
+
+  Changeset description:
+        Fix bug 10483 by guarding against some NULL pointers
+\end{codesample2}
+The value of this hook is that it automates the process of updating a
+bug any time a changeset refers to it.  If you configure the hook
+properly, it makes it easy for people to browse straight from a
+Bugzilla bug to a changeset that refers to that bug.
+
+You can use the code in this hook as a starting point for some more
+exotic Bugzilla integration recipes.  Here are a few possibilities:
+\begin{itemize}
+\item Require that every changeset pushed to the server have a valid
+  bug~ID in its commit comment.  In this case, you'd want to configure
+  the hook as a \hook{pretxncommit} hook.  This would allow the hook
+  to reject changes that didn't contain bug IDs.
+\item Allow incoming changesets to automatically modify the
+  \emph{state} of a bug, as well as simply adding a comment.  For
+  example, the hook could recognise the string ``fixed bug 31337'' as
+  indicating that it should update the state of bug 31337 to
+  ``requires testing''.
+\end{itemize}
+
+\subsubsection{Configuring the \hook{bugzilla} hook}
+\label{sec:hook:bugzilla:config}
+
+You should configure this hook in your server's \hgrc\ as an
+\hook{incoming} hook, for example as follows:
+\begin{codesample2}
+  [hooks]
+  incoming.bugzilla = python:hgext.bugzilla.hook
+\end{codesample2}
+
+Because of the specialised nature of this hook, and because Bugzilla
+was not written with this kind of integration in mind, configuring
+this hook is a somewhat involved process.
+
+Before you begin, you must install the MySQL bindings for Python on
+the host(s) where you'll be running the hook.  If this is not
+available as a binary package for your system, you can download it
+from~\cite{web:mysql-python}.
+
+Configuration information for this hook lives in the
+\rcsection{bugzilla} section of your \hgrc.
+\begin{itemize}
+\item[\rcitem{bugzilla}{version}] The version of Bugzilla installed on
+  the server.  The database schema that Bugzilla uses changes
+  occasionally, so this hook has to know exactly which schema to use.
+  At the moment, the only version supported is \texttt{2.16}.
+\item[\rcitem{bugzilla}{host}] The hostname of the MySQL server that
+  stores your Bugzilla data.  The database must be configured to allow
+  connections from whatever host you are running the \hook{bugzilla}
+  hook on.
+\item[\rcitem{bugzilla}{user}] The username with which to connect to
+  the MySQL server.  The database must be configured to allow this
+  user to connect from whatever host you are running the
+  \hook{bugzilla} hook on.  This user must be able to access and
+  modify Bugzilla tables.  The default value of this item is
+  \texttt{bugs}, which is the standard name of the Bugzilla user in a
+  MySQL database.
+\item[\rcitem{bugzilla}{password}] The MySQL password for the user you
+  configured above.  This is stored as plain text, so you should make
+  sure that unauthorised users cannot read the \hgrc\ file where you
+  store this information.
+\item[\rcitem{bugzilla}{db}] The name of the Bugzilla database on the
+  MySQL server.  The default value of this item is \texttt{bugs},
+  which is the standard name of the MySQL database where Bugzilla
+  stores its data.
+\item[\rcitem{bugzilla}{notify}] If you want Bugzilla to send out a
+  notification email to subscribers after this hook has added a
+  comment to a bug, you will need this hook to run a command whenever
+  it updates the database.  The command to run depends on where you
+  have installed Bugzilla, but it will typically look something like
+  this, if you have Bugzilla installed in
+  \dirname{/var/www/html/bugzilla}:
+  \begin{codesample4}
+    cd /var/www/html/bugzilla && ./processmail %s nobody@nowhere.com
+  \end{codesample4}
+  The Bugzilla \texttt{processmail} program expects to be given a
+  bug~ID (the hook replaces ``\texttt{\%s}'' with the bug~ID) and an
+  email address.  It also expects to be able to write to some files in
+  the directory that it runs in.  If Bugzilla and this hook are not
+  installed on the same machine, you will need to find a way to run
+  \texttt{processmail} on the server where Bugzilla is installed.
+\end{itemize}
+
+\subsubsection{Mapping committer names to Bugzilla user names}
+
+By default, the \hgext{bugzilla} hook tries to use the email address
+of a changeset's committer as the Bugzilla user name with which to
+update a bug.  If this does not suit your needs, you can map committer
+email addresses to Bugzilla user names using a \rcsection{usermap}
+section.
+
+Each item in the \rcsection{usermap} section contains an email address
+on the left, and a Bugzilla user name on the right.
+\begin{codesample2}
+  [usermap]
+  jane.user@example.com = jane
+\end{codesample2}
+You can either keep the \rcsection{usermap} data in a normal \hgrc, or
+tell the \hgext{bugzilla} hook to read the information from an
+external \filename{usermap} file.  In the latter case, you can store
+\filename{usermap} data by itself in (for example) a user-modifiable
+repository.  This makes it possible to let your users maintain their
+own \rcitem{bugzilla}{usermap} entries.  The main \hgrc\ file might
+look like this:
+\begin{codesample2}
+  # regular hgrc file refers to external usermap file
+  [bugzilla]
+  usermap = /home/hg/repos/userdata/bugzilla-usermap.conf
+\end{codesample2}
+While the \filename{usermap} file that it refers to might look like
+this:
+\begin{codesample2}
+  # bugzilla-usermap.conf - inside a hg repository
+  [usermap]
+  stephanie@example.com = steph
+\end{codesample2}
+
+\subsubsection{Configuring the text that gets added to a bug}
+
+You can configure the text that this hook adds as a comment; you
+specify it in the form of a Mercurial template.  Several \hgrc\
+entries (still in the \rcsection{bugzilla} section) control this
+behaviour.
+\begin{itemize}
+\item[\texttt{strip}] The number of leading path elements to strip
+  from a repository's path name to construct a partial path for a URL.
+  For example, if the repositories on your server live under
+  \dirname{/home/hg/repos}, and you have a repository whose path is
+  \dirname{/home/hg/repos/app/tests}, then setting \texttt{strip} to
+  \texttt{4} will give a partial path of \dirname{app/tests}.  The
+  hook will make this partial path available when expanding a
+  template, as \texttt{webroot}.
+\item[\texttt{template}] The text of the template to use.  In addition
+  to the usual changeset-related variables, this template can use
+  \texttt{hgweb} (the value of the \texttt{hgweb} configuration item
+  above) and \texttt{webroot} (the path constructed using
+  \texttt{strip} above).
+\end{itemize}
+
+In addition, you can add a \rcitem{web}{baseurl} item to the
+\rcsection{web} section of your \hgrc.  The \hgext{bugzilla} hook will
+make this available when expanding a template, as the base string to
+use when constructing a URL that will let users browse from a Bugzilla
+comment to view a changeset.  Example:
+\begin{codesample2}
+  [web]
+  baseurl = http://hg.domain.com/
+\end{codesample2}
+
+Here is an example set of \hgext{bugzilla} hook config information.
+\begin{codesample2}
+  [bugzilla]
+  host = bugzilla.example.com
+  password = mypassword
+  version = 2.16
+  # server-side repos live in /home/hg/repos, so strip 4 leading
+  # separators
+  strip = 4
+  hgweb = http://hg.example.com/
+  usermap = /home/hg/repos/notify/bugzilla.conf
+  template = Changeset \{node|short\}, made by \{author\} in the \{webroot\}
+    repo, refers to this bug.\\nFor complete details, see 
+    \{hgweb\}\{webroot\}?cmd=changeset;node=\{node|short\}\\nChangeset
+    description:\\n\\t\{desc|tabindent\}
+\end{codesample2}
+
+\subsubsection{Testing and troubleshooting}
+
+The most common problems with configuring the \hgext{bugzilla} hook
+relate to running Bugzilla's \filename{processmail} script and mapping
+committer names to user names.
+
+Recall from section~\ref{sec:hook:bugzilla:config} above that the user
+that runs the Mercurial process on the server is also the one that
+will run the \filename{processmail} script.  The
+\filename{processmail} script sometimes causes Bugzilla to write to
+files in its configuration directory, and Bugzilla's configuration
+files are usually owned by the user that your web server runs under.
+
+You can cause \filename{processmail} to be run with the suitable
+user's identity using the \command{sudo} command.  Here is an example
+entry for a \filename{sudoers} file.
+\begin{codesample2}
+  hg_user = (httpd_user) NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s
+\end{codesample2}
+This allows the \texttt{hg\_user} user to run a
+\filename{processmail-wrapper} program under the identity of
+\texttt{httpd\_user}.
+
+This indirection through a wrapper script is necessary, because
+\filename{processmail} expects to be run with its current directory
+set to wherever you installed Bugzilla; you can't specify that kind of
+constraint in a \filename{sudoers} file.  The contents of the wrapper
+script are simple:
+\begin{codesample2}
+  #!/bin/sh
+  cd `dirname $0` && ./processmail "$1" nobody@example.com
+\end{codesample2}
+It doesn't seem to matter what email address you pass to
+\filename{processmail}.
+
+If your \rcsection{usermap} is not set up correctly, users will see an
+error message from the \hgext{bugzilla} hook when they push changes
+to the server.  The error message will look like this:
+\begin{codesample2}
+  cannot find bugzilla user id for john.q.public@example.com
+\end{codesample2}
+What this means is that the committer's address,
+\texttt{john.q.public@example.com}, is not a valid Bugzilla user name,
+nor does it have an entry in your \rcsection{usermap} that maps it to
+a valid Bugzilla user name.
+
+\subsection{\hgext{notify}---send email notifications}
+
+Although Mercurial's built-in web server provides RSS feeds of changes
+in every repository, many people prefer to receive change
+notifications via email.  The \hgext{notify} hook lets you send out
+notifications to a set of email addresses whenever changesets arrive
+that those subscribers are interested in.
+
+As with the \hgext{bugzilla} hook, the \hgext{notify} hook is
+template-driven, so you can customise the contents of the notification
+messages that it sends.
+
+By default, the \hgext{notify} hook includes a diff of every changeset
+that it sends out; you can limit the size of the diff, or turn this
+feature off entirely.  It is useful for letting subscribers review
+changes immediately, rather than clicking to follow a URL.
+
+\subsubsection{Configuring the \hgext{notify} hook}
+
+You can set up the \hgext{notify} hook to send one email message per
+incoming changeset, or one per incoming group of changesets (all those
+that arrived in a single pull or push).
+\begin{codesample2}
+  [hooks]
+  # send one email per group of changes
+  changegroup.notify = python:hgext.notify.hook
+  # send one email per change
+  incoming.notify = python:hgext.notify.hook
+\end{codesample2}
+
+Configuration information for this hook lives in the
+\rcsection{notify} section of a \hgrc\ file.
+\begin{itemize}
+\item[\rcitem{notify}{test}] By default, this hook does not send out
+  email at all; instead, it prints the message that it \emph{would}
+  send.  Set this item to \texttt{false} to allow email to be sent.
+  The reason that sending of email is turned off by default is that it
+  takes several tries to configure this extension exactly as you would
+  like, and it would be bad form to spam subscribers with a number of
+  ``broken'' notifications while you debug your configuration.
+\item[\rcitem{notify}{config}] The path to a configuration file that
+  contains subscription information.  This is kept separate from the
+  main \hgrc\ so that you can maintain it in a repository of its own.
+  People can then clone that repository, update their subscriptions,
+  and push the changes back to your server.
+\item[\rcitem{notify}{strip}] The number of leading path separator
+  characters to strip from a repository's path, when deciding whether
+  a repository has subscribers.  For example, if the repositories on
+  your server live in \dirname{/home/hg/repos}, and \hgext{notify} is
+  considering a repository named \dirname{/home/hg/repos/shared/test},
+  setting \rcitem{notify}{strip} to \texttt{4} will cause
+  \hgext{notify} to trim the path it considers down to
+  \dirname{shared/test}, and it will match subscribers against that.
+\item[\rcitem{notify}{template}] The template text to use when sending
+  messages.  This specifies both the contents of the message header
+  and its body.
+\item[\rcitem{notify}{maxdiff}] The maximum number of lines of diff
+  data to append to the end of a message.  If a diff is longer than
+  this, it is truncated.  By default, this is set to 300.  Set this to
+  \texttt{0} to omit diffs from notification emails.
+\item[\rcitem{notify}{sources}] A list of sources of changesets to
+  consider.  This lets you limit \hgext{notify} to only sending out
+  email about changes that remote users pushed into this repository
+  via a server, for example.  See section~\ref{sec:hook:sources} for
+  the sources you can specify here.
+\end{itemize}
+
+If you set the \rcitem{web}{baseurl} item in the \rcsection{web}
+section, you can use it in a template; it will be available as
+\texttt{webroot}.
+
+Here is an example set of \hgext{notify} configuration information.
+\begin{codesample2}
+  [notify]
+  # really send email
+  test = false
+  # subscriber data lives in the notify repo
+  config = /home/hg/repos/notify/notify.conf
+  # repos live in /home/hg/repos on server, so strip 4 "/" chars
+  strip = 4
+  template = X-Hg-Repo: \{webroot\}
+    Subject: \{webroot\}: \{desc|firstline|strip\}
+    From: \{author\}
+
+    changeset \{node|short\} in \{root\}
+    details: \{baseurl\}\{webroot\}?cmd=changeset;node=\{node|short\}
+    description:
+      \{desc|tabindent|strip\}
+
+  [web]
+  baseurl = http://hg.example.com/
+\end{codesample2}
+
+This will produce a message that looks like the following:
+\begin{codesample2}
+  X-Hg-Repo: tests/slave
+  Subject: tests/slave: Handle error case when slave has no buffers
+  Date: Wed,  2 Aug 2006 15:25:46 -0700 (PDT)
+
+  changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave
+  details: http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5
+  description:
+          Handle error case when slave has no buffers
+  diffs (54 lines):
+
+  diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h
+  --- a/include/tests.h      Wed Aug 02 15:19:52 2006 -0700
+  +++ b/include/tests.h      Wed Aug 02 15:25:26 2006 -0700
+  @@ -212,6 +212,15 @@ static __inline__ void test_headers(void *h)
+  [...snip...]
+\end{codesample2}
+
+\subsubsection{Testing and troubleshooting}
+
+Do not forget that by default, the \hgext{notify} extension \emph{will
+  not send any mail} until you explicitly configure it to do so, by
+setting \rcitem{notify}{test} to \texttt{false}.  Until you do that,
+it simply prints the message it \emph{would} send.
+
+\section{Information for writers of hooks}
+\label{sec:hook:ref}
+
+\subsection{In-process hook execution}
+
+An in-process hook is called with arguments of the following form:
+\begin{codesample2}
+  def myhook(ui, repo, **kwargs):
+      pass
+\end{codesample2}
+The \texttt{ui} parameter is a \pymodclass{mercurial.ui}{ui} object.
+The \texttt{repo} parameter is a
+\pymodclass{mercurial.localrepo}{localrepository} object.  The
+names and values of the \texttt{**kwargs} parameters depend on the
+hook being invoked, with the following common features:
+\begin{itemize}
+\item If a parameter is named \texttt{node} or
+  \texttt{parent\emph{N}}, it will contain a hexadecimal changeset ID.
+  The empty string is used to represent ``null changeset ID'' instead
+  of a string of zeroes.
+\item If a parameter is named \texttt{url}, it will contain the URL of
+  a remote repository, if that can be determined.
+\item Boolean-valued parameters are represented as Python
+  \texttt{bool} objects.
+\end{itemize}
+
+An in-process hook is called without a change to the process's working
+directory (unlike external hooks, which are run in the root of the
+repository).  It must not change the process's working directory, or
+it will cause any calls it makes into the Mercurial API to fail.
+
+If a hook returns a boolean ``false'' value, it is considered to have
+succeeded.  If it returns a boolean ``true'' value or raises an
+exception, it is considered to have failed.  A useful way to think of
+the calling convention is ``tell me if you fail''.
+
+Note that changeset IDs are passed into Python hooks as hexadecimal
+strings, not the binary hashes that Mercurial's APIs normally use.  To
+convert a hash from hex to binary, use the
+\pymodfunc{mercurial.node}{bin} function.
+
+\subsection{External hook execution}
+
+An external hook is passed to the shell of the user running Mercurial.
+Features of that shell, such as variable substitution and command
+redirection, are available.  The hook is run in the root directory of
+the repository (unlike in-process hooks, which are run in the same
+directory that Mercurial was run in).
+
+Hook parameters are passed to the hook as environment variables.  Each
+environment variable's name is converted in upper case and prefixed
+with the string ``\texttt{HG\_}''.  For example, if the name of a
+parameter is ``\texttt{node}'', the name of the environment variable
+representing that parameter will be ``\texttt{HG\_NODE}''.
+
+A boolean parameter is represented as the string ``\texttt{1}'' for
+``true'', ``\texttt{0}'' for ``false''.  If an environment variable is
+named \envar{HG\_NODE}, \envar{HG\_PARENT1} or \envar{HG\_PARENT2}, it
+contains a changeset ID represented as a hexadecimal string.  The
+empty string is used to represent ``null changeset ID'' instead of a
+string of zeroes.  If an environment variable is named
+\envar{HG\_URL}, it will contain the URL of a remote repository, if
+that can be determined.
+
+If a hook exits with a status of zero, it is considered to have
+succeeded.  If it exits with a non-zero status, it is considered to
+have failed.
+
+\subsection{Finding out where changesets come from}
+
+A hook that involves the transfer of changesets between a local
+repository and another may be able to find out information about the
+``far side''.  Mercurial knows \emph{how} changes are being
+transferred, and in many cases \emph{where} they are being transferred
+to or from.
+
+\subsubsection{Sources of changesets}
+\label{sec:hook:sources}
+
+Mercurial will tell a hook what means are, or were, used to transfer
+changesets between repositories.  This is provided by Mercurial in a
+Python parameter named \texttt{source}, or an environment variable named
+\envar{HG\_SOURCE}.
+
+\begin{itemize}
+\item[\texttt{serve}] Changesets are transferred to or from a remote
+  repository over http or ssh.
+\item[\texttt{pull}] Changesets are being transferred via a pull from
+  one repository into another.
+\item[\texttt{push}] Changesets are being transferred via a push from
+  one repository into another.
+\item[\texttt{bundle}] Changesets are being transferred to or from a
+  bundle.
+\end{itemize}
+
+\subsubsection{Where changes are going---remote repository URLs}
+\label{sec:hook:url}
+
+When possible, Mercurial will tell a hook the location of the ``far
+side'' of an activity that transfers changeset data between
+repositories.  This is provided by Mercurial in a Python parameter
+named \texttt{url}, or an environment variable named \envar{HG\_URL}.
+
+This information is not always known.  If a hook is invoked in a
+repository that is being served via http or ssh, Mercurial cannot tell
+where the remote repository is, but it may know where the client is
+connecting from.  In such cases, the URL will take one of the
+following forms:
+\begin{itemize}
+\item \texttt{remote:ssh:\emph{ip-address}}---remote ssh client, at
+  the given IP address.
+\item \texttt{remote:http:\emph{ip-address}}---remote http client, at
+  the given IP address.  If the client is using SSL, this will be of
+  the form \texttt{remote:https:\emph{ip-address}}.
+\item Empty---no information could be discovered about the remote
+  client.
+\end{itemize}
+
+\section{Hook reference}
+
+\subsection{\hook{changegroup}---after remote changesets added}
+\label{sec:hook:changegroup}
+
+This hook is run after a group of pre-existing changesets has been
+added to the repository, for example via a \hgcmd{pull} or
+\hgcmd{unbundle}.  This hook is run once per operation that added one
+or more changesets.  This is in contrast to the \hook{incoming} hook,
+which is run once per changeset, regardless of whether the changesets
+arrive in a group.
+
+Some possible uses for this hook include kicking off an automated
+build or test of the added changesets, updating a bug database, or
+notifying subscribers that a repository contains new changes.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{node}] A changeset ID.  The changeset ID of the first
+  changeset in the group that was added.  All changesets between this
+  and \index{tags!\texttt{tip}}\texttt{tip}, inclusive, were added by
+  a single \hgcmd{pull}, \hgcmd{push} or \hgcmd{unbundle}.
+\item[\texttt{source}] A string.  The source of these changes.  See
+  section~\ref{sec:hook:sources} for details.
+\item[\texttt{url}] A URL.  The location of the remote repository, if
+  known.  See section~\ref{sec:hook:url} for more information.
+\end{itemize}
+
+See also: \hook{incoming} (section~\ref{sec:hook:incoming}),
+\hook{prechangegroup} (section~\ref{sec:hook:prechangegroup}),
+\hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
+
+\subsection{\hook{commit}---after a new changeset is created}
+\label{sec:hook:commit}
+
+This hook is run after a new changeset has been created.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{node}] A changeset ID.  The changeset ID of the newly
+  committed changeset.
+\item[\texttt{parent1}] A changeset ID.  The changeset ID of the first
+  parent of the newly committed changeset.
+\item[\texttt{parent2}] A changeset ID.  The changeset ID of the second
+  parent of the newly committed changeset.
+\end{itemize}
+
+See also: \hook{precommit} (section~\ref{sec:hook:precommit}),
+\hook{pretxncommit} (section~\ref{sec:hook:pretxncommit})
+
+\subsection{\hook{incoming}---after one remote changeset is added}
+\label{sec:hook:incoming}
+
+This hook is run after a pre-existing changeset has been added to the
+repository, for example via a \hgcmd{push}.  If a group of changesets
+was added in a single operation, this hook is called once for each
+added changeset.
+
+You can use this hook for the same purposes as the \hook{changegroup}
+hook (section~\ref{sec:hook:changegroup}); it's simply more convenient
+sometimes to run a hook once per group of changesets, while other
+times it's handier once per changeset.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{node}] A changeset ID.  The ID of the newly added
+  changeset.
+\item[\texttt{source}] A string.  The source of these changes.  See
+  section~\ref{sec:hook:sources} for details.
+\item[\texttt{url}] A URL.  The location of the remote repository, if
+  known.  See section~\ref{sec:hook:url} for more information.
+\end{itemize}
+
+See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}) \hook{prechangegroup} (section~\ref{sec:hook:prechangegroup}), \hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
+
+\subsection{\hook{outgoing}---after changesets are propagated}
+\label{sec:hook:outgoing}
+
+This hook is run after a group of changesets has been propagated out
+of this repository, for example by a \hgcmd{push} or \hgcmd{bundle}
+command.
+
+One possible use for this hook is to notify administrators that
+changes have been pulled.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{node}] A changeset ID.  The changeset ID of the first
+  changeset of the group that was sent.
+\item[\texttt{source}] A string.  The source of the of the operation
+  (see section~\ref{sec:hook:sources}).  If a remote client pulled
+  changes from this repository, \texttt{source} will be
+  \texttt{serve}.  If the client that obtained changes from this
+  repository was local, \texttt{source} will be \texttt{bundle},
+  \texttt{pull}, or \texttt{push}, depending on the operation the
+  client performed.
+\item[\texttt{url}] A URL.  The location of the remote repository, if
+  known.  See section~\ref{sec:hook:url} for more information.
+\end{itemize}
+
+See also: \hook{preoutgoing} (section~\ref{sec:hook:preoutgoing})
+
+\subsection{\hook{prechangegroup}---before starting to add remote changesets}
+\label{sec:hook:prechangegroup}
+
+This controlling hook is run before Mercurial begins to add a group of
+changesets from another repository.
+
+This hook does not have any information about the changesets to be
+added, because it is run before transmission of those changesets is
+allowed to begin.  If this hook fails, the changesets will not be
+transmitted.
+
+One use for this hook is to prevent external changes from being added
+to a repository.  For example, you could use this to ``freeze'' a
+server-hosted branch temporarily or permanently so that users cannot
+push to it, while still allowing a local administrator to modify the
+repository.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{source}] A string.  The source of these changes.  See
+  section~\ref{sec:hook:sources} for details.
+\item[\texttt{url}] A URL.  The location of the remote repository, if
+  known.  See section~\ref{sec:hook:url} for more information.
+\end{itemize}
+
+See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}),
+\hook{incoming} (section~\ref{sec:hook:incoming}), ,
+\hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
+
+\subsection{\hook{precommit}---before starting to commit a changeset}
+\label{sec:hook:precommit}
+
+This hook is run before Mercurial begins to commit a new changeset.
+It is run before Mercurial has any of the metadata for the commit,
+such as the files to be committed, the commit message, or the commit
+date.
+
+One use for this hook is to disable the ability to commit new
+changesets, while still allowing incoming changesets.  Another is to
+run a build or test, and only allow the commit to begin if the build
+or test succeeds.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{parent1}] A changeset ID.  The changeset ID of the first
+  parent of the working directory.
+\item[\texttt{parent2}] A changeset ID.  The changeset ID of the second
+  parent of the working directory.
+\end{itemize}
+If the commit proceeds, the parents of the working directory will
+become the parents of the new changeset.
+
+See also: \hook{commit} (section~\ref{sec:hook:commit}),
+\hook{pretxncommit} (section~\ref{sec:hook:pretxncommit})
+
+\subsection{\hook{preoutgoing}---before starting to propagate changesets}
+\label{sec:hook:preoutgoing}
+
+This hook is invoked before Mercurial knows the identities of the
+changesets to be transmitted.
+
+One use for this hook is to prevent changes from being transmitted to
+another repository.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{source}] A string.  The source of the operation that is
+  attempting to obtain changes from this repository (see
+  section~\ref{sec:hook:sources}).  See the documentation for the
+  \texttt{source} parameter to the \hook{outgoing} hook, in
+  section~\ref{sec:hook:outgoing}, for possible values of this
+  parameter.
+\item[\texttt{url}] A URL.  The location of the remote repository, if
+  known.  See section~\ref{sec:hook:url} for more information.
+\end{itemize}
+
+See also: \hook{outgoing} (section~\ref{sec:hook:outgoing})
+
+\subsection{\hook{pretag}---before tagging a changeset}
+\label{sec:hook:pretag}
+
+This controlling hook is run before a tag is created.  If the hook
+succeeds, creation of the tag proceeds.  If the hook fails, the tag is
+not created.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{local}] A boolean.  Whether the tag is local to this
+  repository instance (i.e.~stored in \sfilename{.hg/localtags}) or
+  managed by Mercurial (stored in \sfilename{.hgtags}).
+\item[\texttt{node}] A changeset ID.  The ID of the changeset to be tagged.
+\item[\texttt{tag}] A string.  The name of the tag to be created.
+\end{itemize}
+
+If the tag to be created is revision-controlled, the \hook{precommit}
+and \hook{pretxncommit} hooks (sections~\ref{sec:hook:commit}
+and~\ref{sec:hook:pretxncommit}) will also be run.
+
+See also: \hook{tag} (section~\ref{sec:hook:tag})
+
+\subsection{\hook{pretxnchangegroup}---before completing addition of
+  remote changesets}
+\label{sec:hook:pretxnchangegroup}
+
+This controlling hook is run before a transaction---that manages the
+addition of a group of new changesets from outside the
+repository---completes.  If the hook succeeds, the transaction
+completes, and all of the changesets become permanent within this
+repository.  If the hook fails, the transaction is rolled back, and
+the data for the changesets is erased.
+
+This hook can access the metadata associated with the almost-added
+changesets, but it should not do anything permanent with this data.
+It must also not modify the working directory.
+
+While this hook is running, if other Mercurial processes access this
+repository, they will be able to see the almost-added changesets as if
+they are permanent.  This may lead to race conditions if you do not
+take steps to avoid them.
+
+This hook can be used to automatically vet a group of changesets.  If
+the hook fails, all of the changesets are ``rejected'' when the
+transaction rolls back.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{node}] A changeset ID.  The changeset ID of the first
+  changeset in the group that was added.  All changesets between this
+  and \index{tags!\texttt{tip}}\texttt{tip}, inclusive, were added by
+  a single \hgcmd{pull}, \hgcmd{push} or \hgcmd{unbundle}.
+\item[\texttt{source}] A string.  The source of these changes.  See
+  section~\ref{sec:hook:sources} for details.
+\item[\texttt{url}] A URL.  The location of the remote repository, if
+  known.  See section~\ref{sec:hook:url} for more information.
+\end{itemize}
+
+See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}),
+\hook{incoming} (section~\ref{sec:hook:incoming}),
+\hook{prechangegroup} (section~\ref{sec:hook:prechangegroup})
+
+\subsection{\hook{pretxncommit}---before completing commit of new changeset}
+\label{sec:hook:pretxncommit}
+
+This controlling hook is run before a transaction---that manages a new
+commit---completes.  If the hook succeeds, the transaction completes
+and the changeset becomes permanent within this repository.  If the
+hook fails, the transaction is rolled back, and the commit data is
+erased.
+
+This hook can access the metadata associated with the almost-new
+changeset, but it should not do anything permanent with this data.  It
+must also not modify the working directory.
+
+While this hook is running, if other Mercurial processes access this
+repository, they will be able to see the almost-new changeset as if it
+is permanent.  This may lead to race conditions if you do not take
+steps to avoid them.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{node}] A changeset ID.  The changeset ID of the newly
+  committed changeset.
+\item[\texttt{parent1}] A changeset ID.  The changeset ID of the first
+  parent of the newly committed changeset.
+\item[\texttt{parent2}] A changeset ID.  The changeset ID of the second
+  parent of the newly committed changeset.
+\end{itemize}
+
+See also: \hook{precommit} (section~\ref{sec:hook:precommit})
+
+\subsection{\hook{preupdate}---before updating or merging working directory}
+\label{sec:hook:preupdate}
+
+This controlling hook is run before an update or merge of the working
+directory begins.  It is run only if Mercurial's normal pre-update
+checks determine that the update or merge can proceed.  If the hook
+succeeds, the update or merge may proceed; if it fails, the update or
+merge does not start.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{parent1}] A changeset ID.  The ID of the parent that the
+  working directory is to be updated to.  If the working directory is
+  being merged, it will not change this parent.
+\item[\texttt{parent2}] A changeset ID.  Only set if the working
+  directory is being merged.  The ID of the revision that the working
+  directory is being merged with.
+\end{itemize}
+
+See also: \hook{update} (section~\ref{sec:hook:update})
+
+\subsection{\hook{tag}---after tagging a changeset}
+\label{sec:hook:tag}
+
+This hook is run after a tag has been created.
+
+Parameters to this hook:
+\begin{itemize}
+\item[\texttt{local}] A boolean.  Whether the new tag is local to this
+  repository instance (i.e.~stored in \sfilename{.hg/localtags}) or
+  managed by Mercurial (stored in \sfilename{.hgtags}).
+\item[\texttt{node}] A changeset ID.  The ID of the changeset that was
+  tagged.
+\item[\texttt{tag}] A string.  The name of the tag that was created.
+\end{itemize}
+
+If the created tag is revision-controlled, the \hook{commit} hook
+(section~\ref{sec:hook:commit}) is run before this hook.
+
+See also: \hook{pretag} (section~\ref{sec:hook:pretag})
+
+\subsection{\hook{update}---after updating or merging working directory}
+\label{sec:hook:update}
+
+This hook is run after an update or merge of the working directory
+completes.  Since a merge can fail (if the external \command{hgmerge}
+command fails to resolve conflicts in a file), this hook communicates
+whether the update or merge completed cleanly.
+
+\begin{itemize}
+\item[\texttt{error}] A boolean.  Indicates whether the update or
+  merge completed successfully.
+\item[\texttt{parent1}] A changeset ID.  The ID of the parent that the
+  working directory was updated to.  If the working directory was
+  merged, it will not have changed this parent.
+\item[\texttt{parent2}] A changeset ID.  Only set if the working
+  directory was merged.  The ID of the revision that the working
+  directory was merged with.
+\end{itemize}
+
+See also: \hook{preupdate} (section~\ref{sec:hook:preupdate})
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
Binary file es/kdiff3.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/license.tex	Sat Oct 18 15:44:41 2008 -0500
@@ -0,0 +1,138 @@
+\chapter{Open Publication License}
+\label{cha:opl}
+
+Version 1.0, 8 June 1999
+
+\section{Requirements on both unmodified and modified versions}
+
+The Open Publication works may be reproduced and distributed in whole
+or in part, in any medium physical or electronic, provided that the
+terms of this license are adhered to, and that this license or an
+incorporation of it by reference (with any options elected by the
+author(s) and/or publisher) is displayed in the reproduction.
+
+Proper form for an incorporation by reference is as follows:
+
+\begin{quote}
+  Copyright (c) \emph{year} by \emph{author's name or designee}. This
+  material may be distributed only subject to the terms and conditions
+  set forth in the Open Publication License, v\emph{x.y} or later (the
+  latest version is presently available at
+  \url{http://www.opencontent.org/openpub/}).
+\end{quote}
+
+The reference must be immediately followed with any options elected by
+the author(s) and/or publisher of the document (see
+section~\ref{sec:opl:options}).
+
+Commercial redistribution of Open Publication-licensed material is
+permitted.
+
+Any publication in standard (paper) book form shall require the
+citation of the original publisher and author. The publisher and
+author's names shall appear on all outer surfaces of the book. On all
+outer surfaces of the book the original publisher's name shall be as
+large as the title of the work and cited as possessive with respect to
+the title.
+
+\section{Copyright}
+
+The copyright to each Open Publication is owned by its author(s) or
+designee.
+
+\section{Scope of license}
+
+The following license terms apply to all Open Publication works,
+unless otherwise explicitly stated in the document.
+
+Mere aggregation of Open Publication works or a portion of an Open
+Publication work with other works or programs on the same media shall
+not cause this license to apply to those other works. The aggregate
+work shall contain a notice specifying the inclusion of the Open
+Publication material and appropriate copyright notice.
+
+\textbf{Severability}. If any part of this license is found to be
+unenforceable in any jurisdiction, the remaining portions of the
+license remain in force.
+
+\textbf{No warranty}. Open Publication works are licensed and provided
+``as is'' without warranty of any kind, express or implied, including,
+but not limited to, the implied warranties of merchantability and
+fitness for a particular purpose or a warranty of non-infringement.
+
+\section{Requirements on modified works}
+
+All modified versions of documents covered by this license, including
+translations, anthologies, compilations and partial documents, must
+meet the following requirements:
+
+\begin{enumerate}
+\item The modified version must be labeled as such.
+\item The person making the modifications must be identified and the
+  modifications dated.
+\item Acknowledgement of the original author and publisher if
+  applicable must be retained according to normal academic citation
+  practices.
+\item The location of the original unmodified document must be
+  identified.
+\item The original author's (or authors') name(s) may not be used to
+  assert or imply endorsement of the resulting document without the
+  original author's (or authors') permission.
+\end{enumerate}
+
+\section{Good-practice recommendations}
+
+In addition to the requirements of this license, it is requested from
+and strongly recommended of redistributors that:
+
+\begin{enumerate}
+\item If you are distributing Open Publication works on hardcopy or
+  CD-ROM, you provide email notification to the authors of your intent
+  to redistribute at least thirty days before your manuscript or media
+  freeze, to give the authors time to provide updated documents. This
+  notification should describe modifications, if any, made to the
+  document.
+\item All substantive modifications (including deletions) be either
+  clearly marked up in the document or else described in an attachment
+  to the document.
+\item Finally, while it is not mandatory under this license, it is
+  considered good form to offer a free copy of any hardcopy and CD-ROM
+  expression of an Open Publication-licensed work to its author(s).
+\end{enumerate}
+
+\section{License options}
+\label{sec:opl:options}
+
+The author(s) and/or publisher of an Open Publication-licensed
+document may elect certain options by appending language to the
+reference to or copy of the license. These options are considered part
+of the license instance and must be included with the license (or its
+incorporation by reference) in derived works.
+
+\begin{enumerate}[A]
+\item To prohibit distribution of substantively modified versions
+  without the explicit permission of the author(s). ``Substantive
+  modification'' is defined as a change to the semantic content of the
+  document, and excludes mere changes in format or typographical
+  corrections.
+
+  To accomplish this, add the phrase ``Distribution of substantively
+  modified versions of this document is prohibited without the
+  explicit permission of the copyright holder.'' to the license
+  reference or copy.
+
+\item To prohibit any publication of this work or derivative works in
+  whole or in part in standard (paper) book form for commercial
+  purposes is prohibited unless prior permission is obtained from the
+  copyright holder.
+
+  To accomplish this, add the phrase ``Distribution of the work or
+  derivative of the work in any standard (paper) book form is
+  prohibited unless prior permission is obtained from the copyright
+  holder.'' to the license reference or copy.
+\end{enumerate}
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- a/es/mq-collab.tex	Sat Oct 18 14:35:43 2008 -0500
+++ b/es/mq-collab.tex	Sat Oct 18 15:44:41 2008 -0500
@@ -0,0 +1,393 @@
+\chapter{Advanced uses of Mercurial Queues}
+\label{chap:mq-collab}
+
+While it's easy to pick up straightforward uses of Mercurial Queues,
+use of a little discipline and some of MQ's less frequently used
+capabilities makes it possible to work in complicated development
+environments.
+
+In this chapter, I will use as an example a technique I have used to
+manage the development of an Infiniband device driver for the Linux
+kernel.  The driver in question is large (at least as drivers go),
+with 25,000 lines of code spread across 35 source files.  It is
+maintained by a small team of developers.
+
+While much of the material in this chapter is specific to Linux, the
+same principles apply to any code base for which you're not the
+primary owner, and upon which you need to do a lot of development.
+
+\section{The problem of many targets}
+
+The Linux kernel changes rapidly, and has never been internally
+stable; developers frequently make drastic changes between releases.
+This means that a version of the driver that works well with a
+particular released version of the kernel will not even \emph{compile}
+correctly against, typically, any other version.
+
+To maintain a driver, we have to keep a number of distinct versions of
+Linux in mind.
+\begin{itemize}
+\item One target is the main Linux kernel development tree.
+  Maintenance of the code is in this case partly shared by other
+  developers in the kernel community, who make ``drive-by''
+  modifications to the driver as they develop and refine kernel
+  subsystems.
+\item We also maintain a number of ``backports'' to older versions of
+  the Linux kernel, to support the needs of customers who are running
+  older Linux distributions that do not incorporate our drivers.  (To
+  \emph{backport} a piece of code is to modify it to work in an older
+  version of its target environment than the version it was developed
+  for.)
+\item Finally, we make software releases on a schedule that is
+  necessarily not aligned with those used by Linux distributors and
+  kernel developers, so that we can deliver new features to customers
+  without forcing them to upgrade their entire kernels or
+  distributions.
+\end{itemize}
+
+\subsection{Tempting approaches that don't work well}
+
+There are two ``standard'' ways to maintain a piece of software that
+has to target many different environments.
+
+The first is to maintain a number of branches, each intended for a
+single target.  The trouble with this approach is that you must
+maintain iron discipline in the flow of changes between repositories.
+A new feature or bug fix must start life in a ``pristine'' repository,
+then percolate out to every backport repository.  Backport changes are
+more limited in the branches they should propagate to; a backport
+change that is applied to a branch where it doesn't belong will
+probably stop the driver from compiling.
+
+The second is to maintain a single source tree filled with conditional
+statements that turn chunks of code on or off depending on the
+intended target.  Because these ``ifdefs'' are not allowed in the
+Linux kernel tree, a manual or automatic process must be followed to
+strip them out and yield a clean tree.  A code base maintained in this
+fashion rapidly becomes a rat's nest of conditional blocks that are
+difficult to understand and maintain.
+
+Neither of these approaches is well suited to a situation where you
+don't ``own'' the canonical copy of a source tree.  In the case of a
+Linux driver that is distributed with the standard kernel, Linus's
+tree contains the copy of the code that will be treated by the world
+as canonical.  The upstream version of ``my'' driver can be modified
+by people I don't know, without me even finding out about it until
+after the changes show up in Linus's tree.  
+
+These approaches have the added weakness of making it difficult to
+generate well-formed patches to submit upstream.
+
+In principle, Mercurial Queues seems like a good candidate to manage a
+development scenario such as the above.  While this is indeed the
+case, MQ contains a few added features that make the job more
+pleasant.
+
+\section{Conditionally applying patches with 
+  guards}
+
+Perhaps the best way to maintain sanity with so many targets is to be
+able to choose specific patches to apply for a given situation.  MQ
+provides a feature called ``guards'' (which originates with quilt's
+\texttt{guards} command) that does just this.  To start off, let's
+create a simple repository for experimenting in.
+\interaction{mq.guards.init}
+This gives us a tiny repository that contains two patches that don't
+have any dependencies on each other, because they touch different files.
+
+The idea behind conditional application is that you can ``tag'' a
+patch with a \emph{guard}, which is simply a text string of your
+choosing, then tell MQ to select specific guards to use when applying
+patches.  MQ will then either apply, or skip over, a guarded patch,
+depending on the guards that you have selected.
+
+A patch can have an arbitrary number of guards;
+each one is \emph{positive} (``apply this patch if this guard is
+selected'') or \emph{negative} (``skip this patch if this guard is
+selected'').  A patch with no guards is always applied.
+
+\section{Controlling the guards on a patch}
+
+The \hgxcmd{mq}{qguard} command lets you determine which guards should
+apply to a patch, or display the guards that are already in effect.
+Without any arguments, it displays the guards on the current topmost
+patch.
+\interaction{mq.guards.qguard}
+To set a positive guard on a patch, prefix the name of the guard with
+a ``\texttt{+}''.
+\interaction{mq.guards.qguard.pos}
+To set a negative guard on a patch, prefix the name of the guard with
+a ``\texttt{-}''.
+\interaction{mq.guards.qguard.neg}
+
+\begin{note}
+  The \hgxcmd{mq}{qguard} command \emph{sets} the guards on a patch; it
+  doesn't \emph{modify} them.  What this means is that if you run
+  \hgcmdargs{qguard}{+a +b} on a patch, then \hgcmdargs{qguard}{+c} on
+  the same patch, the \emph{only} guard that will be set on it
+  afterwards is \texttt{+c}.
+\end{note}
+
+Mercurial stores guards in the \sfilename{series} file; the form in
+which they are stored is easy both to understand and to edit by hand.
+(In other words, you don't have to use the \hgxcmd{mq}{qguard} command if
+you don't want to; it's okay to simply edit the \sfilename{series}
+file.)
+\interaction{mq.guards.series}
+
+\section{Selecting the guards to use}
+
+The \hgxcmd{mq}{qselect} command determines which guards are active at a
+given time.  The effect of this is to determine which patches MQ will
+apply the next time you run \hgxcmd{mq}{qpush}.  It has no other effect; in
+particular, it doesn't do anything to patches that are already
+applied.
+
+With no arguments, the \hgxcmd{mq}{qselect} command lists the guards
+currently in effect, one per line of output.  Each argument is treated
+as the name of a guard to apply.
+\interaction{mq.guards.qselect.foo}
+In case you're interested, the currently selected guards are stored in
+the \sfilename{guards} file.
+\interaction{mq.guards.qselect.cat}
+We can see the effect the selected guards have when we run
+\hgxcmd{mq}{qpush}.
+\interaction{mq.guards.qselect.qpush}
+
+A guard cannot start with a ``\texttt{+}'' or ``\texttt{-}''
+character.  The name of a guard must not contain white space, but most
+other characters are acceptable.  If you try to use a guard with an
+invalid name, MQ will complain:
+\interaction{mq.guards.qselect.error} 
+Changing the selected guards changes the patches that are applied.
+\interaction{mq.guards.qselect.quux} 
+You can see in the example below that negative guards take precedence
+over positive guards.
+\interaction{mq.guards.qselect.foobar}
+
+\section{MQ's rules for applying patches}
+
+The rules that MQ uses when deciding whether to apply a patch
+are as follows.
+\begin{itemize}
+\item A patch that has no guards is always applied.
+\item If the patch has any negative guard that matches any currently
+  selected guard, the patch is skipped.
+\item If the patch has any positive guard that matches any currently
+  selected guard, the patch is applied.
+\item If the patch has positive or negative guards, but none matches
+  any currently selected guard, the patch is skipped.
+\end{itemize}
+
+\section{Trimming the work environment}
+
+In working on the device driver I mentioned earlier, I don't apply the
+patches to a normal Linux kernel tree.  Instead, I use a repository
+that contains only a snapshot of the source files and headers that are
+relevant to Infiniband development.  This repository is~1\% the size
+of a kernel repository, so it's easier to work with.
+
+I then choose a ``base'' version on top of which the patches are
+applied.  This is a snapshot of the Linux kernel tree as of a revision
+of my choosing.  When I take the snapshot, I record the changeset ID
+from the kernel repository in the commit message.  Since the snapshot
+preserves the ``shape'' and content of the relevant parts of the
+kernel tree, I can apply my patches on top of either my tiny
+repository or a normal kernel tree.
+
+Normally, the base tree atop which the patches apply should be a
+snapshot of a very recent upstream tree.  This best facilitates the
+development of patches that can easily be submitted upstream with few
+or no modifications.
+
+\section{Dividing up the \sfilename{series} file}
+
+I categorise the patches in the \sfilename{series} file into a number
+of logical groups.  Each section of like patches begins with a block
+of comments that describes the purpose of the patches that follow.
+
+The sequence of patch groups that I maintain follows.  The ordering of
+these groups is important; I'll describe why after I introduce the
+groups.
+\begin{itemize}
+\item The ``accepted'' group.  Patches that the development team has
+  submitted to the maintainer of the Infiniband subsystem, and which
+  he has accepted, but which are not present in the snapshot that the
+  tiny repository is based on.  These are ``read only'' patches,
+  present only to transform the tree into a similar state as it is in
+  the upstream maintainer's repository.
+\item The ``rework'' group.  Patches that I have submitted, but that
+  the upstream maintainer has requested modifications to before he
+  will accept them.
+\item The ``pending'' group.  Patches that I have not yet submitted to
+  the upstream maintainer, but which we have finished working on.
+  These will be ``read only'' for a while.  If the upstream maintainer
+  accepts them upon submission, I'll move them to the end of the
+  ``accepted'' group.  If he requests that I modify any, I'll move
+  them to the beginning of the ``rework'' group.
+\item The ``in progress'' group.  Patches that are actively being
+  developed, and should not be submitted anywhere yet.
+\item The ``backport'' group.  Patches that adapt the source tree to
+  older versions of the kernel tree.
+\item The ``do not ship'' group.  Patches that for some reason should
+  never be submitted upstream.  For example, one such patch might
+  change embedded driver identification strings to make it easier to
+  distinguish, in the field, between an out-of-tree version of the
+  driver and a version shipped by a distribution vendor.
+\end{itemize}
+
+Now to return to the reasons for ordering groups of patches in this
+way.  We would like the lowest patches in the stack to be as stable as
+possible, so that we will not need to rework higher patches due to
+changes in context.  Putting patches that will never be changed first
+in the \sfilename{series} file serves this purpose.
+
+We would also like the patches that we know we'll need to modify to be
+applied on top of a source tree that resembles the upstream tree as
+closely as possible.  This is why we keep accepted patches around for
+a while.
+
+The ``backport'' and ``do not ship'' patches float at the end of the
+\sfilename{series} file.  The backport patches must be applied on top
+of all other patches, and the ``do not ship'' patches might as well
+stay out of harm's way.
+
+\section{Maintaining the patch series}
+
+In my work, I use a number of guards to control which patches are to
+be applied.
+
+\begin{itemize}
+\item ``Accepted'' patches are guarded with \texttt{accepted}.  I
+  enable this guard most of the time.  When I'm applying the patches
+  on top of a tree where the patches are already present, I can turn
+  this patch off, and the patches that follow it will apply cleanly.
+\item Patches that are ``finished'', but not yet submitted, have no
+  guards.  If I'm applying the patch stack to a copy of the upstream
+  tree, I don't need to enable any guards in order to get a reasonably
+  safe source tree.
+\item Those patches that need reworking before being resubmitted are
+  guarded with \texttt{rework}.
+\item For those patches that are still under development, I use
+  \texttt{devel}.
+\item A backport patch may have several guards, one for each version
+  of the kernel to which it applies.  For example, a patch that
+  backports a piece of code to~2.6.9 will have a~\texttt{2.6.9} guard.
+\end{itemize}
+This variety of guards gives me considerable flexibility in
+qdetermining what kind of source tree I want to end up with.  For most
+situations, the selection of appropriate guards is automated during
+the build process, but I can manually tune the guards to use for less
+common circumstances.
+
+\subsection{The art of writing backport patches}
+
+Using MQ, writing a backport patch is a simple process.  All such a
+patch has to do is modify a piece of code that uses a kernel feature
+not present in the older version of the kernel, so that the driver
+continues to work correctly under that older version.
+
+A useful goal when writing a good backport patch is to make your code
+look as if it was written for the older version of the kernel you're
+targeting.  The less obtrusive the patch, the easier it will be to
+understand and maintain.  If you're writing a collection of backport
+patches to avoid the ``rat's nest'' effect of lots of
+\texttt{\#ifdef}s (hunks of source code that are only used
+conditionally) in your code, don't introduce version-dependent
+\texttt{\#ifdef}s into the patches.  Instead, write several patches,
+each of which makes unconditional changes, and control their
+application using guards.
+
+There are two reasons to divide backport patches into a distinct
+group, away from the ``regular'' patches whose effects they modify.
+The first is that intermingling the two makes it more difficult to use
+a tool like the \hgext{patchbomb} extension to automate the process of
+submitting the patches to an upstream maintainer.  The second is that
+a backport patch could perturb the context in which a subsequent
+regular patch is applied, making it impossible to apply the regular
+patch cleanly \emph{without} the earlier backport patch already being
+applied.
+
+\section{Useful tips for developing with MQ}
+
+\subsection{Organising patches in directories}
+
+If you're working on a substantial project with MQ, it's not difficult
+to accumulate a large number of patches.  For example, I have one
+patch repository that contains over 250 patches.
+
+If you can group these patches into separate logical categories, you
+can if you like store them in different directories; MQ has no
+problems with patch names that contain path separators.
+
+\subsection{Viewing the history of a patch}
+\label{mq-collab:tips:interdiff}
+
+If you're developing a set of patches over a long time, it's a good
+idea to maintain them in a repository, as discussed in
+section~\ref{sec:mq:repo}.  If you do so, you'll quickly discover that
+using the \hgcmd{diff} command to look at the history of changes to a
+patch is unworkable.  This is in part because you're looking at the
+second derivative of the real code (a diff of a diff), but also
+because MQ adds noise to the process by modifying time stamps and
+directory names when it updates a patch.
+
+However, you can use the \hgext{extdiff} extension, which is bundled
+with Mercurial, to turn a diff of two versions of a patch into
+something readable.  To do this, you will need a third-party package
+called \package{patchutils}~\cite{web:patchutils}.  This provides a
+command named \command{interdiff}, which shows the differences between
+two diffs as a diff.  Used on two versions of the same diff, it
+generates a diff that represents the diff from the first to the second
+version.
+
+You can enable the \hgext{extdiff} extension in the usual way, by
+adding a line to the \rcsection{extensions} section of your \hgrc.
+\begin{codesample2}
+  [extensions]
+  extdiff =
+\end{codesample2}
+The \command{interdiff} command expects to be passed the names of two
+files, but the \hgext{extdiff} extension passes the program it runs a
+pair of directories, each of which can contain an arbitrary number of
+files.  We thus need a small program that will run \command{interdiff}
+on each pair of files in these two directories.  This program is
+available as \sfilename{hg-interdiff} in the \dirname{examples}
+directory of the source code repository that accompanies this book.
+\excode{hg-interdiff}
+
+With the \sfilename{hg-interdiff} program in your shell's search path,
+you can run it as follows, from inside an MQ patch directory:
+\begin{codesample2}
+  hg extdiff -p hg-interdiff -r A:B my-change.patch
+\end{codesample2}
+Since you'll probably want to use this long-winded command a lot, you
+can get \hgext{hgext} to make it available as a normal Mercurial
+command, again by editing your \hgrc.
+\begin{codesample2}
+  [extdiff]
+  cmd.interdiff = hg-interdiff
+\end{codesample2}
+This directs \hgext{hgext} to make an \texttt{interdiff} command
+available, so you can now shorten the previous invocation of
+\hgxcmd{extdiff}{extdiff} to something a little more wieldy.
+\begin{codesample2}
+  hg interdiff -r A:B my-change.patch
+\end{codesample2}
+
+\begin{note}
+  The \command{interdiff} command works well only if the underlying
+  files against which versions of a patch are generated remain the
+  same.  If you create a patch, modify the underlying files, and then
+  regenerate the patch, \command{interdiff} may not produce useful
+  output.
+\end{note}
+
+The \hgext{extdiff} extension is useful for more than merely improving
+the presentation of MQ~patches.  To read more about it, go to
+section~\ref{sec:hgext:extdiff}.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- a/es/mq-ref.tex	Sat Oct 18 14:35:43 2008 -0500
+++ b/es/mq-ref.tex	Sat Oct 18 15:44:41 2008 -0500
@@ -0,0 +1,349 @@
+\chapter{Mercurial Queues reference}
+\label{chap:mqref}
+
+\section{MQ command reference}
+\label{sec:mqref:cmdref}
+
+For an overview of the commands provided by MQ, use the command
+\hgcmdargs{help}{mq}.
+
+\subsection{\hgxcmd{mq}{qapplied}---print applied patches}
+
+The \hgxcmd{mq}{qapplied} command prints the current stack of applied
+patches.  Patches are printed in oldest-to-newest order, so the last
+patch in the list is the ``top'' patch.
+
+\subsection{\hgxcmd{mq}{qcommit}---commit changes in the queue repository}
+
+The \hgxcmd{mq}{qcommit} command commits any outstanding changes in the
+\sdirname{.hg/patches} repository.  This command only works if the
+\sdirname{.hg/patches} directory is a repository, i.e.~you created the
+directory using \hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} or ran
+\hgcmd{init} in the directory after running \hgxcmd{mq}{qinit}.
+
+This command is shorthand for \hgcmdargs{commit}{--cwd .hg/patches}.
+
+\subsection{\hgxcmd{mq}{qdelete}---delete a patch from the
+  \sfilename{series} file}
+
+The \hgxcmd{mq}{qdelete} command removes the entry for a patch from the
+\sfilename{series} file in the \sdirname{.hg/patches} directory.  It
+does not pop the patch if the patch is already applied.  By default,
+it does not delete the patch file; use the \hgxopt{mq}{qdel}{-f} option to
+do that.
+
+Options:
+\begin{itemize}
+\item[\hgxopt{mq}{qdel}{-f}] Delete the patch file.
+\end{itemize}
+
+\subsection{\hgxcmd{mq}{qdiff}---print a diff of the topmost applied patch}
+
+The \hgxcmd{mq}{qdiff} command prints a diff of the topmost applied patch.
+It is equivalent to \hgcmdargs{diff}{-r-2:-1}.
+
+\subsection{\hgxcmd{mq}{qfold}---merge (``fold'') several patches into one}
+
+The \hgxcmd{mq}{qfold} command merges multiple patches into the topmost
+applied patch, so that the topmost applied patch makes the union of
+all of the changes in the patches in question.
+
+The patches to fold must not be applied; \hgxcmd{mq}{qfold} will exit with
+an error if any is.  The order in which patches are folded is
+significant; \hgcmdargs{qfold}{a b} means ``apply the current topmost
+patch, followed by \texttt{a}, followed by \texttt{b}''.
+
+The comments from the folded patches are appended to the comments of
+the destination patch, with each block of comments separated by three
+asterisk (``\texttt{*}'') characters.  Use the \hgxopt{mq}{qfold}{-e}
+option to edit the commit message for the combined patch/changeset
+after the folding has completed.
+
+Options:
+\begin{itemize}
+\item[\hgxopt{mq}{qfold}{-e}] Edit the commit message and patch description
+  for the newly folded patch.
+\item[\hgxopt{mq}{qfold}{-l}] Use the contents of the given file as the new
+  commit message and patch description for the folded patch.
+\item[\hgxopt{mq}{qfold}{-m}] Use the given text as the new commit message
+  and patch description for the folded patch.
+\end{itemize}
+
+\subsection{\hgxcmd{mq}{qheader}---display the header/description of a patch}
+
+The \hgxcmd{mq}{qheader} command prints the header, or description, of a
+patch.  By default, it prints the header of the topmost applied patch.
+Given an argument, it prints the header of the named patch.
+
+\subsection{\hgxcmd{mq}{qimport}---import a third-party patch into the queue}
+
+The \hgxcmd{mq}{qimport} command adds an entry for an external patch to the
+\sfilename{series} file, and copies the patch into the
+\sdirname{.hg/patches} directory.  It adds the entry immediately after
+the topmost applied patch, but does not push the patch.
+
+If the \sdirname{.hg/patches} directory is a repository,
+\hgxcmd{mq}{qimport} automatically does an \hgcmd{add} of the imported
+patch.
+
+\subsection{\hgxcmd{mq}{qinit}---prepare a repository to work with MQ}
+
+The \hgxcmd{mq}{qinit} command prepares a repository to work with MQ.  It
+creates a directory called \sdirname{.hg/patches}.
+
+Options:
+\begin{itemize}
+\item[\hgxopt{mq}{qinit}{-c}] Create \sdirname{.hg/patches} as a repository
+  in its own right.  Also creates a \sfilename{.hgignore} file that
+  will ignore the \sfilename{status} file.
+\end{itemize}
+
+When the \sdirname{.hg/patches} directory is a repository, the
+\hgxcmd{mq}{qimport} and \hgxcmd{mq}{qnew} commands automatically \hgcmd{add}
+new patches.
+
+\subsection{\hgxcmd{mq}{qnew}---create a new patch}
+
+The \hgxcmd{mq}{qnew} command creates a new patch.  It takes one mandatory
+argument, the name to use for the patch file.  The newly created patch
+is created empty by default.  It is added to the \sfilename{series}
+file after the current topmost applied patch, and is immediately
+pushed on top of that patch.
+
+If \hgxcmd{mq}{qnew} finds modified files in the working directory, it will
+refuse to create a new patch unless the \hgxopt{mq}{qnew}{-f} option is
+used (see below).  This behaviour allows you to \hgxcmd{mq}{qrefresh} your
+topmost applied patch before you apply a new patch on top of it.
+
+Options:
+\begin{itemize}
+\item[\hgxopt{mq}{qnew}{-f}] Create a new patch if the contents of the
+  working directory are modified.  Any outstanding modifications are
+  added to the newly created patch, so after this command completes,
+  the working directory will no longer be modified.
+\item[\hgxopt{mq}{qnew}{-m}] Use the given text as the commit message.
+  This text will be stored at the beginning of the patch file, before
+  the patch data.
+\end{itemize}
+
+\subsection{\hgxcmd{mq}{qnext}---print the name of the next patch}
+
+The \hgxcmd{mq}{qnext} command prints the name name of the next patch in
+the \sfilename{series} file after the topmost applied patch.  This
+patch will become the topmost applied patch if you run \hgxcmd{mq}{qpush}.
+
+\subsection{\hgxcmd{mq}{qpop}---pop patches off the stack}
+
+The \hgxcmd{mq}{qpop} command removes applied patches from the top of the
+stack of applied patches.  By default, it removes only one patch.
+
+This command removes the changesets that represent the popped patches
+from the repository, and updates the working directory to undo the
+effects of the patches.
+
+This command takes an optional argument, which it uses as the name or
+index of the patch to pop to.  If given a name, it will pop patches
+until the named patch is the topmost applied patch.  If given a
+number, \hgxcmd{mq}{qpop} treats the number as an index into the entries in
+the series file, counting from zero (empty lines and lines containing
+only comments do not count).  It pops patches until the patch
+identified by the given index is the topmost applied patch.
+
+The \hgxcmd{mq}{qpop} command does not read or write patches or the
+\sfilename{series} file.  It is thus safe to \hgxcmd{mq}{qpop} a patch that
+you have removed from the \sfilename{series} file, or a patch that you
+have renamed or deleted entirely.  In the latter two cases, use the
+name of the patch as it was when you applied it.
+
+By default, the \hgxcmd{mq}{qpop} command will not pop any patches if the
+working directory has been modified.  You can override this behaviour
+using the \hgxopt{mq}{qpop}{-f} option, which reverts all modifications in
+the working directory.
+
+Options:
+\begin{itemize}
+\item[\hgxopt{mq}{qpop}{-a}] Pop all applied patches.  This returns the
+  repository to its state before you applied any patches.
+\item[\hgxopt{mq}{qpop}{-f}] Forcibly revert any modifications to the
+  working directory when popping.
+\item[\hgxopt{mq}{qpop}{-n}] Pop a patch from the named queue.
+\end{itemize}
+
+The \hgxcmd{mq}{qpop} command removes one line from the end of the
+\sfilename{status} file for each patch that it pops.
+
+\subsection{\hgxcmd{mq}{qprev}---print the name of the previous patch}
+
+The \hgxcmd{mq}{qprev} command prints the name of the patch in the
+\sfilename{series} file that comes before the topmost applied patch.
+This will become the topmost applied patch if you run \hgxcmd{mq}{qpop}.
+
+\subsection{\hgxcmd{mq}{qpush}---push patches onto the stack}
+\label{sec:mqref:cmd:qpush}
+
+The \hgxcmd{mq}{qpush} command adds patches onto the applied stack.  By
+default, it adds only one patch.
+
+This command creates a new changeset to represent each applied patch,
+and updates the working directory to apply the effects of the patches.
+
+The default data used when creating a changeset are as follows:
+\begin{itemize}
+\item The commit date and time zone are the current date and time
+  zone.  Because these data are used to compute the identity of a
+  changeset, this means that if you \hgxcmd{mq}{qpop} a patch and
+  \hgxcmd{mq}{qpush} it again, the changeset that you push will have a
+  different identity than the changeset you popped.
+\item The author is the same as the default used by the \hgcmd{commit}
+  command.
+\item The commit message is any text from the patch file that comes
+  before the first diff header.  If there is no such text, a default
+  commit message is used that identifies the name of the patch.
+\end{itemize}
+If a patch contains a Mercurial patch header (XXX add link), the
+information in the patch header overrides these defaults.
+
+Options:
+\begin{itemize}
+\item[\hgxopt{mq}{qpush}{-a}] Push all unapplied patches from the
+  \sfilename{series} file until there are none left to push.
+\item[\hgxopt{mq}{qpush}{-l}] Add the name of the patch to the end
+  of the commit message.
+\item[\hgxopt{mq}{qpush}{-m}] If a patch fails to apply cleanly, use the
+  entry for the patch in another saved queue to compute the parameters
+  for a three-way merge, and perform a three-way merge using the
+  normal Mercurial merge machinery.  Use the resolution of the merge
+  as the new patch content.
+\item[\hgxopt{mq}{qpush}{-n}] Use the named queue if merging while pushing.
+\end{itemize}
+
+The \hgxcmd{mq}{qpush} command reads, but does not modify, the
+\sfilename{series} file.  It appends one line to the \hgcmd{status}
+file for each patch that it pushes.
+
+\subsection{\hgxcmd{mq}{qrefresh}---update the topmost applied patch}
+
+The \hgxcmd{mq}{qrefresh} command updates the topmost applied patch.  It
+modifies the patch, removes the old changeset that represented the
+patch, and creates a new changeset to represent the modified patch.
+
+The \hgxcmd{mq}{qrefresh} command looks for the following modifications:
+\begin{itemize}
+\item Changes to the commit message, i.e.~the text before the first
+  diff header in the patch file, are reflected in the new changeset
+  that represents the patch.
+\item Modifications to tracked files in the working directory are
+  added to the patch.
+\item Changes to the files tracked using \hgcmd{add}, \hgcmd{copy},
+  \hgcmd{remove}, or \hgcmd{rename}.  Added files and copy and rename
+  destinations are added to the patch, while removed files and rename
+  sources are removed.
+\end{itemize}
+
+Even if \hgxcmd{mq}{qrefresh} detects no changes, it still recreates the
+changeset that represents the patch.  This causes the identity of the
+changeset to differ from the previous changeset that identified the
+patch.
+
+Options:
+\begin{itemize}
+\item[\hgxopt{mq}{qrefresh}{-e}] Modify the commit and patch description,
+  using the preferred text editor.
+\item[\hgxopt{mq}{qrefresh}{-m}] Modify the commit message and patch
+  description, using the given text.
+\item[\hgxopt{mq}{qrefresh}{-l}] Modify the commit message and patch
+  description, using text from the given file.
+\end{itemize}
+
+\subsection{\hgxcmd{mq}{qrename}---rename a patch}
+
+The \hgxcmd{mq}{qrename} command renames a patch, and changes the entry for
+the patch in the \sfilename{series} file.
+
+With a single argument, \hgxcmd{mq}{qrename} renames the topmost applied
+patch.  With two arguments, it renames its first argument to its
+second.
+
+\subsection{\hgxcmd{mq}{qrestore}---restore saved queue state}
+
+XXX No idea what this does.
+
+\subsection{\hgxcmd{mq}{qsave}---save current queue state}
+
+XXX Likewise.
+
+\subsection{\hgxcmd{mq}{qseries}---print the entire patch series}
+
+The \hgxcmd{mq}{qseries} command prints the entire patch series from the
+\sfilename{series} file.  It prints only patch names, not empty lines
+or comments.  It prints in order from first to be applied to last.
+
+\subsection{\hgxcmd{mq}{qtop}---print the name of the current patch}
+
+The \hgxcmd{mq}{qtop} prints the name of the topmost currently applied
+patch.
+
+\subsection{\hgxcmd{mq}{qunapplied}---print patches not yet applied}
+
+The \hgxcmd{mq}{qunapplied} command prints the names of patches from the
+\sfilename{series} file that are not yet applied.  It prints them in
+order from the next patch that will be pushed to the last.
+
+\subsection{\hgcmd{strip}---remove a revision and descendants}
+
+The \hgcmd{strip} command removes a revision, and all of its
+descendants, from the repository.  It undoes the effects of the
+removed revisions from the repository, and updates the working
+directory to the first parent of the removed revision.
+
+The \hgcmd{strip} command saves a backup of the removed changesets in
+a bundle, so that they can be reapplied if removed in error.
+
+Options:
+\begin{itemize}
+\item[\hgopt{strip}{-b}] Save unrelated changesets that are intermixed
+  with the stripped changesets in the backup bundle.
+\item[\hgopt{strip}{-f}] If a branch has multiple heads, remove all
+  heads. XXX This should be renamed, and use \texttt{-f} to strip revs
+  when there are pending changes.
+\item[\hgopt{strip}{-n}] Do not save a backup bundle.
+\end{itemize}
+
+\section{MQ file reference}
+
+\subsection{The \sfilename{series} file}
+
+The \sfilename{series} file contains a list of the names of all
+patches that MQ can apply.  It is represented as a list of names, with
+one name saved per line.  Leading and trailing white space in each
+line are ignored.
+
+Lines may contain comments.  A comment begins with the ``\texttt{\#}''
+character, and extends to the end of the line.  Empty lines, and lines
+that contain only comments, are ignored.
+
+You will often need to edit the \sfilename{series} file by hand, hence
+the support for comments and empty lines noted above.  For example,
+you can comment out a patch temporarily, and \hgxcmd{mq}{qpush} will skip
+over that patch when applying patches.  You can also change the order
+in which patches are applied by reordering their entries in the
+\sfilename{series} file.
+
+Placing the \sfilename{series} file under revision control is also
+supported; it is a good idea to place all of the patches that it
+refers to under revision control, as well.  If you create a patch
+directory using the \hgxopt{mq}{qinit}{-c} option to \hgxcmd{mq}{qinit}, this
+will be done for you automatically.
+
+\subsection{The \sfilename{status} file}
+
+The \sfilename{status} file contains the names and changeset hashes of
+all patches that MQ currently has applied.  Unlike the
+\sfilename{series} file, this file is not intended for editing.  You
+should not place this file under revision control, or modify it in any
+way.  It is used by MQ strictly for internal book-keeping.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- a/es/mq.tex	Sat Oct 18 14:35:43 2008 -0500
+++ b/es/mq.tex	Sat Oct 18 15:44:41 2008 -0500
@@ -0,0 +1,1043 @@
+\chapter{Managing change with Mercurial Queues}
+\label{chap:mq}
+
+\section{The patch management problem}
+\label{sec:mq:patch-mgmt}
+
+Here is a common scenario: you need to install a software package from
+source, but you find a bug that you must fix in the source before you
+can start using the package.  You make your changes, forget about the
+package for a while, and a few months later you need to upgrade to a
+newer version of the package.  If the newer version of the package
+still has the bug, you must extract your fix from the older source
+tree and apply it against the newer version.  This is a tedious task,
+and it's easy to make mistakes.
+
+This is a simple case of the ``patch management'' problem.  You have
+an ``upstream'' source tree that you can't change; you need to make
+some local changes on top of the upstream tree; and you'd like to be
+able to keep those changes separate, so that you can apply them to
+newer versions of the upstream source.
+
+The patch management problem arises in many situations.  Probably the
+most visible is that a user of an open source software project will
+contribute a bug fix or new feature to the project's maintainers in the
+form of a patch.
+
+Distributors of operating systems that include open source software
+often need to make changes to the packages they distribute so that
+they will build properly in their environments.
+
+When you have few changes to maintain, it is easy to manage a single
+patch using the standard \command{diff} and \command{patch} programs
+(see section~\ref{sec:mq:patch} for a discussion of these tools).
+Once the number of changes grows, it starts to make sense to maintain
+patches as discrete ``chunks of work,'' so that for example a single
+patch will contain only one bug fix (the patch might modify several
+files, but it's doing ``only one thing''), and you may have a number
+of such patches for different bugs you need fixed and local changes
+you require.  In this situation, if you submit a bug fix patch to the
+upstream maintainers of a package and they include your fix in a
+subsequent release, you can simply drop that single patch when you're
+updating to the newer release.
+
+Maintaining a single patch against an upstream tree is a little
+tedious and error-prone, but not difficult.  However, the complexity
+of the problem grows rapidly as the number of patches you have to
+maintain increases.  With more than a tiny number of patches in hand,
+understanding which ones you have applied and maintaining them moves
+from messy to overwhelming.
+
+Fortunately, Mercurial includes a powerful extension, Mercurial Queues
+(or simply ``MQ''), that massively simplifies the patch management
+problem.
+
+\section{The prehistory of Mercurial Queues}
+\label{sec:mq:history}
+
+During the late 1990s, several Linux kernel developers started to
+maintain ``patch series'' that modified the behaviour of the Linux
+kernel.  Some of these series were focused on stability, some on
+feature coverage, and others were more speculative.
+
+The sizes of these patch series grew rapidly.  In 2002, Andrew Morton
+published some shell scripts he had been using to automate the task of
+managing his patch queues.  Andrew was successfully using these
+scripts to manage hundreds (sometimes thousands) of patches on top of
+the Linux kernel.
+
+\subsection{A patchwork quilt}
+\label{sec:mq:quilt}
+
+In early 2003, Andreas Gruenbacher and Martin Quinson borrowed the
+approach of Andrew's scripts and published a tool called ``patchwork
+quilt''~\cite{web:quilt}, or simply ``quilt''
+(see~\cite{gruenbacher:2005} for a paper describing it).  Because
+quilt substantially automated patch management, it rapidly gained a
+large following among open source software developers.
+
+Quilt manages a \emph{stack of patches} on top of a directory tree.
+To begin, you tell quilt to manage a directory tree, and tell it which
+files you want to manage; it stores away the names and contents of
+those files.  To fix a bug, you create a new patch (using a single
+command), edit the files you need to fix, then ``refresh'' the patch.
+
+The refresh step causes quilt to scan the directory tree; it updates
+the patch with all of the changes you have made.  You can create
+another patch on top of the first, which will track the changes
+required to modify the tree from ``tree with one patch applied'' to
+``tree with two patches applied''.
+
+You can \emph{change} which patches are applied to the tree.  If you
+``pop'' a patch, the changes made by that patch will vanish from the
+directory tree.  Quilt remembers which patches you have popped,
+though, so you can ``push'' a popped patch again, and the directory
+tree will be restored to contain the modifications in the patch.  Most
+importantly, you can run the ``refresh'' command at any time, and the
+topmost applied patch will be updated.  This means that you can, at
+any time, change both which patches are applied and what
+modifications those patches make.
+
+Quilt knows nothing about revision control tools, so it works equally
+well on top of an unpacked tarball or a Subversion working copy.
+
+\subsection{From patchwork quilt to Mercurial Queues}
+\label{sec:mq:quilt-mq}
+
+In mid-2005, Chris Mason took the features of quilt and wrote an
+extension that he called Mercurial Queues, which added quilt-like
+behaviour to Mercurial.
+
+The key difference between quilt and MQ is that quilt knows nothing
+about revision control systems, while MQ is \emph{integrated} into
+Mercurial.  Each patch that you push is represented as a Mercurial
+changeset.  Pop a patch, and the changeset goes away.
+
+Because quilt does not care about revision control tools, it is still
+a tremendously useful piece of software to know about for situations
+where you cannot use Mercurial and MQ.
+
+\section{The huge advantage of MQ}
+
+I cannot overstate the value that MQ offers through the unification of
+patches and revision control.
+
+A major reason that patches have persisted in the free software and
+open source world---in spite of the availability of increasingly
+capable revision control tools over the years---is the \emph{agility}
+they offer.  
+
+Traditional revision control tools make a permanent, irreversible
+record of everything that you do.  While this has great value, it's
+also somewhat stifling.  If you want to perform a wild-eyed
+experiment, you have to be careful in how you go about it, or you risk
+leaving unneeded---or worse, misleading or destabilising---traces of
+your missteps and errors in the permanent revision record.
+
+By contrast, MQ's marriage of distributed revision control with
+patches makes it much easier to isolate your work.  Your patches live
+on top of normal revision history, and you can make them disappear or
+reappear at will.  If you don't like a patch, you can drop it.  If a
+patch isn't quite as you want it to be, simply fix it---as many times
+as you need to, until you have refined it into the form you desire.
+
+As an example, the integration of patches with revision control makes
+understanding patches and debugging their effects---and their
+interplay with the code they're based on---\emph{enormously} easier.
+Since every applied patch has an associated changeset, you can use
+\hgcmdargs{log}{\emph{filename}} to see which changesets and patches
+affected a file.  You can use the \hgext{bisect} command to
+binary-search through all changesets and applied patches to see where
+a bug got introduced or fixed.  You can use the \hgcmd{annotate}
+command to see which changeset or patch modified a particular line of
+a source file.  And so on.
+
+\section{Understanding patches}
+\label{sec:mq:patch}
+
+Because MQ doesn't hide its patch-oriented nature, it is helpful to
+understand what patches are, and a little about the tools that work
+with them.
+
+The traditional Unix \command{diff} command compares two files, and
+prints a list of differences between them. The \command{patch} command
+understands these differences as \emph{modifications} to make to a
+file.  Take a look at figure~\ref{ex:mq:diff} for a simple example of
+these commands in action.
+
+\begin{figure}[ht]
+  \interaction{mq.dodiff.diff}
+  \caption{Simple uses of the \command{diff} and \command{patch} commands}
+  \label{ex:mq:diff}
+\end{figure}
+
+The type of file that \command{diff} generates (and \command{patch}
+takes as input) is called a ``patch'' or a ``diff''; there is no
+difference between a patch and a diff.  (We'll use the term ``patch'',
+since it's more commonly used.)
+
+A patch file can start with arbitrary text; the \command{patch}
+command ignores this text, but MQ uses it as the commit message when
+creating changesets.  To find the beginning of the patch content,
+\command{patch} searches for the first line that starts with the
+string ``\texttt{diff~-}''.
+
+MQ works with \emph{unified} diffs (\command{patch} can accept several
+other diff formats, but MQ doesn't).  A unified diff contains two
+kinds of header.  The \emph{file header} describes the file being
+modified; it contains the name of the file to modify.  When
+\command{patch} sees a new file header, it looks for a file with that
+name to start modifying.
+
+After the file header comes a series of \emph{hunks}.  Each hunk
+starts with a header; this identifies the range of line numbers within
+the file that the hunk should modify.  Following the header, a hunk
+starts and ends with a few (usually three) lines of text from the
+unmodified file; these are called the \emph{context} for the hunk.  If
+there's only a small amount of context between successive hunks,
+\command{diff} doesn't print a new hunk header; it just runs the hunks
+together, with a few lines of context between modifications.
+
+Each line of context begins with a space character.  Within the hunk,
+a line that begins with ``\texttt{-}'' means ``remove this line,''
+while a line that begins with ``\texttt{+}'' means ``insert this
+line.''  For example, a line that is modified is represented by one
+deletion and one insertion.
+
+We will return to some of the more subtle aspects of patches later (in
+section~\ref{sec:mq:adv-patch}), but you should have enough information
+now to use MQ.
+
+\section{Getting started with Mercurial Queues}
+\label{sec:mq:start}
+
+Because MQ is implemented as an extension, you must explicitly enable
+before you can use it.  (You don't need to download anything; MQ ships
+with the standard Mercurial distribution.)  To enable MQ, edit your
+\tildefile{.hgrc} file, and add the lines in figure~\ref{ex:mq:config}.
+
+\begin{figure}[ht]
+  \begin{codesample4}
+    [extensions]
+    hgext.mq =
+  \end{codesample4}
+  \label{ex:mq:config}
+  \caption{Contents to add to \tildefile{.hgrc} to enable the MQ extension}
+\end{figure}
+
+Once the extension is enabled, it will make a number of new commands
+available.  To verify that the extension is working, you can use
+\hgcmd{help} to see if the \hgxcmd{mq}{qinit} command is now available; see
+the example in figure~\ref{ex:mq:enabled}.
+
+\begin{figure}[ht]
+  \interaction{mq.qinit-help.help}
+  \caption{How to verify that MQ is enabled}
+  \label{ex:mq:enabled}
+\end{figure}
+
+You can use MQ with \emph{any} Mercurial repository, and its commands
+only operate within that repository.  To get started, simply prepare
+the repository using the \hgxcmd{mq}{qinit} command (see
+figure~\ref{ex:mq:qinit}).  This command creates an empty directory
+called \sdirname{.hg/patches}, where MQ will keep its metadata.  As
+with many Mercurial commands, the \hgxcmd{mq}{qinit} command prints nothing
+if it succeeds.
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qinit}
+  \caption{Preparing a repository for use with MQ}
+  \label{ex:mq:qinit}
+\end{figure}
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qnew}
+  \caption{Creating a new patch}
+  \label{ex:mq:qnew}
+\end{figure}
+
+\subsection{Creating a new patch}
+
+To begin work on a new patch, use the \hgxcmd{mq}{qnew} command.  This
+command takes one argument, the name of the patch to create.  MQ will
+use this as the name of an actual file in the \sdirname{.hg/patches}
+directory, as you can see in figure~\ref{ex:mq:qnew}.
+
+Also newly present in the \sdirname{.hg/patches} directory are two
+other files, \sfilename{series} and \sfilename{status}.  The
+\sfilename{series} file lists all of the patches that MQ knows about
+for this repository, with one patch per line.  Mercurial uses the
+\sfilename{status} file for internal book-keeping; it tracks all of the
+patches that MQ has \emph{applied} in this repository.
+
+\begin{note}
+  You may sometimes want to edit the \sfilename{series} file by hand;
+  for example, to change the sequence in which some patches are
+  applied.  However, manually editing the \sfilename{status} file is
+  almost always a bad idea, as it's easy to corrupt MQ's idea of what
+  is happening.
+\end{note}
+
+Once you have created your new patch, you can edit files in the
+working directory as you usually would.  All of the normal Mercurial
+commands, such as \hgcmd{diff} and \hgcmd{annotate}, work exactly as
+they did before.
+
+\subsection{Refreshing a patch}
+
+When you reach a point where you want to save your work, use the
+\hgxcmd{mq}{qrefresh} command (figure~\ref{ex:mq:qnew}) to update the patch
+you are working on.  This command folds the changes you have made in
+the working directory into your patch, and updates its corresponding
+changeset to contain those changes.
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qrefresh}
+  \caption{Refreshing a patch}
+  \label{ex:mq:qrefresh}
+\end{figure}
+
+You can run \hgxcmd{mq}{qrefresh} as often as you like, so it's a good way
+to ``checkpoint'' your work.  Refresh your patch at an opportune
+time; try an experiment; and if the experiment doesn't work out,
+\hgcmd{revert} your modifications back to the last time you refreshed.
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qrefresh2}
+  \caption{Refresh a patch many times to accumulate changes}
+  \label{ex:mq:qrefresh2}
+\end{figure}
+
+\subsection{Stacking and tracking patches}
+
+Once you have finished working on a patch, or need to work on another,
+you can use the \hgxcmd{mq}{qnew} command again to create a new patch.
+Mercurial will apply this patch on top of your existing patch.  See
+figure~\ref{ex:mq:qnew2} for an example.  Notice that the patch
+contains the changes in our prior patch as part of its context (you
+can see this more clearly in the output of \hgcmd{annotate}).
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qnew2}
+  \caption{Stacking a second patch on top of the first}
+  \label{ex:mq:qnew2}
+\end{figure}
+
+So far, with the exception of \hgxcmd{mq}{qnew} and \hgxcmd{mq}{qrefresh}, we've
+been careful to only use regular Mercurial commands.  However, MQ
+provides many commands that are easier to use when you are thinking
+about patches, as illustrated in figure~\ref{ex:mq:qseries}:
+
+\begin{itemize}
+\item The \hgxcmd{mq}{qseries} command lists every patch that MQ knows
+  about in this repository, from oldest to newest (most recently
+  \emph{created}).
+\item The \hgxcmd{mq}{qapplied} command lists every patch that MQ has
+  \emph{applied} in this repository, again from oldest to newest (most
+  recently applied).
+\end{itemize}
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qseries}
+  \caption{Understanding the patch stack with \hgxcmd{mq}{qseries} and
+    \hgxcmd{mq}{qapplied}}
+  \label{ex:mq:qseries}
+\end{figure}
+
+\subsection{Manipulating the patch stack}
+
+The previous discussion implied that there must be a difference
+between ``known'' and ``applied'' patches, and there is.  MQ can
+manage a patch without it being applied in the repository.
+
+An \emph{applied} patch has a corresponding changeset in the
+repository, and the effects of the patch and changeset are visible in
+the working directory.  You can undo the application of a patch using
+the \hgxcmd{mq}{qpop} command.  MQ still \emph{knows about}, or manages, a
+popped patch, but the patch no longer has a corresponding changeset in
+the repository, and the working directory does not contain the changes
+made by the patch.  Figure~\ref{fig:mq:stack} illustrates the
+difference between applied and tracked patches.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{mq-stack}
+  \caption{Applied and unapplied patches in the MQ patch stack}
+  \label{fig:mq:stack}
+\end{figure}
+
+You can reapply an unapplied, or popped, patch using the \hgxcmd{mq}{qpush}
+command.  This creates a new changeset to correspond to the patch, and
+the patch's changes once again become present in the working
+directory.  See figure~\ref{ex:mq:qpop} for examples of \hgxcmd{mq}{qpop}
+and \hgxcmd{mq}{qpush} in action.  Notice that once we have popped a patch
+or two patches, the output of \hgxcmd{mq}{qseries} remains the same, while
+that of \hgxcmd{mq}{qapplied} has changed.
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qpop}
+  \caption{Modifying the stack of applied patches}
+  \label{ex:mq:qpop}
+\end{figure}
+
+\subsection{Pushing and popping many patches}
+
+While \hgxcmd{mq}{qpush} and \hgxcmd{mq}{qpop} each operate on a single patch at
+a time by default, you can push and pop many patches in one go.  The
+\hgxopt{mq}{qpush}{-a} option to \hgxcmd{mq}{qpush} causes it to push all
+unapplied patches, while the \hgxopt{mq}{qpop}{-a} option to \hgxcmd{mq}{qpop}
+causes it to pop all applied patches.  (For some more ways to push and
+pop many patches, see section~\ref{sec:mq:perf} below.)
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qpush-a}
+  \caption{Pushing all unapplied patches}
+  \label{ex:mq:qpush-a}
+\end{figure}
+
+\subsection{Safety checks, and overriding them}
+
+Several MQ commands check the working directory before they do
+anything, and fail if they find any modifications.  They do this to
+ensure that you won't lose any changes that you have made, but not yet
+incorporated into a patch.  Figure~\ref{ex:mq:add} illustrates this;
+the \hgxcmd{mq}{qnew} command will not create a new patch if there are
+outstanding changes, caused in this case by the \hgcmd{add} of
+\filename{file3}.
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.add}
+  \caption{Forcibly creating a patch}
+  \label{ex:mq:add}
+\end{figure}
+
+Commands that check the working directory all take an ``I know what
+I'm doing'' option, which is always named \option{-f}.  The exact
+meaning of \option{-f} depends on the command.  For example,
+\hgcmdargs{qnew}{\hgxopt{mq}{qnew}{-f}} will incorporate any outstanding
+changes into the new patch it creates, but
+\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-f}} will revert modifications to any
+files affected by the patch that it is popping.  Be sure to read the
+documentation for a command's \option{-f} option before you use it!
+
+\subsection{Working on several patches at once}
+
+The \hgxcmd{mq}{qrefresh} command always refreshes the \emph{topmost}
+applied patch.  This means that you can suspend work on one patch (by
+refreshing it), pop or push to make a different patch the top, and
+work on \emph{that} patch for a while.
+
+Here's an example that illustrates how you can use this ability.
+Let's say you're developing a new feature as two patches.  The first
+is a change to the core of your software, and the second---layered on
+top of the first---changes the user interface to use the code you just
+added to the core.  If you notice a bug in the core while you're
+working on the UI patch, it's easy to fix the core.  Simply
+\hgxcmd{mq}{qrefresh} the UI patch to save your in-progress changes, and
+\hgxcmd{mq}{qpop} down to the core patch.  Fix the core bug,
+\hgxcmd{mq}{qrefresh} the core patch, and \hgxcmd{mq}{qpush} back to the UI
+patch to continue where you left off.
+
+\section{More about patches}
+\label{sec:mq:adv-patch}
+
+MQ uses the GNU \command{patch} command to apply patches, so it's
+helpful to know a few more detailed aspects of how \command{patch}
+works, and about patches themselves.
+
+\subsection{The strip count}
+
+If you look at the file headers in a patch, you will notice that the
+pathnames usually have an extra component on the front that isn't
+present in the actual path name.  This is a holdover from the way that
+people used to generate patches (people still do this, but it's
+somewhat rare with modern revision control tools).  
+
+Alice would unpack a tarball, edit her files, then decide that she
+wanted to create a patch.  So she'd rename her working directory,
+unpack the tarball again (hence the need for the rename), and use the
+\cmdopt{diff}{-r} and \cmdopt{diff}{-N} options to \command{diff} to
+recursively generate a patch between the unmodified directory and the
+modified one.  The result would be that the name of the unmodified
+directory would be at the front of the left-hand path in every file
+header, and the name of the modified directory would be at the front
+of the right-hand path.
+
+Since someone receiving a patch from the Alices of the net would be
+unlikely to have unmodified and modified directories with exactly the
+same names, the \command{patch} command has a \cmdopt{patch}{-p}
+option that indicates the number of leading path name components to
+strip when trying to apply a patch.  This number is called the
+\emph{strip count}.
+
+An option of ``\texttt{-p1}'' means ``use a strip count of one''.  If
+\command{patch} sees a file name \filename{foo/bar/baz} in a file
+header, it will strip \filename{foo} and try to patch a file named
+\filename{bar/baz}.  (Strictly speaking, the strip count refers to the
+number of \emph{path separators} (and the components that go with them
+) to strip.  A strip count of one will turn \filename{foo/bar} into
+\filename{bar}, but \filename{/foo/bar} (notice the extra leading
+slash) into \filename{foo/bar}.)
+
+The ``standard'' strip count for patches is one; almost all patches
+contain one leading path name component that needs to be stripped.
+Mercurial's \hgcmd{diff} command generates path names in this form,
+and the \hgcmd{import} command and MQ expect patches to have a strip
+count of one.
+
+If you receive a patch from someone that you want to add to your patch
+queue, and the patch needs a strip count other than one, you cannot
+just \hgxcmd{mq}{qimport} the patch, because \hgxcmd{mq}{qimport} does not yet
+have a \texttt{-p} option (see~\bug{311}).  Your best bet is to
+\hgxcmd{mq}{qnew} a patch of your own, then use \cmdargs{patch}{-p\emph{N}}
+to apply their patch, followed by \hgcmd{addremove} to pick up any
+files added or removed by the patch, followed by \hgxcmd{mq}{qrefresh}.
+This complexity may become unnecessary; see~\bug{311} for details.
+\subsection{Strategies for applying a patch}
+
+When \command{patch} applies a hunk, it tries a handful of
+successively less accurate strategies to try to make the hunk apply.
+This falling-back technique often makes it possible to take a patch
+that was generated against an old version of a file, and apply it
+against a newer version of that file.
+
+First, \command{patch} tries an exact match, where the line numbers,
+the context, and the text to be modified must apply exactly.  If it
+cannot make an exact match, it tries to find an exact match for the
+context, without honouring the line numbering information.  If this
+succeeds, it prints a line of output saying that the hunk was applied,
+but at some \emph{offset} from the original line number.
+
+If a context-only match fails, \command{patch} removes the first and
+last lines of the context, and tries a \emph{reduced} context-only
+match.  If the hunk with reduced context succeeds, it prints a message
+saying that it applied the hunk with a \emph{fuzz factor} (the number
+after the fuzz factor indicates how many lines of context
+\command{patch} had to trim before the patch applied).
+
+When neither of these techniques works, \command{patch} prints a
+message saying that the hunk in question was rejected.  It saves
+rejected hunks (also simply called ``rejects'') to a file with the
+same name, and an added \sfilename{.rej} extension.  It also saves an
+unmodified copy of the file with a \sfilename{.orig} extension; the
+copy of the file without any extensions will contain any changes made
+by hunks that \emph{did} apply cleanly.  If you have a patch that
+modifies \filename{foo} with six hunks, and one of them fails to
+apply, you will have: an unmodified \filename{foo.orig}, a
+\filename{foo.rej} containing one hunk, and \filename{foo}, containing
+the changes made by the five successful five hunks.
+
+\subsection{Some quirks of patch representation}
+
+There are a few useful things to know about how \command{patch} works
+with files.
+\begin{itemize}
+\item This should already be obvious, but \command{patch} cannot
+  handle binary files.
+\item Neither does it care about the executable bit; it creates new
+  files as readable, but not executable.
+\item \command{patch} treats the removal of a file as a diff between
+  the file to be removed and the empty file.  So your idea of ``I
+  deleted this file'' looks like ``every line of this file was
+  deleted'' in a patch.
+\item It treats the addition of a file as a diff between the empty
+  file and the file to be added.  So in a patch, your idea of ``I
+  added this file'' looks like ``every line of this file was added''.
+\item It treats a renamed file as the removal of the old name, and the
+  addition of the new name.  This means that renamed files have a big
+  footprint in patches.  (Note also that Mercurial does not currently
+  try to infer when files have been renamed or copied in a patch.)
+\item \command{patch} cannot represent empty files, so you cannot use
+  a patch to represent the notion ``I added this empty file to the
+  tree''.
+\end{itemize}
+\subsection{Beware the fuzz}
+
+While applying a hunk at an offset, or with a fuzz factor, will often
+be completely successful, these inexact techniques naturally leave
+open the possibility of corrupting the patched file.  The most common
+cases typically involve applying a patch twice, or at an incorrect
+location in the file.  If \command{patch} or \hgxcmd{mq}{qpush} ever
+mentions an offset or fuzz factor, you should make sure that the
+modified files are correct afterwards.  
+
+It's often a good idea to refresh a patch that has applied with an
+offset or fuzz factor; refreshing the patch generates new context
+information that will make it apply cleanly.  I say ``often,'' not
+``always,'' because sometimes refreshing a patch will make it fail to
+apply against a different revision of the underlying files.  In some
+cases, such as when you're maintaining a patch that must sit on top of
+multiple versions of a source tree, it's acceptable to have a patch
+apply with some fuzz, provided you've verified the results of the
+patching process in such cases.
+
+\subsection{Handling rejection}
+
+If \hgxcmd{mq}{qpush} fails to apply a patch, it will print an error
+message and exit.  If it has left \sfilename{.rej} files behind, it is
+usually best to fix up the rejected hunks before you push more patches
+or do any further work.
+
+If your patch \emph{used to} apply cleanly, and no longer does because
+you've changed the underlying code that your patches are based on,
+Mercurial Queues can help; see section~\ref{sec:mq:merge} for details.
+
+Unfortunately, there aren't any great techniques for dealing with
+rejected hunks.  Most often, you'll need to view the \sfilename{.rej}
+file and edit the target file, applying the rejected hunks by hand.
+
+If you're feeling adventurous, Neil Brown, a Linux kernel hacker,
+wrote a tool called \command{wiggle}~\cite{web:wiggle}, which is more
+vigorous than \command{patch} in its attempts to make a patch apply.
+
+Another Linux kernel hacker, Chris Mason (the author of Mercurial
+Queues), wrote a similar tool called
+\command{mpatch}~\cite{web:mpatch}, which takes a simple approach to
+automating the application of hunks rejected by \command{patch}.  The
+\command{mpatch} command can help with four common reasons that a hunk
+may be rejected:
+
+\begin{itemize}
+\item The context in the middle of a hunk has changed.
+\item A hunk is missing some context at the beginning or end.
+\item A large hunk might apply better---either entirely or in
+  part---if it was broken up into smaller hunks.
+\item A hunk removes lines with slightly different content than those
+  currently present in the file.
+\end{itemize}
+
+If you use \command{wiggle} or \command{mpatch}, you should be doubly
+careful to check your results when you're done.  In fact,
+\command{mpatch} enforces this method of double-checking the tool's
+output, by automatically dropping you into a merge program when it has
+done its job, so that you can verify its work and finish off any
+remaining merges.
+
+\section{Getting the best performance out of MQ}
+\label{sec:mq:perf}
+
+MQ is very efficient at handling a large number of patches.  I ran
+some performance experiments in mid-2006 for a talk that I gave at the
+2006 EuroPython conference~\cite{web:europython}.  I used as my data
+set the Linux 2.6.17-mm1 patch series, which consists of 1,738
+patches.  I applied these on top of a Linux kernel repository
+containing all 27,472 revisions between Linux 2.6.12-rc2 and Linux
+2.6.17.
+
+On my old, slow laptop, I was able to
+\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} all 1,738 patches in 3.5 minutes,
+and \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} them all in 30 seconds.  (On a
+newer laptop, the time to push all patches dropped to two minutes.)  I
+could \hgxcmd{mq}{qrefresh} one of the biggest patches (which made 22,779
+lines of changes to 287 files) in 6.6 seconds.
+
+Clearly, MQ is well suited to working in large trees, but there are a
+few tricks you can use to get the best performance of it.
+
+First of all, try to ``batch'' operations together.  Every time you
+run \hgxcmd{mq}{qpush} or \hgxcmd{mq}{qpop}, these commands scan the working
+directory once to make sure you haven't made some changes and then
+forgotten to run \hgxcmd{mq}{qrefresh}.  On a small tree, the time that
+this scan takes is unnoticeable.  However, on a medium-sized tree
+(containing tens of thousands of files), it can take a second or more.
+
+The \hgxcmd{mq}{qpush} and \hgxcmd{mq}{qpop} commands allow you to push and pop
+multiple patches at a time.  You can identify the ``destination
+patch'' that you want to end up at.  When you \hgxcmd{mq}{qpush} with a
+destination specified, it will push patches until that patch is at the
+top of the applied stack.  When you \hgxcmd{mq}{qpop} to a destination, MQ
+will pop patches until the destination patch is at the top.
+
+You can identify a destination patch using either the name of the
+patch, or by number.  If you use numeric addressing, patches are
+counted from zero; this means that the first patch is zero, the second
+is one, and so on.
+
+\section{Updating your patches when the underlying code changes}
+\label{sec:mq:merge}
+
+It's common to have a stack of patches on top of an underlying
+repository that you don't modify directly.  If you're working on
+changes to third-party code, or on a feature that is taking longer to
+develop than the rate of change of the code beneath, you will often
+need to sync up with the underlying code, and fix up any hunks in your
+patches that no longer apply.  This is called \emph{rebasing} your
+patch series.
+
+The simplest way to do this is to \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}}
+your patches, then \hgcmd{pull} changes into the underlying
+repository, and finally \hgcmdargs{qpush}{\hgxopt{mq}{qpop}{-a}} your
+patches again.  MQ will stop pushing any time it runs across a patch
+that fails to apply during conflicts, allowing you to fix your
+conflicts, \hgxcmd{mq}{qrefresh} the affected patch, and continue pushing
+until you have fixed your entire stack.
+
+This approach is easy to use and works well if you don't expect
+changes to the underlying code to affect how well your patches apply.
+If your patch stack touches code that is modified frequently or
+invasively in the underlying repository, however, fixing up rejected
+hunks by hand quickly becomes tiresome.
+
+It's possible to partially automate the rebasing process.  If your
+patches apply cleanly against some revision of the underlying repo, MQ
+can use this information to help you to resolve conflicts between your
+patches and a different revision.
+
+The process is a little involved.
+\begin{enumerate}
+\item To begin, \hgcmdargs{qpush}{-a} all of your patches on top of
+  the revision where you know that they apply cleanly.
+\item Save a backup copy of your patch directory using
+  \hgcmdargs{qsave}{\hgxopt{mq}{qsave}{-e} \hgxopt{mq}{qsave}{-c}}.  This prints
+  the name of the directory that it has saved the patches in.  It will
+  save the patches to a directory called
+  \sdirname{.hg/patches.\emph{N}}, where \texttt{\emph{N}} is a small
+  integer.  It also commits a ``save changeset'' on top of your
+  applied patches; this is for internal book-keeping, and records the
+  states of the \sfilename{series} and \sfilename{status} files.
+\item Use \hgcmd{pull} to bring new changes into the underlying
+  repository.  (Don't run \hgcmdargs{pull}{-u}; see below for why.)
+\item Update to the new tip revision, using
+  \hgcmdargs{update}{\hgopt{update}{-C}} to override the patches you
+  have pushed.
+\item Merge all patches using \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}
+    \hgxopt{mq}{qpush}{-a}}.  The \hgxopt{mq}{qpush}{-m} option to \hgxcmd{mq}{qpush}
+  tells MQ to perform a three-way merge if the patch fails to apply.
+\end{enumerate}
+
+During the \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}}, each patch in the
+\sfilename{series} file is applied normally.  If a patch applies with
+fuzz or rejects, MQ looks at the queue you \hgxcmd{mq}{qsave}d, and
+performs a three-way merge with the corresponding changeset.  This
+merge uses Mercurial's normal merge machinery, so it may pop up a GUI
+merge tool to help you to resolve problems.
+
+When you finish resolving the effects of a patch, MQ refreshes your
+patch based on the result of the merge.
+
+At the end of this process, your repository will have one extra head
+from the old patch queue, and a copy of the old patch queue will be in
+\sdirname{.hg/patches.\emph{N}}. You can remove the extra head using
+\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a} \hgxopt{mq}{qpop}{-n} patches.\emph{N}}
+or \hgcmd{strip}.  You can delete \sdirname{.hg/patches.\emph{N}} once
+you are sure that you no longer need it as a backup.
+
+\section{Identifying patches}
+
+MQ commands that work with patches let you refer to a patch either by
+using its name or by a number.  By name is obvious enough; pass the
+name \filename{foo.patch} to \hgxcmd{mq}{qpush}, for example, and it will
+push patches until \filename{foo.patch} is applied.  
+
+As a shortcut, you can refer to a patch using both a name and a
+numeric offset; \texttt{foo.patch-2} means ``two patches before
+\texttt{foo.patch}'', while \texttt{bar.patch+4} means ``four patches
+after \texttt{bar.patch}''.
+
+Referring to a patch by index isn't much different.  The first patch
+printed in the output of \hgxcmd{mq}{qseries} is patch zero (yes, it's one
+of those start-at-zero counting systems); the second is patch one; and
+so on.
+
+MQ also makes it easy to work with patches when you are using normal
+Mercurial commands.  Every command that accepts a changeset ID will
+also accept the name of an applied patch.  MQ augments the tags
+normally in the repository with an eponymous one for each applied
+patch.  In addition, the special tags \index{tags!special tag
+  names!\texttt{qbase}}\texttt{qbase} and \index{tags!special tag
+  names!\texttt{qtip}}\texttt{qtip} identify the ``bottom-most'' and
+topmost applied patches, respectively.
+
+These additions to Mercurial's normal tagging capabilities make
+dealing with patches even more of a breeze.
+\begin{itemize}
+\item Want to patchbomb a mailing list with your latest series of
+  changes?
+  \begin{codesample4}
+    hg email qbase:qtip
+  \end{codesample4}
+  (Don't know what ``patchbombing'' is?  See
+  section~\ref{sec:hgext:patchbomb}.)
+\item Need to see all of the patches since \texttt{foo.patch} that
+  have touched files in a subdirectory of your tree?
+  \begin{codesample4}
+    hg log -r foo.patch:qtip \emph{subdir}
+  \end{codesample4}
+\end{itemize}
+
+Because MQ makes the names of patches available to the rest of
+Mercurial through its normal internal tag machinery, you don't need to
+type in the entire name of a patch when you want to identify it by
+name.
+
+\begin{figure}[ht]
+  \interaction{mq.id.output}
+  \caption{Using MQ's tag features to work with patches}
+  \label{ex:mq:id}
+\end{figure}
+
+Another nice consequence of representing patch names as tags is that
+when you run the \hgcmd{log} command, it will display a patch's name
+as a tag, simply as part of its normal output.  This makes it easy to
+visually distinguish applied patches from underlying ``normal''
+revisions.  Figure~\ref{ex:mq:id} shows a few normal Mercurial
+commands in use with applied patches.
+
+\section{Useful things to know about}
+
+There are a number of aspects of MQ usage that don't fit tidily into
+sections of their own, but that are good to know.  Here they are, in
+one place.
+
+\begin{itemize}
+\item Normally, when you \hgxcmd{mq}{qpop} a patch and \hgxcmd{mq}{qpush} it
+  again, the changeset that represents the patch after the pop/push
+  will have a \emph{different identity} than the changeset that
+  represented the hash beforehand.  See
+  section~\ref{sec:mqref:cmd:qpush} for information as to why this is.
+\item It's not a good idea to \hgcmd{merge} changes from another
+  branch with a patch changeset, at least if you want to maintain the
+  ``patchiness'' of that changeset and changesets below it on the
+  patch stack.  If you try to do this, it will appear to succeed, but
+  MQ will become confused.
+\end{itemize}
+
+\section{Managing patches in a repository}
+\label{sec:mq:repo}
+
+Because MQ's \sdirname{.hg/patches} directory resides outside a
+Mercurial repository's working directory, the ``underlying'' Mercurial
+repository knows nothing about the management or presence of patches.
+
+This presents the interesting possibility of managing the contents of
+the patch directory as a Mercurial repository in its own right.  This
+can be a useful way to work.  For example, you can work on a patch for
+a while, \hgxcmd{mq}{qrefresh} it, then \hgcmd{commit} the current state of
+the patch.  This lets you ``roll back'' to that version of the patch
+later on.
+
+You can then share different versions of the same patch stack among
+multiple underlying repositories.  I use this when I am developing a
+Linux kernel feature.  I have a pristine copy of my kernel sources for
+each of several CPU architectures, and a cloned repository under each
+that contains the patches I am working on.  When I want to test a
+change on a different architecture, I push my current patches to the
+patch repository associated with that kernel tree, pop and push all of
+my patches, and build and test that kernel.
+
+Managing patches in a repository makes it possible for multiple
+developers to work on the same patch series without colliding with
+each other, all on top of an underlying source base that they may or
+may not control.
+
+\subsection{MQ support for patch repositories}
+
+MQ helps you to work with the \sdirname{.hg/patches} directory as a
+repository; when you prepare a repository for working with patches
+using \hgxcmd{mq}{qinit}, you can pass the \hgxopt{mq}{qinit}{-c} option to
+create the \sdirname{.hg/patches} directory as a Mercurial repository.
+
+\begin{note}
+  If you forget to use the \hgxopt{mq}{qinit}{-c} option, you can simply go
+  into the \sdirname{.hg/patches} directory at any time and run
+  \hgcmd{init}.  Don't forget to add an entry for the
+  \sfilename{status} file to the \sfilename{.hgignore} file, though
+
+  (\hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} does this for you
+  automatically); you \emph{really} don't want to manage the
+  \sfilename{status} file.
+\end{note}
+
+As a convenience, if MQ notices that the \dirname{.hg/patches}
+directory is a repository, it will automatically \hgcmd{add} every
+patch that you create and import.
+
+MQ provides a shortcut command, \hgxcmd{mq}{qcommit}, that runs
+\hgcmd{commit} in the \sdirname{.hg/patches} directory.  This saves
+some bothersome typing.
+
+Finally, as a convenience to manage the patch directory, you can
+define the alias \command{mq} on Unix systems. For example, on Linux
+systems using the \command{bash} shell, you can include the following
+snippet in your \tildefile{.bashrc}.
+
+\begin{codesample2}
+  alias mq=`hg -R \$(hg root)/.hg/patches'
+\end{codesample2}
+
+You can then issue commands of the form \cmdargs{mq}{pull} from
+the main repository.
+
+\subsection{A few things to watch out for}
+
+MQ's support for working with a repository full of patches is limited
+in a few small respects.
+
+MQ cannot automatically detect changes that you make to the patch
+directory.  If you \hgcmd{pull}, manually edit, or \hgcmd{update}
+changes to patches or the \sfilename{series} file, you will have to
+\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} and then
+\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} in the underlying repository to
+see those changes show up there.  If you forget to do this, you can
+confuse MQ's idea of which patches are applied.
+
+\section{Third party tools for working with patches}
+\label{sec:mq:tools}
+
+Once you've been working with patches for a while, you'll find
+yourself hungry for tools that will help you to understand and
+manipulate the patches you're dealing with.
+
+The \command{diffstat} command~\cite{web:diffstat} generates a
+histogram of the modifications made to each file in a patch.  It
+provides a good way to ``get a sense of'' a patch---which files it
+affects, and how much change it introduces to each file and as a
+whole.  (I find that it's a good idea to use \command{diffstat}'s
+\cmdopt{diffstat}{-p} option as a matter of course, as otherwise it
+will try to do clever things with prefixes of file names that
+inevitably confuse at least me.)
+
+\begin{figure}[ht]
+  \interaction{mq.tools.tools}
+  \caption{The \command{diffstat}, \command{filterdiff}, and \command{lsdiff} commands}
+  \label{ex:mq:tools}
+\end{figure}
+
+The \package{patchutils} package~\cite{web:patchutils} is invaluable.
+It provides a set of small utilities that follow the ``Unix
+philosophy;'' each does one useful thing with a patch.  The
+\package{patchutils} command I use most is \command{filterdiff}, which
+extracts subsets from a patch file.  For example, given a patch that
+modifies hundreds of files across dozens of directories, a single
+invocation of \command{filterdiff} can generate a smaller patch that
+only touches files whose names match a particular glob pattern.  See
+section~\ref{mq-collab:tips:interdiff} for another example.
+
+\section{Good ways to work with patches}
+
+Whether you are working on a patch series to submit to a free software
+or open source project, or a series that you intend to treat as a
+sequence of regular changesets when you're done, you can use some
+simple techniques to keep your work well organised.
+
+Give your patches descriptive names.  A good name for a patch might be
+\filename{rework-device-alloc.patch}, because it will immediately give
+you a hint what the purpose of the patch is.  Long names shouldn't be
+a problem; you won't be typing the names often, but you \emph{will} be
+running commands like \hgxcmd{mq}{qapplied} and \hgxcmd{mq}{qtop} over and over.
+Good naming becomes especially important when you have a number of
+patches to work with, or if you are juggling a number of different
+tasks and your patches only get a fraction of your attention.
+
+Be aware of what patch you're working on.  Use the \hgxcmd{mq}{qtop}
+command and skim over the text of your patches frequently---for
+example, using \hgcmdargs{tip}{\hgopt{tip}{-p}})---to be sure of where
+you stand.  I have several times worked on and \hgxcmd{mq}{qrefresh}ed a
+patch other than the one I intended, and it's often tricky to migrate
+changes into the right patch after making them in the wrong one.
+
+For this reason, it is very much worth investing a little time to
+learn how to use some of the third-party tools I described in
+section~\ref{sec:mq:tools}, particularly \command{diffstat} and
+\command{filterdiff}.  The former will give you a quick idea of what
+changes your patch is making, while the latter makes it easy to splice
+hunks selectively out of one patch and into another.
+
+\section{MQ cookbook}
+
+\subsection{Manage ``trivial'' patches}
+
+Because the overhead of dropping files into a new Mercurial repository
+is so low, it makes a lot of sense to manage patches this way even if
+you simply want to make a few changes to a source tarball that you
+downloaded.
+
+Begin by downloading and unpacking the source tarball,
+and turning it into a Mercurial repository.
+\interaction{mq.tarball.download}
+
+Continue by creating a patch stack and making your changes.
+\interaction{mq.tarball.qinit}
+
+Let's say a few weeks or months pass, and your package author releases
+a new version.  First, bring their changes into the repository.
+\interaction{mq.tarball.newsource}
+The pipeline starting with \hgcmd{locate} above deletes all files in
+the working directory, so that \hgcmd{commit}'s
+\hgopt{commit}{--addremove} option can actually tell which files have
+really been removed in the newer version of the source.
+
+Finally, you can apply your patches on top of the new tree.
+\interaction{mq.tarball.repush}
+
+\subsection{Combining entire patches}
+\label{sec:mq:combine}
+
+MQ provides a command, \hgxcmd{mq}{qfold} that lets you combine entire
+patches.  This ``folds'' the patches you name, in the order you name
+them, into the topmost applied patch, and concatenates their
+descriptions onto the end of its description.  The patches that you
+fold must be unapplied before you fold them.
+
+The order in which you fold patches matters.  If your topmost applied
+patch is \texttt{foo}, and you \hgxcmd{mq}{qfold} \texttt{bar} and
+\texttt{quux} into it, you will end up with a patch that has the same
+effect as if you applied first \texttt{foo}, then \texttt{bar},
+followed by \texttt{quux}.
+
+\subsection{Merging part of one patch into another}
+
+Merging \emph{part} of one patch into another is more difficult than
+combining entire patches.
+
+If you want to move changes to entire files, you can use
+\command{filterdiff}'s \cmdopt{filterdiff}{-i} and
+\cmdopt{filterdiff}{-x} options to choose the modifications to snip
+out of one patch, concatenating its output onto the end of the patch
+you want to merge into.  You usually won't need to modify the patch
+you've merged the changes from.  Instead, MQ will report some rejected
+hunks when you \hgxcmd{mq}{qpush} it (from the hunks you moved into the
+other patch), and you can simply \hgxcmd{mq}{qrefresh} the patch to drop
+the duplicate hunks.
+
+If you have a patch that has multiple hunks modifying a file, and you
+only want to move a few of those hunks, the job becomes more messy,
+but you can still partly automate it.  Use \cmdargs{lsdiff}{-nvv} to
+print some metadata about the patch.
+\interaction{mq.tools.lsdiff}
+
+This command prints three different kinds of number:
+\begin{itemize}
+\item (in the first column) a \emph{file number} to identify each file
+  modified in the patch;
+\item (on the next line, indented) the line number within a modified
+  file where a hunk starts; and
+\item (on the same line) a \emph{hunk number} to identify that hunk.
+\end{itemize}
+
+You'll have to use some visual inspection, and reading of the patch,
+to identify the file and hunk numbers you'll want, but you can then
+pass them to to \command{filterdiff}'s \cmdopt{filterdiff}{--files}
+and \cmdopt{filterdiff}{--hunks} options, to select exactly the file
+and hunk you want to extract.
+
+Once you have this hunk, you can concatenate it onto the end of your
+destination patch and continue with the remainder of
+section~\ref{sec:mq:combine}.
+
+\section{Differences between quilt and MQ}
+
+If you are already familiar with quilt, MQ provides a similar command
+set.  There are a few differences in the way that it works.
+
+You will already have noticed that most quilt commands have MQ
+counterparts that simply begin with a ``\texttt{q}''.  The exceptions
+are quilt's \texttt{add} and \texttt{remove} commands, the
+counterparts for which are the normal Mercurial \hgcmd{add} and
+\hgcmd{remove} commands.  There is no MQ equivalent of the quilt
+\texttt{edit} command.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
Binary file es/note.png has changed
--- a/es/tour-merge.tex	Sat Oct 18 14:35:43 2008 -0500
+++ b/es/tour-merge.tex	Sat Oct 18 15:44:41 2008 -0500
@@ -0,0 +1,283 @@
+\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''.  
+
+\subsection{Head changesets}
+
+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}
+
+\subsection{Performing the merge}
+
+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}
+
+\subsection{Committing the results of the merge}
+
+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}
+In figure~\ref{fig:tour-merge:merge}, you can see a representation of
+what happens to the working directory during the merge, and how this
+affects the repository when the commit happens.  During the merge, the
+working directory has two parent changesets, and these become the
+parents of the new changeset.
+
+\section{Merging conflicting changes}
+
+Most merges are simple affairs, but sometimes you'll find yourself
+merging changes where each modifies the same portions of the same
+files.  Unless both modifications are identical, this results in a
+\emph{conflict}, where you have to decide how to reconcile the
+different changes into something coherent.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{tour-merge-conflict}
+  \caption{Conflicting changes to a document}
+  \label{fig:tour-merge:conflict}
+\end{figure}
+
+Figure~\ref{fig:tour-merge:conflict} illustrates an instance of two
+conflicting changes to a document.  We started with a single version
+of the file; then we made some changes; while someone else made
+different changes to the same text.  Our task in resolving the
+conflicting changes is to decide what the file should look like.
+
+Mercurial doesn't have a built-in facility for handling conflicts.
+Instead, it runs an external program called \command{hgmerge}.  This
+is a shell script that is bundled with Mercurial; you can change it to
+behave however you please.  What it does by default is try to find one
+of several different merging tools that are likely to be installed on
+your system.  It first tries a few fully automatic merging tools; if
+these don't succeed (because the resolution process requires human
+guidance) or aren't present, the script tries a few different
+graphical merging tools.
+
+It's also possible to get Mercurial to run another program or script
+instead of \command{hgmerge}, by setting the \envar{HGMERGE}
+environment variable to the name of your preferred program.
+
+\subsection{Using a graphical merge tool}
+
+My preferred graphical merge tool is \command{kdiff3}, which I'll use
+to describe the features that are common to graphical file merging
+tools.  You can see a screenshot of \command{kdiff3} in action in
+figure~\ref{fig:tour-merge:kdiff3}.  The kind of merge it is
+performing is called a \emph{three-way merge}, because there are three
+different versions of the file of interest to us.  The tool thus
+splits the upper portion of the window into three panes:
+\begin{itemize}
+\item At the left is the \emph{base} version of the file, i.e.~the
+  most recent version from which the two versions we're trying to
+  merge are descended.
+\item In the middle is ``our'' version of the file, with the contents
+  that we modified.
+\item On the right is ``their'' version of the file, the one that
+  from the changeset that we're trying to merge with.
+\end{itemize}
+In the pane below these is the current \emph{result} of the merge.
+Our task is to replace all of the red text, which indicates unresolved
+conflicts, with some sensible merger of the ``ours'' and ``theirs''
+versions of the file.
+
+All four of these panes are \emph{locked together}; if we scroll
+vertically or horizontally in any of them, the others are updated to
+display the corresponding sections of their respective files.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{kdiff3}
+  \caption{Using \command{kdiff3} to merge versions of a file}
+  \label{fig:tour-merge:kdiff3}
+\end{figure}
+
+For each conflicting portion of the file, we can choose to resolve
+the conflict using some combination of text from the base version,
+ours, or theirs.  We can also manually edit the merged file at any
+time, in case we need to make further modifications.
+
+There are \emph{many} file merging tools available, too many to cover
+here.  They vary in which platforms they are available for, and in
+their particular strengths and weaknesses.  Most are tuned for merging
+files containing plain text, while a few are aimed at specialised file
+formats (generally XML).
+
+\subsection{A worked example}
+
+In this example, we will reproduce the file modification history of
+figure~\ref{fig:tour-merge:conflict} above.  Let's begin by creating a
+repository with a base version of our document.
+\interaction{tour-merge-conflict.wife}
+We'll clone the repository and make a change to the file.
+\interaction{tour-merge-conflict.cousin}
+And another clone, to simulate someone else making a change to the
+file.  (This hints at the idea that it's not all that unusual to merge
+with yourself when you isolate tasks in separate repositories, and
+indeed to find and resolve conflicts while doing so.)
+\interaction{tour-merge-conflict.son}
+Having created two different versions of the file, we'll set up an
+environment suitable for running our merge.
+\interaction{tour-merge-conflict.pull}
+
+In this example, I won't use Mercurial's normal \command{hgmerge}
+program to do the merge, because it would drop my nice automated
+example-running tool into a graphical user interface.  Instead, I'll
+set \envar{HGMERGE} to tell Mercurial to use the non-interactive
+\command{merge} command.  This is bundled with many Unix-like systems.
+If you're following this example on your computer, don't bother
+setting \envar{HGMERGE}.
+\interaction{tour-merge-conflict.merge}
+Because \command{merge} can't resolve the conflicting changes, it
+leaves \emph{merge markers} inside the file that has conflicts,
+indicating which lines have conflicts, and whether they came from our
+version of the file or theirs.
+
+Mercurial can tell from the way \command{merge} exits that it wasn't
+able to merge successfully, so it tells us what commands we'll need to
+run if we want to redo the merging operation.  This could be useful
+if, for example, we were running a graphical merge tool and quit
+because we were confused or realised we had made a mistake.
+
+If automatic or manual merges fail, there's nothing to prevent us from
+``fixing up'' the affected files ourselves, and committing the results
+of our merge:
+\interaction{tour-merge-conflict.commit}
+
+\section{Simplifying the pull-merge-commit sequence}
+\label{sec:tour-merge:fetch}
+
+The process of merging changes as outlined above is straightforward,
+but requires running three commands in sequence.
+\begin{codesample2}
+  hg pull
+  hg merge
+  hg commit -m 'Merged remote changes'
+\end{codesample2}
+In the case of the final commit, you also need to enter a commit
+message, which is almost always going to be a piece of uninteresting
+``boilerplate'' text.
+
+It would be nice to reduce the number of steps needed, if this were
+possible.  Indeed, Mercurial is distributed with an extension called
+\hgext{fetch} that does just this.
+
+Mercurial provides a flexible extension mechanism that lets people
+extend its functionality, while keeping the core of Mercurial small
+and easy to deal with.  Some extensions add new commands that you can
+use from the command line, while others work ``behind the scenes,''
+for example adding capabilities to the server.
+
+The \hgext{fetch} extension adds a new command called, not
+surprisingly, \hgcmd{fetch}.  This extension acts as a combination of
+\hgcmd{pull}, \hgcmd{update} and \hgcmd{merge}.  It begins by pulling
+changes from another repository into the current repository.  If it
+finds that the changes added a new head to the repository, it begins a
+merge, then commits the result of the merge with an
+automatically-generated commit message.  If no new heads were added,
+it updates the working directory to the new tip changeset.
+
+Enabling the \hgext{fetch} extension is easy.  Edit your
+\sfilename{.hgrc}, and either go to the \rcsection{extensions} section
+or create an \rcsection{extensions} section.  Then add a line that
+simply reads ``\Verb+fetch +''.
+\begin{codesample2}
+  [extensions]
+  fetch =
+\end{codesample2}
+(Normally, on the right-hand side of the ``\texttt{=}'' would appear
+the location of the extension, but since the \hgext{fetch} extension
+is in the standard distribution, Mercurial knows where to search for
+it.)
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/undo-manual-merge.dot	Sat Oct 18 15:44:41 2008 -0500
@@ -0,0 +1,8 @@
+digraph undo_manual {
+	"first change" -> "second change";
+	"second change" -> "third change";
+	backout [label="back out\nsecond change", shape=box];
+	"second change" -> backout;
+	"third change" -> "manual\nmerge";
+	backout -> "manual\nmerge";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/undo-non-tip.dot	Sat Oct 18 15:44:41 2008 -0500
@@ -0,0 +1,9 @@
+digraph undo_non_tip {
+	"first change" -> "second change";
+	"second change" -> "third change";
+	backout [label="back out\nsecond change", shape=box];
+	"second change" -> backout;
+	merge [label="automated\nmerge", shape=box];
+	"third change" -> merge;
+	backout -> merge;
+}