changeset 831:acf9dc5f088d

Add a skeletal preface.
author Bryan O'Sullivan <bos@serpentine.com>
date Thu, 07 May 2009 21:07:35 -0700
parents cbdff5945f9d
children d5688822c51d
files en/00book.xml en/ch00-preface.xml en/ch01-intro.xml en/ch01-tour-basic.xml en/ch02-tour-basic.xml en/ch02-tour-merge.xml en/ch03-concepts.xml en/ch03-tour-merge.xml en/ch04-concepts.xml en/ch04-daily.xml en/ch05-collab.xml en/ch05-daily.xml en/ch06-collab.xml en/ch06-filenames.xml en/ch07-branch.xml en/ch07-filenames.xml en/ch08-branch.xml en/ch08-undo.xml en/ch09-hook.xml en/ch09-undo.xml en/ch10-hook.xml en/ch10-template.xml en/ch11-mq.xml en/ch11-template.xml en/ch12-mq-collab.xml en/ch12-mq.xml en/ch13-hgext.xml en/ch13-mq-collab.xml en/ch14-hgext.xml
diffstat 29 files changed, 12771 insertions(+), 12632 deletions(-) [+]
line wrap: on
line diff
--- a/en/00book.xml	Thu May 07 21:06:49 2009 -0700
+++ b/en/00book.xml	Thu May 07 21:07:35 2009 -0700
@@ -8,19 +8,20 @@
 <!-- Chapters. -->
 
 <!ENTITY ch00     SYSTEM "ch00-preface.xml">
-<!ENTITY ch01     SYSTEM "ch01-tour-basic.xml">
-<!ENTITY ch02     SYSTEM "ch02-tour-merge.xml">
-<!ENTITY ch03     SYSTEM "ch03-concepts.xml">
-<!ENTITY ch04     SYSTEM "ch04-daily.xml">
-<!ENTITY ch05     SYSTEM "ch05-collab.xml">
-<!ENTITY ch06     SYSTEM "ch06-filenames.xml">
-<!ENTITY ch07     SYSTEM "ch07-branch.xml">
-<!ENTITY ch08     SYSTEM "ch08-undo.xml">
-<!ENTITY ch09     SYSTEM "ch09-hook.xml">
-<!ENTITY ch10     SYSTEM "ch10-template.xml">
-<!ENTITY ch11     SYSTEM "ch11-mq.xml">
-<!ENTITY ch12     SYSTEM "ch12-mq-collab.xml">
-<!ENTITY ch13     SYSTEM "ch13-hgext.xml">
+<!ENTITY ch01     SYSTEM "ch01-intro.xml">
+<!ENTITY ch02     SYSTEM "ch02-tour-basic.xml">
+<!ENTITY ch03     SYSTEM "ch03-tour-merge.xml">
+<!ENTITY ch04     SYSTEM "ch04-concepts.xml">
+<!ENTITY ch05     SYSTEM "ch05-daily.xml">
+<!ENTITY ch06     SYSTEM "ch06-collab.xml">
+<!ENTITY ch07     SYSTEM "ch07-filenames.xml">
+<!ENTITY ch08     SYSTEM "ch08-branch.xml">
+<!ENTITY ch09     SYSTEM "ch09-undo.xml">
+<!ENTITY ch10     SYSTEM "ch10-hook.xml">
+<!ENTITY ch11     SYSTEM "ch11-template.xml">
+<!ENTITY ch12     SYSTEM "ch12-mq.xml">
+<!ENTITY ch13     SYSTEM "ch13-mq-collab.xml">
+<!ENTITY ch14     SYSTEM "ch14-hgext.xml">
 <!ENTITY appA     SYSTEM "appA-svn.xml">
 <!ENTITY appB     SYSTEM "appB-mq-ref.xml">
 <!ENTITY appC     SYSTEM "appC-srcinstall.xml">
@@ -96,6 +97,8 @@
   &ch12;
   <!-- BEGIN ch13 -->
   &ch13;
+  <!-- BEGIN ch14 -->
+  &ch14;
   <!-- BEGIN appA -->
   &appA;
   <!-- BEGIN appB -->
--- a/en/ch00-preface.xml	Thu May 07 21:06:49 2009 -0700
+++ b/en/ch00-preface.xml	Thu May 07 21:07:35 2009 -0700
@@ -5,751 +5,153 @@
   <title>Preface</title>
 
   <sect1>
-    <title>Why revision control? Why Mercurial?</title>
-
-    <para id="x_6d">Revision control is the process of managing multiple
-      versions of a piece of information.  In its simplest form, this
-      is something that many people do by hand: every time you modify
-      a file, save it under a new name that contains a number, each
-      one higher than the number of the preceding version.</para>
+    <title>Conventions Used in This Book</title>
 
-    <para id="x_6e">Manually managing multiple versions of even a single file is
-      an error-prone task, though, so software tools to help automate
-      this process have long been available.  The earliest automated
-      revision control tools were intended to help a single user to
-      manage revisions of a single file.  Over the past few decades,
-      the scope of revision control tools has expanded greatly; they
-      now manage multiple files, and help multiple people to work
-      together.  The best modern revision control tools have no
-      problem coping with thousands of people working together on
-      projects that consist of hundreds of thousands of files.</para>
+    <para>The following typographical conventions are used in this
+      book:</para>
 
-    <para id="x_6f">The arrival of distributed revision control is relatively
-      recent, and so far this new field has grown due to people's
-      willingness to explore ill-charted territory.</para>
-
-    <para id="x_70">I am writing a book about distributed revision control
-      because I believe that it is an important subject that deserves
-      a field guide. I chose to write about Mercurial because it is
-      the easiest tool to learn the terrain with, and yet it scales to
-      the demands of real, challenging environments where many other
-      revision control tools buckle.</para>
-
-    <sect2>
-      <title>Why use revision control?</title>
-
-      <para id="x_71">There are a number of reasons why you or your team might
-	want to use an automated revision control tool for a
-	project.</para>
+    <variablelist>
+      <varlistentry>
+        <term>Italic</term>
 
-      <itemizedlist>
-	<listitem><para id="x_72">It will track the history and evolution of
-	    your project, so you don't have to.  For every change,
-	    you'll have a log of <emphasis>who</emphasis> made it;
-	    <emphasis>why</emphasis> they made it;
-	    <emphasis>when</emphasis> they made it; and
-	    <emphasis>what</emphasis> the change
-	    was.</para></listitem>
-	<listitem><para id="x_73">When you're working with other people,
-	    revision control software makes it easier for you to
-	    collaborate.  For example, when people more or less
-	    simultaneously make potentially incompatible changes, the
-	    software will help you to identify and resolve those
-	    conflicts.</para></listitem>
-	<listitem><para id="x_74">It can help you to recover from mistakes.  If
-	    you make a change that later turns out to be in error, you
-	    can revert to an earlier version of one or more files.  In
-	    fact, a <emphasis>really</emphasis> good revision control
-	    tool will even help you to efficiently figure out exactly
-	    when a problem was introduced (see <xref
-	      linkend="sec:undo:bisect"/> for details).</para></listitem>
-	<listitem><para id="x_75">It will help you to work simultaneously on,
-	    and manage the drift between, multiple versions of your
-	    project.</para></listitem>
-      </itemizedlist>
+        <listitem>
+          <para>Indicates new terms, URLs, email addresses, filenames,
+	    and file extensions.</para>
+        </listitem>
+      </varlistentry>
 
-      <para id="x_76">Most of these reasons are equally
-	valid&emdash;at least in theory&emdash;whether you're working
-	on a project by yourself, or with a hundred other
-	people.</para>
+      <varlistentry>
+        <term><literal>Constant width</literal></term>
 
-      <para id="x_77">A key question about the practicality of revision control
-	at these two different scales (<quote>lone hacker</quote> and
-	<quote>huge team</quote>) is how its
-	<emphasis>benefits</emphasis> compare to its
-	<emphasis>costs</emphasis>.  A revision control tool that's
-	difficult to understand or use is going to impose a high
-	cost.</para>
-
-      <para id="x_78">A five-hundred-person project is likely to collapse under
-	its own weight almost immediately without a revision control
-	tool and process. In this case, the cost of using revision
-	control might hardly seem worth considering, since
-	<emphasis>without</emphasis> it, failure is almost
-	guaranteed.</para>
+        <listitem>
+          <para>Used for program listings, as well as within
+	    paragraphs to refer to program elements such as variable
+	    or function names, databases, data types, environment
+	    variables, statements, and keywords.</para>
+        </listitem>
+      </varlistentry>
 
-      <para id="x_79">On the other hand, a one-person <quote>quick hack</quote>
-	might seem like a poor place to use a revision control tool,
-	because surely the cost of using one must be close to the
-	overall cost of the project.  Right?</para>
-
-      <para id="x_7a">Mercurial uniquely supports <emphasis>both</emphasis> of
-	these scales of development.  You can learn the basics in just
-	a few minutes, and due to its low overhead, you can apply
-	revision control to the smallest of projects with ease.  Its
-	simplicity means you won't have a lot of abstruse concepts or
-	command sequences competing for mental space with whatever
-	you're <emphasis>really</emphasis> trying to do.  At the same
-	time, Mercurial's high performance and peer-to-peer nature let
-	you scale painlessly to handle large projects.</para>
-
-      <para id="x_7b">No revision control tool can rescue a poorly run project,
-	but a good choice of tools can make a huge difference to the
-	fluidity with which you can work on a project.</para>
-
-    </sect2>
+      <varlistentry>
+        <term><userinput>Constant width bold</userinput></term>
 
-    <sect2>
-      <title>The many names of revision control</title>
+        <listitem>
+          <para>Shows commands or other text that should be typed
+	    literally by the user.</para>
+        </listitem>
+      </varlistentry>
 
-      <para id="x_7c">Revision control is a diverse field, so much so that it is
-	referred to by many names and acronyms.  Here are a few of the
-	more common variations you'll encounter:</para>
-      <itemizedlist>
-	<listitem><para id="x_7d">Revision control (RCS)</para></listitem>
-	<listitem><para id="x_7e">Software configuration management (SCM), or
-	    configuration management</para></listitem>
-	<listitem><para id="x_7f">Source code management</para></listitem>
-	<listitem><para id="x_80">Source code control, or source
-	    control</para></listitem>
-	<listitem><para id="x_81">Version control
-	    (VCS)</para></listitem></itemizedlist>
-      <para id="x_82">Some people claim that these terms actually have different
-	meanings, but in practice they overlap so much that there's no
-	agreed or even useful way to tease them apart.</para>
-
-    </sect2>
-  </sect1>
+      <varlistentry>
+        <term><replaceable>Constant width italic</replaceable></term>
 
-  <sect1>
-    <title>This book is a work in progress</title>
-
-    <para id="x_83">I am releasing this book while I am still writing it, in the
-      hope that it will prove useful to others.  I am writing under an
-      open license in the hope that you, my readers, will contribute
-      feedback and perhaps content of your own.</para>
-
-  </sect1>
-  <sect1>
-    <title>About the examples in this book</title>
-
-    <para id="x_84">This book takes an unusual approach to code samples.  Every
-      example is <quote>live</quote>&emdash;each one is actually the result
-      of a shell script that executes the Mercurial commands you see.
-      Every time an image of the book is built from its sources, all
-      the example scripts are automatically run, and their current
-      results compared against their expected results.</para>
+        <listitem>
+          <para>Shows text that should be replaced with user-supplied
+	    values or by values determined by context.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
 
-    <para id="x_85">The advantage of this approach is that the examples are
-      always accurate; they describe <emphasis>exactly</emphasis> the
-      behavior of the version of Mercurial that's mentioned at the
-      front of the book.  If I update the version of Mercurial that
-      I'm documenting, and the output of some command changes, the
-      build fails.</para>
+    <tip>
+      <para>This icon signifies a tip, suggestion, or general
+	note.</para>
+    </tip>
 
-    <para id="x_86">There is a small disadvantage to this approach, which is
-      that the dates and times you'll see in examples tend to be
-      <quote>squashed</quote> together in a way that they wouldn't be
-      if the same commands were being typed by a human.  Where a human
-      can issue no more than one command every few seconds, with any
-      resulting timestamps correspondingly spread out, my automated
-      example scripts run many commands in one second.</para>
-
-    <para id="x_87">As an instance of this, several consecutive commits in an
-      example can show up as having occurred during the same second.
-      You can see this occur in the <literal
-	role="hg-ext">bisect</literal> example in <xref
-	linkend="sec:undo:bisect"/>, for instance.</para>
-
-    <para id="x_88">So when you're reading examples, don't place too much weight
-      on the dates or times you see in the output of commands.  But
-      <emphasis>do</emphasis> be confident that the behavior you're
-      seeing is consistent and reproducible.</para>
-
+    <caution>
+      <para>This icon indicates a warning or caution.</para>
+    </caution>
   </sect1>
 
   <sect1>
-    <title>Trends in the field</title>
-
-    <para id="x_89">There has been an unmistakable trend in the development and
-      use of revision control tools over the past four decades, as
-      people have become familiar with the capabilities of their tools
-      and constrained by their limitations.</para>
-
-    <para id="x_8a">The first generation began by managing single files on
-      individual computers.  Although these tools represented a huge
-      advance over ad-hoc manual revision control, their locking model
-      and reliance on a single computer limited them to small,
-      tightly-knit teams.</para>
-
-    <para id="x_8b">The second generation loosened these constraints by moving
-      to network-centered architectures, and managing entire projects
-      at a time.  As projects grew larger, they ran into new problems.
-      With clients needing to talk to servers very frequently, server
-      scaling became an issue for large projects.  An unreliable
-      network connection could prevent remote users from being able to
-      talk to the server at all.  As open source projects started
-      making read-only access available anonymously to anyone, people
-      without commit privileges found that they could not use the
-      tools to interact with a project in a natural way, as they could
-      not record their changes.</para>
-
-    <para id="x_8c">The current generation of revision control tools is
-      peer-to-peer in nature.  All of these systems have dropped the
-      dependency on a single central server, and allow people to
-      distribute their revision control data to where it's actually
-      needed.  Collaboration over the Internet has moved from
-      constrained by technology to a matter of choice and consensus.
-      Modern tools can operate offline indefinitely and autonomously,
-      with a network connection only needed when syncing changes with
-      another repository.</para>
-
-  </sect1>
-  <sect1>
-    <title>A few of the advantages of distributed revision
-      control</title>
-
-    <para id="x_8d">Even though distributed revision control tools have for
-      several years been as robust and usable as their
-      previous-generation counterparts, people using older tools have
-      not yet necessarily woken up to their advantages.  There are a
-      number of ways in which distributed tools shine relative to
-      centralised ones.</para>
-
-    <para id="x_8e">For an individual developer, distributed tools are almost
-      always much faster than centralised tools.  This is for a simple
-      reason: a centralised tool needs to talk over the network for
-      many common operations, because most metadata is stored in a
-      single copy on the central server.  A distributed tool stores
-      all of its metadata locally.  All else being equal, talking over
-      the network adds overhead to a centralised tool.  Don't
-      underestimate the value of a snappy, responsive tool: you're
-      going to spend a lot of time interacting with your revision
-      control software.</para>
-
-    <para id="x_8f">Distributed tools are indifferent to the vagaries of your
-      server infrastructure, again because they replicate metadata to
-      so many locations.  If you use a centralised system and your
-      server catches fire, you'd better hope that your backup media
-      are reliable, and that your last backup was recent and actually
-      worked.  With a distributed tool, you have many backups
-      available on every contributor's computer.</para>
-
-    <para id="x_90">The reliability of your network will affect distributed
-      tools far less than it will centralised tools.  You can't even
-      use a centralised tool without a network connection, except for
-      a few highly constrained commands.  With a distributed tool, if
-      your network connection goes down while you're working, you may
-      not even notice.  The only thing you won't be able to do is talk
-      to repositories on other computers, something that is relatively
-      rare compared with local operations.  If you have a far-flung
-      team of collaborators, this may be significant.</para>
-
-    <sect2>
-      <title>Advantages for open source projects</title>
-
-      <para id="x_91">If you take a shine to an open source project and decide
-	that you would like to start hacking on it, and that project
-	uses a distributed revision control tool, you are at once a
-	peer with the people who consider themselves the
-	<quote>core</quote> of that project.  If they publish their
-	repositories, you can immediately copy their project history,
-	start making changes, and record your work, using the same
-	tools in the same ways as insiders.  By contrast, with a
-	centralised tool, you must use the software in a <quote>read
-	  only</quote> mode unless someone grants you permission to
-	commit changes to their central server.  Until then, you won't
-	be able to record changes, and your local modifications will
-	be at risk of corruption any time you try to update your
-	client's view of the repository.</para>
-
-      <sect3>
-	<title>The forking non-problem</title>
-
-	<para id="x_92">It has been suggested that distributed revision control
-	  tools pose some sort of risk to open source projects because
-	  they make it easy to <quote>fork</quote> the development of
-	  a project.  A fork happens when there are differences in
-	  opinion or attitude between groups of developers that cause
-	  them to decide that they can't work together any longer.
-	  Each side takes a more or less complete copy of the
-	  project's source code, and goes off in its own
-	  direction.</para>
-
-	<para id="x_93">Sometimes the camps in a fork decide to reconcile their
-	  differences. With a centralised revision control system, the
-	  <emphasis>technical</emphasis> process of reconciliation is
-	  painful, and has to be performed largely by hand.  You have
-	  to decide whose revision history is going to
-	  <quote>win</quote>, and graft the other team's changes into
-	  the tree somehow. This usually loses some or all of one
-	  side's revision history.</para>
+    <title>Using Code Examples</title>
 
-	<para id="x_94">What distributed tools do with respect to forking is
-	  they make forking the <emphasis>only</emphasis> way to
-	  develop a project.  Every single change that you make is
-	  potentially a fork point.  The great strength of this
-	  approach is that a distributed revision control tool has to
-	  be really good at <emphasis>merging</emphasis> forks,
-	  because forks are absolutely fundamental: they happen all
-	  the time.</para>
-
-	<para id="x_95">If every piece of work that everybody does, all the
-	  time, is framed in terms of forking and merging, then what
-	  the open source world refers to as a <quote>fork</quote>
-	  becomes <emphasis>purely</emphasis> a social issue.  If
-	  anything, distributed tools <emphasis>lower</emphasis> the
-	  likelihood of a fork:</para>
-	<itemizedlist>
-	  <listitem><para id="x_96">They eliminate the social distinction that
-	      centralised tools impose: that between insiders (people
-	      with commit access) and outsiders (people
-	      without).</para></listitem>
-	  <listitem><para id="x_97">They make it easier to reconcile after a
-	      social fork, because all that's involved from the
-	      perspective of the revision control software is just
-	      another merge.</para></listitem></itemizedlist>
-
-	<para id="x_98">Some people resist distributed tools because they want
-	  to retain tight control over their projects, and they
-	  believe that centralised tools give them this control.
-	  However, if you're of this belief, and you publish your CVS
-	  or Subversion repositories publicly, there are plenty of
-	  tools available that can pull out your entire project's
-	  history (albeit slowly) and recreate it somewhere that you
-	  don't control.  So while your control in this case is
-	  illusory, you are forgoing the ability to fluidly
-	  collaborate with whatever people feel compelled to mirror
-	  and fork your history.</para>
-
-      </sect3>
-    </sect2>
-    <sect2>
-      <title>Advantages for commercial projects</title>
-
-      <para id="x_99">Many commercial projects are undertaken by teams that are
-	scattered across the globe.  Contributors who are far from a
-	central server will see slower command execution and perhaps
-	less reliability.  Commercial revision control systems attempt
-	to ameliorate these problems with remote-site replication
-	add-ons that are typically expensive to buy and cantankerous
-	to administer.  A distributed system doesn't suffer from these
-	problems in the first place.  Better yet, you can easily set
-	up multiple authoritative servers, say one per site, so that
-	there's no redundant communication between repositories over
-	expensive long-haul network links.</para>
+    <para>This book is here to help you get your job done. In general,
+      you may use the code in this book in your programs and
+      documentation. You do not need to contact us for permission
+      unless you’re reproducing a significant portion of the code. For
+      example, writing a program that uses several chunks of code from
+      this book does not require permission. Selling or distributing a
+      CD-ROM of examples from O’Reilly books does require permission.
+      Answering a question by citing this book and quoting example
+      code does not require permission. Incorporating a significant
+      amount of example code from this book into your product’s
+      documentation does require permission.</para>
 
-      <para id="x_9a">Centralised revision control systems tend to have
-	relatively low scalability.  It's not unusual for an expensive
-	centralised system to fall over under the combined load of
-	just a few dozen concurrent users.  Once again, the typical
-	response tends to be an expensive and clunky replication
-	facility.  Since the load on a central server&emdash;if you have
-	one at all&emdash;is many times lower with a distributed tool
-	(because all of the data is replicated everywhere), a single
-	cheap server can handle the needs of a much larger team, and
-	replication to balance load becomes a simple matter of
-	scripting.</para>
-
-      <para id="x_9b">If you have an employee in the field, troubleshooting a
-	problem at a customer's site, they'll benefit from distributed
-	revision control. The tool will let them generate custom
-	builds, try different fixes in isolation from each other, and
-	search efficiently through history for the sources of bugs and
-	regressions in the customer's environment, all without needing
-	to connect to your company's network.</para>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Why choose Mercurial?</title>
-
-    <para id="x_9c">Mercurial has a unique set of properties that make it a
-      particularly good choice as a revision control system.</para>
-    <itemizedlist>
-      <listitem><para id="x_9d">It is easy to learn and use.</para></listitem>
-      <listitem><para id="x_9e">It is lightweight.</para></listitem>
-      <listitem><para id="x_9f">It scales excellently.</para></listitem>
-      <listitem><para id="x_a0">It is easy to
-	  customise.</para></listitem></itemizedlist>
-
-    <para id="x_a1">If you are at all familiar with revision control systems,
-      you should be able to get up and running with Mercurial in less
-      than five minutes.  Even if not, it will take no more than a few
-      minutes longer.  Mercurial's command and feature sets are
-      generally uniform and consistent, so you can keep track of a few
-      general rules instead of a host of exceptions.</para>
-
-    <para id="x_a2">On a small project, you can start working with Mercurial in
-      moments. Creating new changes and branches; transferring changes
-      around (whether locally or over a network); and history and
-      status operations are all fast.  Mercurial attempts to stay
-      nimble and largely out of your way by combining low cognitive
-      overhead with blazingly fast operations.</para>
-
-    <para id="x_a3">The usefulness of Mercurial is not limited to small
-      projects: it is used by projects with hundreds to thousands of
-      contributors, each containing tens of thousands of files and
-      hundreds of megabytes of source code.</para>
-
-    <para id="x_a4">If the core functionality of Mercurial is not enough for
-      you, it's easy to build on.  Mercurial is well suited to
-      scripting tasks, and its clean internals and implementation in
-      Python make it easy to add features in the form of extensions.
-      There are a number of popular and useful extensions already
-      available, ranging from helping to identify bugs to improving
-      performance.</para>
-
-  </sect1>
-  <sect1>
-    <title>Mercurial compared with other tools</title>
+    <para>We appreciate, but do not require, attribution. An
+      attribution usually includes the title, author, publisher, and
+      ISBN. For example: “<emphasis>Book Title</emphasis> by Some
+      Author. Copyright 2008 O’Reilly Media, Inc.,
+      978-0-596-xxxx-x.”</para>
 
-    <para id="x_a5">Before you read on, please understand that this section
-      necessarily reflects my own experiences, interests, and (dare I
-      say it) biases.  I have used every one of the revision control
-      tools listed below, in most cases for several years at a
-      time.</para>
-
-
-    <sect2>
-      <title>Subversion</title>
-
-      <para id="x_a6">Subversion is a popular revision control tool, developed
-	to replace CVS.  It has a centralised client/server
-	architecture.</para>
-
-      <para id="x_a7">Subversion and Mercurial have similarly named commands for
-	performing the same operations, so if you're familiar with
-	one, it is easy to learn to use the other.  Both tools are
-	portable to all popular operating systems.</para>
-
-      <para id="x_a8">Prior to version 1.5, Subversion had no useful support for
-	merges. At the time of writing, its merge tracking capability
-	is new, and known to be <ulink
-	  url="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">complicated 
-	  and buggy</ulink>.</para>
-
-      <para id="x_a9">Mercurial has a substantial performance advantage over
-	Subversion on every revision control operation I have
-	benchmarked.  I have measured its advantage as ranging from a
-	factor of two to a factor of six when compared with Subversion
-	1.4.3's <emphasis>ra_local</emphasis> file store, which is the
-	fastest access method available.  In more realistic
-	deployments involving a network-based store, Subversion will
-	be at a substantially larger disadvantage.  Because many
-	Subversion commands must talk to the server and Subversion
-	does not have useful replication facilities, server capacity
-	and network bandwidth become bottlenecks for modestly large
-	projects.</para>
-
-      <para id="x_aa">Additionally, Subversion incurs substantial storage
-	overhead to avoid network transactions for a few common
-	operations, such as finding modified files
-	(<literal>status</literal>) and displaying modifications
-	against the current revision (<literal>diff</literal>).  As a
-	result, a Subversion working copy is often the same size as,
-	or larger than, a Mercurial repository and working directory,
-	even though the Mercurial repository contains a complete
-	history of the project.</para>
-
-      <para id="x_ab">Subversion is widely supported by third party tools.
-	Mercurial currently lags considerably in this area.  This gap
-	is closing, however, and indeed some of Mercurial's GUI tools
-	now outshine their Subversion equivalents.  Like Mercurial,
-	Subversion has an excellent user manual.</para>
+    <para>If you feel your use of code examples falls outside fair use
+      or the permission given above, feel free to contact us at
+      <email>permissions@oreilly.com</email>.</para>
+  </sect1>
 
-      <para id="x_ac">Because Subversion doesn't store revision history on the
-	client, it is well suited to managing projects that deal with
-	lots of large, opaque binary files.  If you check in fifty
-	revisions to an incompressible 10MB file, Subversion's
-	client-side space usage stays constant The space used by any
-	distributed SCM will grow rapidly in proportion to the number
-	of revisions, because the differences between each revision
-	are large.</para>
-
-      <para id="x_ad">In addition, it's often difficult or, more usually,
-	impossible to merge different versions of a binary file.
-	Subversion's ability to let a user lock a file, so that they
-	temporarily have the exclusive right to commit changes to it,
-	can be a significant advantage to a project where binary files
-	are widely used.</para>
-
-      <para id="x_ae">Mercurial can import revision history from a Subversion
-	repository. It can also export revision history to a
-	Subversion repository.  This makes it easy to <quote>test the
-	  waters</quote> and use Mercurial and Subversion in parallel
-	before deciding to switch.  History conversion is incremental,
-	so you can perform an initial conversion, then small
-	additional conversions afterwards to bring in new
-	changes.</para>
-
-
-    </sect2>
-    <sect2>
-      <title>Git</title>
-
-      <para id="x_af">Git is a distributed revision control tool that was
-	developed for managing the Linux kernel source tree.  Like
-	Mercurial, its early design was somewhat influenced by
-	Monotone.</para>
-
-      <para id="x_b0">Git has a very large command set, with version 1.5.0
-	providing 139 individual commands.  It has something of a
-	reputation for being difficult to learn.  Compared to Git,
-	Mercurial has a strong focus on simplicity.</para>
-
-      <para id="x_b1">In terms of performance, Git is extremely fast.  In
-	several cases, it is faster than Mercurial, at least on Linux,
-	while Mercurial performs better on other operations.  However,
-	on Windows, the performance and general level of support that
-	Git provides is, at the time of writing, far behind that of
-	Mercurial.</para>
-
-      <para id="x_b2">While a Mercurial repository needs no maintenance, a Git
-	repository requires frequent manual <quote>repacks</quote> of
-	its metadata.  Without these, performance degrades, while
-	space usage grows rapidly.  A server that contains many Git
-	repositories that are not rigorously and frequently repacked
-	will become heavily disk-bound during backups, and there have
-	been instances of daily backups taking far longer than 24
-	hours as a result.  A freshly packed Git repository is
-	slightly smaller than a Mercurial repository, but an unpacked
-	repository is several orders of magnitude larger.</para>
-
-      <para id="x_b3">The core of Git is written in C.  Many Git commands are
-	implemented as shell or Perl scripts, and the quality of these
-	scripts varies widely. I have encountered several instances
-	where scripts charged along blindly in the presence of errors
-	that should have been fatal.</para>
+  <sect1>
+    <title>Safari® Books Online</title>
 
-      <para id="x_b4">Mercurial can import revision history from a Git
-	repository.</para>
-
-
-    </sect2>
-    <sect2>
-      <title>CVS</title>
-
-      <para id="x_b5">CVS is probably the most widely used revision control tool
-	in the world.  Due to its age and internal untidiness, it has
-	been only lightly maintained for many years.</para>
-
-      <para id="x_b6">It has a centralised client/server architecture.  It does
-	not group related file changes into atomic commits, making it
-	easy for people to <quote>break the build</quote>: one person
-	can successfully commit part of a change and then be blocked
-	by the need for a merge, causing other people to see only a
-	portion of the work they intended to do.  This also affects
-	how you work with project history.  If you want to see all of
-	the modifications someone made as part of a task, you will
-	need to manually inspect the descriptions and timestamps of
-	the changes made to each file involved (if you even know what
-	those files were).</para>
-
-      <para id="x_b7">CVS has a muddled notion of tags and branches that I will
-	not attempt to even describe.  It does not support renaming of
-	files or directories well, making it easy to corrupt a
-	repository.  It has almost no internal consistency checking
-	capabilities, so it is usually not even possible to tell
-	whether or how a repository is corrupt.  I would not recommend
-	CVS for any project, existing or new.</para>
-
-      <para id="x_b8">Mercurial can import CVS revision history.  However, there
-	are a few caveats that apply; these are true of every other
-	revision control tool's CVS importer, too.  Due to CVS's lack
-	of atomic changes and unversioned filesystem hierarchy, it is
-	not possible to reconstruct CVS history completely accurately;
-	some guesswork is involved, and renames will usually not show
-	up.  Because a lot of advanced CVS administration has to be
-	done by hand and is hence error-prone, it's common for CVS
-	importers to run into multiple problems with corrupted
-	repositories (completely bogus revision timestamps and files
-	that have remained locked for over a decade are just two of
-	the less interesting problems I can recall from personal
-	experience).</para>
-
-      <para id="x_b9">Mercurial can import revision history from a CVS
-	repository.</para>
-
-
-    </sect2>
-    <sect2>
-      <title>Commercial tools</title>
+    <note role="safarienabled">
+      <para>When you see a Safari® Books Online icon on the cover of
+	your favorite technology book, that means the book is
+	available online through the O’Reilly Network Safari
+	Bookshelf.</para>
+    </note>
 
-      <para id="x_ba">Perforce has a centralised client/server architecture,
-	with no client-side caching of any data.  Unlike modern
-	revision control tools, Perforce requires that a user run a
-	command to inform the server about every file they intend to
-	edit.</para>
-
-      <para id="x_bb">The performance of Perforce is quite good for small teams,
-	but it falls off rapidly as the number of users grows beyond a
-	few dozen. Modestly large Perforce installations require the
-	deployment of proxies to cope with the load their users
-	generate.</para>
-
-
-    </sect2>
-    <sect2>
-      <title>Choosing a revision control tool</title>
-
-      <para id="x_bc">With the exception of CVS, all of the tools listed above
-	have unique strengths that suit them to particular styles of
-	work.  There is no single revision control tool that is best
-	in all situations.</para>
-
-      <para id="x_bd">As an example, Subversion is a good choice for working
-	with frequently edited binary files, due to its centralised
-	nature and support for file locking.</para>
-
-      <para id="x_be">I personally find Mercurial's properties of simplicity,
-	performance, and good merge support to be a compelling
-	combination that has served me well for several years.</para>
-
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Switching from another tool to Mercurial</title>
-
-    <para id="x_bf">Mercurial is bundled with an extension named <literal
-	role="hg-ext">convert</literal>, which can incrementally
-      import revision history from several other revision control
-      tools.  By <quote>incremental</quote>, I mean that you can
-      convert all of a project's history to date in one go, then rerun
-      the conversion later to obtain new changes that happened after
-      the initial conversion.</para>
-
-    <para id="x_c0">The revision control tools supported by <literal
-	role="hg-ext">convert</literal> are as follows:</para>
-    <itemizedlist>
-      <listitem><para id="x_c1">Subversion</para></listitem>
-      <listitem><para id="x_c2">CVS</para></listitem>
-      <listitem><para id="x_c3">Git</para></listitem>
-      <listitem><para id="x_c4">Darcs</para></listitem></itemizedlist>
-
-    <para id="x_c5">In addition, <literal role="hg-ext">convert</literal> can
-      export changes from Mercurial to Subversion.  This makes it
-      possible to try Subversion and Mercurial in parallel before
-      committing to a switchover, without risking the loss of any
-      work.</para>
-
-    <para id="x_c6">The <command role="hg-ext-convert">convert</command> command
-      is easy to use.  Simply point it at the path or URL of the
-      source repository, optionally give it the name of the
-      destination repository, and it will start working.  After the
-      initial conversion, just run the same command again to import
-      new changes.</para>
+    <para>Safari offers a solution that’s better than e-books. It’s a
+      virtual library that lets you easily search thousands of top
+      tech books, cut and paste code samples, download chapters, and
+      find quick answers when you need the most accurate, current
+      information. Try it for free at <ulink role="orm:hideurl:ital"
+	url="http://my.safaribooksonline.com/?portal=oreilly">http://my.safaribooksonline.com</ulink>.</para>
   </sect1>
 
   <sect1>
-    <title>A short history of revision control</title>
+    <title>How to Contact Us</title>
 
-    <para id="x_c7">The best known of the old-time revision control tools is
-      SCCS (Source Code Control System), which Marc Rochkind wrote at
-      Bell Labs, in the early 1970s.  SCCS operated on individual
-      files, and required every person working on a project to have
-      access to a shared workspace on a single system.  Only one
-      person could modify a file at any time; arbitration for access
-      to files was via locks.  It was common for people to lock files,
-      and later forget to unlock them, preventing anyone else from
-      modifying those files without the help of an
-      administrator.</para>
+    <para>Please address comments and questions concerning this book
+      to the publisher:</para>
 
-    <para id="x_c8">Walter Tichy developed a free alternative to SCCS in the
-      early 1980s; he called his program RCS (Revision Control System).
-      Like SCCS, RCS required developers to work in a single shared
-      workspace, and to lock files to prevent multiple people from
-      modifying them simultaneously.</para>
+    <simplelist type="vert">
+      <member>O’Reilly Media, Inc.</member>
 
-    <para id="x_c9">Later in the 1980s, Dick Grune used RCS as a building block
-      for a set of shell scripts he initially called cmt, but then
-      renamed to CVS (Concurrent Versions System).  The big innovation
-      of CVS was that it let developers work simultaneously and
-      somewhat independently in their own personal workspaces.  The
-      personal workspaces prevented developers from stepping on each
-      other's toes all the time, as was common with SCCS and RCS. Each
-      developer had a copy of every project file, and could modify
-      their copies independently.  They had to merge their edits prior
-      to committing changes to the central repository.</para>
+      <member>1005 Gravenstein Highway North</member>
+
+      <member>Sebastopol, CA 95472</member>
 
-    <para id="x_ca">Brian Berliner took Grune's original scripts and rewrote
-      them in C, releasing in 1989 the code that has since developed
-      into the modern version of CVS.  CVS subsequently acquired the
-      ability to operate over a network connection, giving it a
-      client/server architecture.  CVS's architecture is centralised;
-      only the server has a copy of the history of the project. Client
-      workspaces just contain copies of recent versions of the
-      project's files, and a little metadata to tell them where the
-      server is.  CVS has been enormously successful; it is probably
-      the world's most widely used revision control system.</para>
+      <member>800-998-9938 (in the United States or Canada)</member>
 
-    <para id="x_cb">In the early 1990s, Sun Microsystems developed an early
-      distributed revision control system, called TeamWare.  A
-      TeamWare workspace contains a complete copy of the project's
-      history.  TeamWare has no notion of a central repository.  (CVS
-      relied upon RCS for its history storage; TeamWare used
-      SCCS.)</para>
+      <member>707-829-0515 (international or local)</member>
+
+      <member>707 829-0104 (fax)</member>
+    </simplelist>
 
-    <para id="x_cc">As the 1990s progressed, awareness grew of a number of
-      problems with CVS.  It records simultaneous changes to multiple
-      files individually, instead of grouping them together as a
-      single logically atomic operation.  It does not manage its file
-      hierarchy well; it is easy to make a mess of a repository by
-      renaming files and directories.  Worse, its source code is
-      difficult to read and maintain, which made the <quote>pain
-	level</quote> of fixing these architectural problems
-      prohibitive.</para>
+    <para>We have a web page for this book, where we list errata,
+      examples, and any additional information. You can access this
+      page at:</para>
 
-    <para id="x_cd">In 2001, Jim Blandy and Karl Fogel, two developers who had
-      worked on CVS, started a project to replace it with a tool that
-      would have a better architecture and cleaner code.  The result,
-      Subversion, does not stray from CVS's centralised client/server
-      model, but it adds multi-file atomic commits, better namespace
-      management, and a number of other features that make it a
-      generally better tool than CVS. Since its initial release, it
-      has rapidly grown in popularity.</para>
+    <simplelist type="vert">
+      <member><ulink url="http://www.oreilly.com/catalog/&lt;catalog
+	  page&gt;"></ulink></member>
+    </simplelist>
+
+    <remark>Don’t forget to update the &lt;url&gt; attribute,
+      too.</remark>
 
-    <para id="x_ce">More or less simultaneously, Graydon Hoare began working on
-      an ambitious distributed revision control system that he named
-      Monotone. While Monotone addresses many of CVS's design flaws
-      and has a peer-to-peer architecture, it goes beyond earlier (and
-      subsequent) revision control tools in a number of innovative
-      ways.  It uses cryptographic hashes as identifiers, and has an
-      integral notion of <quote>trust</quote> for code from different
-      sources.</para>
+    <para>To comment or ask technical questions about this book, send
+      email to:</para>
 
-    <para id="x_cf">Mercurial began life in 2005.  While a few aspects of its
-      design are influenced by Monotone, Mercurial focuses on ease of
-      use, high performance, and scalability to very large
-      projects.</para>
+    <simplelist type="vert">
+      <member><email>bookquestions@oreilly.com</email></member>
+    </simplelist>
 
-  </sect1>
-
-  <sect1>
-    <title>Colophon&emdash;this book is Free</title>
+    <para>For more information about our books, conferences, Resource
+      Centers, and the O’Reilly Network, see our web site at:</para>
 
-    <para id="x_d0">This book is licensed under the Open Publication License,
-      and is produced entirely using Free Software tools.  It is
-      typeset with DocBook XML.  Illustrations are drawn and rendered with
-      <ulink url="http://www.inkscape.org/">Inkscape</ulink>.</para>
-
-    <para id="x_d1">The complete source code for this book is published as a
-      Mercurial repository, at <ulink
-	url="http://hg.serpentine.com/mercurial/book">http://hg.serpentine.com/mercurial/book</ulink>.</para>
-
+    <simplelist type="vert">
+      <member><ulink url="http://www.oreilly.com"></ulink></member>
+    </simplelist>
   </sect1>
 </preface>
+
 <!--
 local variables: 
 sgml-parent-document: ("00book.xml" "book" "preface")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch01-intro.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,734 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:intro">
+  <?dbhtml filename="how-did-we-get-here.html"?>
+  <title>How did we get here?</title>
+
+  <sect1>
+    <title>Why revision control? Why Mercurial?</title>
+
+    <para id="x_6d">Revision control is the process of managing multiple
+      versions of a piece of information.  In its simplest form, this
+      is something that many people do by hand: every time you modify
+      a file, save it under a new name that contains a number, each
+      one higher than the number of the preceding version.</para>
+
+    <para id="x_6e">Manually managing multiple versions of even a single file is
+      an error-prone task, though, so software tools to help automate
+      this process have long been available.  The earliest automated
+      revision control tools were intended to help a single user to
+      manage revisions of a single file.  Over the past few decades,
+      the scope of revision control tools has expanded greatly; they
+      now manage multiple files, and help multiple people to work
+      together.  The best modern revision control tools have no
+      problem coping with thousands of people working together on
+      projects that consist of hundreds of thousands of files.</para>
+
+    <para id="x_6f">The arrival of distributed revision control is relatively
+      recent, and so far this new field has grown due to people's
+      willingness to explore ill-charted territory.</para>
+
+    <para id="x_70">I am writing a book about distributed revision control
+      because I believe that it is an important subject that deserves
+      a field guide. I chose to write about Mercurial because it is
+      the easiest tool to learn the terrain with, and yet it scales to
+      the demands of real, challenging environments where many other
+      revision control tools buckle.</para>
+
+    <sect2>
+      <title>Why use revision control?</title>
+
+      <para id="x_71">There are a number of reasons why you or your team might
+	want to use an automated revision control tool for a
+	project.</para>
+
+      <itemizedlist>
+	<listitem><para id="x_72">It will track the history and evolution of
+	    your project, so you don't have to.  For every change,
+	    you'll have a log of <emphasis>who</emphasis> made it;
+	    <emphasis>why</emphasis> they made it;
+	    <emphasis>when</emphasis> they made it; and
+	    <emphasis>what</emphasis> the change
+	    was.</para></listitem>
+	<listitem><para id="x_73">When you're working with other people,
+	    revision control software makes it easier for you to
+	    collaborate.  For example, when people more or less
+	    simultaneously make potentially incompatible changes, the
+	    software will help you to identify and resolve those
+	    conflicts.</para></listitem>
+	<listitem><para id="x_74">It can help you to recover from mistakes.  If
+	    you make a change that later turns out to be in error, you
+	    can revert to an earlier version of one or more files.  In
+	    fact, a <emphasis>really</emphasis> good revision control
+	    tool will even help you to efficiently figure out exactly
+	    when a problem was introduced (see <xref
+	      linkend="sec:undo:bisect"/> for details).</para></listitem>
+	<listitem><para id="x_75">It will help you to work simultaneously on,
+	    and manage the drift between, multiple versions of your
+	    project.</para></listitem>
+      </itemizedlist>
+
+      <para id="x_76">Most of these reasons are equally
+	valid&emdash;at least in theory&emdash;whether you're working
+	on a project by yourself, or with a hundred other
+	people.</para>
+
+      <para id="x_77">A key question about the practicality of revision control
+	at these two different scales (<quote>lone hacker</quote> and
+	<quote>huge team</quote>) is how its
+	<emphasis>benefits</emphasis> compare to its
+	<emphasis>costs</emphasis>.  A revision control tool that's
+	difficult to understand or use is going to impose a high
+	cost.</para>
+
+      <para id="x_78">A five-hundred-person project is likely to collapse under
+	its own weight almost immediately without a revision control
+	tool and process. In this case, the cost of using revision
+	control might hardly seem worth considering, since
+	<emphasis>without</emphasis> it, failure is almost
+	guaranteed.</para>
+
+      <para id="x_79">On the other hand, a one-person <quote>quick hack</quote>
+	might seem like a poor place to use a revision control tool,
+	because surely the cost of using one must be close to the
+	overall cost of the project.  Right?</para>
+
+      <para id="x_7a">Mercurial uniquely supports <emphasis>both</emphasis> of
+	these scales of development.  You can learn the basics in just
+	a few minutes, and due to its low overhead, you can apply
+	revision control to the smallest of projects with ease.  Its
+	simplicity means you won't have a lot of abstruse concepts or
+	command sequences competing for mental space with whatever
+	you're <emphasis>really</emphasis> trying to do.  At the same
+	time, Mercurial's high performance and peer-to-peer nature let
+	you scale painlessly to handle large projects.</para>
+
+      <para id="x_7b">No revision control tool can rescue a poorly run project,
+	but a good choice of tools can make a huge difference to the
+	fluidity with which you can work on a project.</para>
+
+    </sect2>
+
+    <sect2>
+      <title>The many names of revision control</title>
+
+      <para id="x_7c">Revision control is a diverse field, so much so that it is
+	referred to by many names and acronyms.  Here are a few of the
+	more common variations you'll encounter:</para>
+      <itemizedlist>
+	<listitem><para id="x_7d">Revision control (RCS)</para></listitem>
+	<listitem><para id="x_7e">Software configuration management (SCM), or
+	    configuration management</para></listitem>
+	<listitem><para id="x_7f">Source code management</para></listitem>
+	<listitem><para id="x_80">Source code control, or source
+	    control</para></listitem>
+	<listitem><para id="x_81">Version control
+	    (VCS)</para></listitem></itemizedlist>
+      <para id="x_82">Some people claim that these terms actually have different
+	meanings, but in practice they overlap so much that there's no
+	agreed or even useful way to tease them apart.</para>
+
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>About the examples in this book</title>
+
+    <para id="x_84">This book takes an unusual approach to code samples.  Every
+      example is <quote>live</quote>&emdash;each one is actually the result
+      of a shell script that executes the Mercurial commands you see.
+      Every time an image of the book is built from its sources, all
+      the example scripts are automatically run, and their current
+      results compared against their expected results.</para>
+
+    <para id="x_85">The advantage of this approach is that the examples are
+      always accurate; they describe <emphasis>exactly</emphasis> the
+      behavior of the version of Mercurial that's mentioned at the
+      front of the book.  If I update the version of Mercurial that
+      I'm documenting, and the output of some command changes, the
+      build fails.</para>
+
+    <para id="x_86">There is a small disadvantage to this approach, which is
+      that the dates and times you'll see in examples tend to be
+      <quote>squashed</quote> together in a way that they wouldn't be
+      if the same commands were being typed by a human.  Where a human
+      can issue no more than one command every few seconds, with any
+      resulting timestamps correspondingly spread out, my automated
+      example scripts run many commands in one second.</para>
+
+    <para id="x_87">As an instance of this, several consecutive commits in an
+      example can show up as having occurred during the same second.
+      You can see this occur in the <literal
+	role="hg-ext">bisect</literal> example in <xref
+	linkend="sec:undo:bisect"/>, for instance.</para>
+
+    <para id="x_88">So when you're reading examples, don't place too much weight
+      on the dates or times you see in the output of commands.  But
+      <emphasis>do</emphasis> be confident that the behavior you're
+      seeing is consistent and reproducible.</para>
+
+  </sect1>
+
+  <sect1>
+    <title>Trends in the field</title>
+
+    <para id="x_89">There has been an unmistakable trend in the development and
+      use of revision control tools over the past four decades, as
+      people have become familiar with the capabilities of their tools
+      and constrained by their limitations.</para>
+
+    <para id="x_8a">The first generation began by managing single files on
+      individual computers.  Although these tools represented a huge
+      advance over ad-hoc manual revision control, their locking model
+      and reliance on a single computer limited them to small,
+      tightly-knit teams.</para>
+
+    <para id="x_8b">The second generation loosened these constraints by moving
+      to network-centered architectures, and managing entire projects
+      at a time.  As projects grew larger, they ran into new problems.
+      With clients needing to talk to servers very frequently, server
+      scaling became an issue for large projects.  An unreliable
+      network connection could prevent remote users from being able to
+      talk to the server at all.  As open source projects started
+      making read-only access available anonymously to anyone, people
+      without commit privileges found that they could not use the
+      tools to interact with a project in a natural way, as they could
+      not record their changes.</para>
+
+    <para id="x_8c">The current generation of revision control tools is
+      peer-to-peer in nature.  All of these systems have dropped the
+      dependency on a single central server, and allow people to
+      distribute their revision control data to where it's actually
+      needed.  Collaboration over the Internet has moved from
+      constrained by technology to a matter of choice and consensus.
+      Modern tools can operate offline indefinitely and autonomously,
+      with a network connection only needed when syncing changes with
+      another repository.</para>
+
+  </sect1>
+  <sect1>
+    <title>A few of the advantages of distributed revision
+      control</title>
+
+    <para id="x_8d">Even though distributed revision control tools have for
+      several years been as robust and usable as their
+      previous-generation counterparts, people using older tools have
+      not yet necessarily woken up to their advantages.  There are a
+      number of ways in which distributed tools shine relative to
+      centralised ones.</para>
+
+    <para id="x_8e">For an individual developer, distributed tools are almost
+      always much faster than centralised tools.  This is for a simple
+      reason: a centralised tool needs to talk over the network for
+      many common operations, because most metadata is stored in a
+      single copy on the central server.  A distributed tool stores
+      all of its metadata locally.  All else being equal, talking over
+      the network adds overhead to a centralised tool.  Don't
+      underestimate the value of a snappy, responsive tool: you're
+      going to spend a lot of time interacting with your revision
+      control software.</para>
+
+    <para id="x_8f">Distributed tools are indifferent to the vagaries of your
+      server infrastructure, again because they replicate metadata to
+      so many locations.  If you use a centralised system and your
+      server catches fire, you'd better hope that your backup media
+      are reliable, and that your last backup was recent and actually
+      worked.  With a distributed tool, you have many backups
+      available on every contributor's computer.</para>
+
+    <para id="x_90">The reliability of your network will affect distributed
+      tools far less than it will centralised tools.  You can't even
+      use a centralised tool without a network connection, except for
+      a few highly constrained commands.  With a distributed tool, if
+      your network connection goes down while you're working, you may
+      not even notice.  The only thing you won't be able to do is talk
+      to repositories on other computers, something that is relatively
+      rare compared with local operations.  If you have a far-flung
+      team of collaborators, this may be significant.</para>
+
+    <sect2>
+      <title>Advantages for open source projects</title>
+
+      <para id="x_91">If you take a shine to an open source project and decide
+	that you would like to start hacking on it, and that project
+	uses a distributed revision control tool, you are at once a
+	peer with the people who consider themselves the
+	<quote>core</quote> of that project.  If they publish their
+	repositories, you can immediately copy their project history,
+	start making changes, and record your work, using the same
+	tools in the same ways as insiders.  By contrast, with a
+	centralised tool, you must use the software in a <quote>read
+	  only</quote> mode unless someone grants you permission to
+	commit changes to their central server.  Until then, you won't
+	be able to record changes, and your local modifications will
+	be at risk of corruption any time you try to update your
+	client's view of the repository.</para>
+
+      <sect3>
+	<title>The forking non-problem</title>
+
+	<para id="x_92">It has been suggested that distributed revision control
+	  tools pose some sort of risk to open source projects because
+	  they make it easy to <quote>fork</quote> the development of
+	  a project.  A fork happens when there are differences in
+	  opinion or attitude between groups of developers that cause
+	  them to decide that they can't work together any longer.
+	  Each side takes a more or less complete copy of the
+	  project's source code, and goes off in its own
+	  direction.</para>
+
+	<para id="x_93">Sometimes the camps in a fork decide to reconcile their
+	  differences. With a centralised revision control system, the
+	  <emphasis>technical</emphasis> process of reconciliation is
+	  painful, and has to be performed largely by hand.  You have
+	  to decide whose revision history is going to
+	  <quote>win</quote>, and graft the other team's changes into
+	  the tree somehow. This usually loses some or all of one
+	  side's revision history.</para>
+
+	<para id="x_94">What distributed tools do with respect to forking is
+	  they make forking the <emphasis>only</emphasis> way to
+	  develop a project.  Every single change that you make is
+	  potentially a fork point.  The great strength of this
+	  approach is that a distributed revision control tool has to
+	  be really good at <emphasis>merging</emphasis> forks,
+	  because forks are absolutely fundamental: they happen all
+	  the time.</para>
+
+	<para id="x_95">If every piece of work that everybody does, all the
+	  time, is framed in terms of forking and merging, then what
+	  the open source world refers to as a <quote>fork</quote>
+	  becomes <emphasis>purely</emphasis> a social issue.  If
+	  anything, distributed tools <emphasis>lower</emphasis> the
+	  likelihood of a fork:</para>
+	<itemizedlist>
+	  <listitem><para id="x_96">They eliminate the social distinction that
+	      centralised tools impose: that between insiders (people
+	      with commit access) and outsiders (people
+	      without).</para></listitem>
+	  <listitem><para id="x_97">They make it easier to reconcile after a
+	      social fork, because all that's involved from the
+	      perspective of the revision control software is just
+	      another merge.</para></listitem></itemizedlist>
+
+	<para id="x_98">Some people resist distributed tools because they want
+	  to retain tight control over their projects, and they
+	  believe that centralised tools give them this control.
+	  However, if you're of this belief, and you publish your CVS
+	  or Subversion repositories publicly, there are plenty of
+	  tools available that can pull out your entire project's
+	  history (albeit slowly) and recreate it somewhere that you
+	  don't control.  So while your control in this case is
+	  illusory, you are forgoing the ability to fluidly
+	  collaborate with whatever people feel compelled to mirror
+	  and fork your history.</para>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Advantages for commercial projects</title>
+
+      <para id="x_99">Many commercial projects are undertaken by teams that are
+	scattered across the globe.  Contributors who are far from a
+	central server will see slower command execution and perhaps
+	less reliability.  Commercial revision control systems attempt
+	to ameliorate these problems with remote-site replication
+	add-ons that are typically expensive to buy and cantankerous
+	to administer.  A distributed system doesn't suffer from these
+	problems in the first place.  Better yet, you can easily set
+	up multiple authoritative servers, say one per site, so that
+	there's no redundant communication between repositories over
+	expensive long-haul network links.</para>
+
+      <para id="x_9a">Centralised revision control systems tend to have
+	relatively low scalability.  It's not unusual for an expensive
+	centralised system to fall over under the combined load of
+	just a few dozen concurrent users.  Once again, the typical
+	response tends to be an expensive and clunky replication
+	facility.  Since the load on a central server&emdash;if you have
+	one at all&emdash;is many times lower with a distributed tool
+	(because all of the data is replicated everywhere), a single
+	cheap server can handle the needs of a much larger team, and
+	replication to balance load becomes a simple matter of
+	scripting.</para>
+
+      <para id="x_9b">If you have an employee in the field, troubleshooting a
+	problem at a customer's site, they'll benefit from distributed
+	revision control. The tool will let them generate custom
+	builds, try different fixes in isolation from each other, and
+	search efficiently through history for the sources of bugs and
+	regressions in the customer's environment, all without needing
+	to connect to your company's network.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Why choose Mercurial?</title>
+
+    <para id="x_9c">Mercurial has a unique set of properties that make it a
+      particularly good choice as a revision control system.</para>
+    <itemizedlist>
+      <listitem><para id="x_9d">It is easy to learn and use.</para></listitem>
+      <listitem><para id="x_9e">It is lightweight.</para></listitem>
+      <listitem><para id="x_9f">It scales excellently.</para></listitem>
+      <listitem><para id="x_a0">It is easy to
+	  customise.</para></listitem></itemizedlist>
+
+    <para id="x_a1">If you are at all familiar with revision control systems,
+      you should be able to get up and running with Mercurial in less
+      than five minutes.  Even if not, it will take no more than a few
+      minutes longer.  Mercurial's command and feature sets are
+      generally uniform and consistent, so you can keep track of a few
+      general rules instead of a host of exceptions.</para>
+
+    <para id="x_a2">On a small project, you can start working with Mercurial in
+      moments. Creating new changes and branches; transferring changes
+      around (whether locally or over a network); and history and
+      status operations are all fast.  Mercurial attempts to stay
+      nimble and largely out of your way by combining low cognitive
+      overhead with blazingly fast operations.</para>
+
+    <para id="x_a3">The usefulness of Mercurial is not limited to small
+      projects: it is used by projects with hundreds to thousands of
+      contributors, each containing tens of thousands of files and
+      hundreds of megabytes of source code.</para>
+
+    <para id="x_a4">If the core functionality of Mercurial is not enough for
+      you, it's easy to build on.  Mercurial is well suited to
+      scripting tasks, and its clean internals and implementation in
+      Python make it easy to add features in the form of extensions.
+      There are a number of popular and useful extensions already
+      available, ranging from helping to identify bugs to improving
+      performance.</para>
+
+  </sect1>
+  <sect1>
+    <title>Mercurial compared with other tools</title>
+
+    <para id="x_a5">Before you read on, please understand that this section
+      necessarily reflects my own experiences, interests, and (dare I
+      say it) biases.  I have used every one of the revision control
+      tools listed below, in most cases for several years at a
+      time.</para>
+
+
+    <sect2>
+      <title>Subversion</title>
+
+      <para id="x_a6">Subversion is a popular revision control tool, developed
+	to replace CVS.  It has a centralised client/server
+	architecture.</para>
+
+      <para id="x_a7">Subversion and Mercurial have similarly named commands for
+	performing the same operations, so if you're familiar with
+	one, it is easy to learn to use the other.  Both tools are
+	portable to all popular operating systems.</para>
+
+      <para id="x_a8">Prior to version 1.5, Subversion had no useful support for
+	merges. At the time of writing, its merge tracking capability
+	is new, and known to be <ulink
+	  url="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">complicated 
+	  and buggy</ulink>.</para>
+
+      <para id="x_a9">Mercurial has a substantial performance advantage over
+	Subversion on every revision control operation I have
+	benchmarked.  I have measured its advantage as ranging from a
+	factor of two to a factor of six when compared with Subversion
+	1.4.3's <emphasis>ra_local</emphasis> file store, which is the
+	fastest access method available.  In more realistic
+	deployments involving a network-based store, Subversion will
+	be at a substantially larger disadvantage.  Because many
+	Subversion commands must talk to the server and Subversion
+	does not have useful replication facilities, server capacity
+	and network bandwidth become bottlenecks for modestly large
+	projects.</para>
+
+      <para id="x_aa">Additionally, Subversion incurs substantial storage
+	overhead to avoid network transactions for a few common
+	operations, such as finding modified files
+	(<literal>status</literal>) and displaying modifications
+	against the current revision (<literal>diff</literal>).  As a
+	result, a Subversion working copy is often the same size as,
+	or larger than, a Mercurial repository and working directory,
+	even though the Mercurial repository contains a complete
+	history of the project.</para>
+
+      <para id="x_ab">Subversion is widely supported by third party tools.
+	Mercurial currently lags considerably in this area.  This gap
+	is closing, however, and indeed some of Mercurial's GUI tools
+	now outshine their Subversion equivalents.  Like Mercurial,
+	Subversion has an excellent user manual.</para>
+
+      <para id="x_ac">Because Subversion doesn't store revision history on the
+	client, it is well suited to managing projects that deal with
+	lots of large, opaque binary files.  If you check in fifty
+	revisions to an incompressible 10MB file, Subversion's
+	client-side space usage stays constant The space used by any
+	distributed SCM will grow rapidly in proportion to the number
+	of revisions, because the differences between each revision
+	are large.</para>
+
+      <para id="x_ad">In addition, it's often difficult or, more usually,
+	impossible to merge different versions of a binary file.
+	Subversion's ability to let a user lock a file, so that they
+	temporarily have the exclusive right to commit changes to it,
+	can be a significant advantage to a project where binary files
+	are widely used.</para>
+
+      <para id="x_ae">Mercurial can import revision history from a Subversion
+	repository. It can also export revision history to a
+	Subversion repository.  This makes it easy to <quote>test the
+	  waters</quote> and use Mercurial and Subversion in parallel
+	before deciding to switch.  History conversion is incremental,
+	so you can perform an initial conversion, then small
+	additional conversions afterwards to bring in new
+	changes.</para>
+
+
+    </sect2>
+    <sect2>
+      <title>Git</title>
+
+      <para id="x_af">Git is a distributed revision control tool that was
+	developed for managing the Linux kernel source tree.  Like
+	Mercurial, its early design was somewhat influenced by
+	Monotone.</para>
+
+      <para id="x_b0">Git has a very large command set, with version 1.5.0
+	providing 139 individual commands.  It has something of a
+	reputation for being difficult to learn.  Compared to Git,
+	Mercurial has a strong focus on simplicity.</para>
+
+      <para id="x_b1">In terms of performance, Git is extremely fast.  In
+	several cases, it is faster than Mercurial, at least on Linux,
+	while Mercurial performs better on other operations.  However,
+	on Windows, the performance and general level of support that
+	Git provides is, at the time of writing, far behind that of
+	Mercurial.</para>
+
+      <para id="x_b2">While a Mercurial repository needs no maintenance, a Git
+	repository requires frequent manual <quote>repacks</quote> of
+	its metadata.  Without these, performance degrades, while
+	space usage grows rapidly.  A server that contains many Git
+	repositories that are not rigorously and frequently repacked
+	will become heavily disk-bound during backups, and there have
+	been instances of daily backups taking far longer than 24
+	hours as a result.  A freshly packed Git repository is
+	slightly smaller than a Mercurial repository, but an unpacked
+	repository is several orders of magnitude larger.</para>
+
+      <para id="x_b3">The core of Git is written in C.  Many Git commands are
+	implemented as shell or Perl scripts, and the quality of these
+	scripts varies widely. I have encountered several instances
+	where scripts charged along blindly in the presence of errors
+	that should have been fatal.</para>
+
+      <para id="x_b4">Mercurial can import revision history from a Git
+	repository.</para>
+
+
+    </sect2>
+    <sect2>
+      <title>CVS</title>
+
+      <para id="x_b5">CVS is probably the most widely used revision control tool
+	in the world.  Due to its age and internal untidiness, it has
+	been only lightly maintained for many years.</para>
+
+      <para id="x_b6">It has a centralised client/server architecture.  It does
+	not group related file changes into atomic commits, making it
+	easy for people to <quote>break the build</quote>: one person
+	can successfully commit part of a change and then be blocked
+	by the need for a merge, causing other people to see only a
+	portion of the work they intended to do.  This also affects
+	how you work with project history.  If you want to see all of
+	the modifications someone made as part of a task, you will
+	need to manually inspect the descriptions and timestamps of
+	the changes made to each file involved (if you even know what
+	those files were).</para>
+
+      <para id="x_b7">CVS has a muddled notion of tags and branches that I will
+	not attempt to even describe.  It does not support renaming of
+	files or directories well, making it easy to corrupt a
+	repository.  It has almost no internal consistency checking
+	capabilities, so it is usually not even possible to tell
+	whether or how a repository is corrupt.  I would not recommend
+	CVS for any project, existing or new.</para>
+
+      <para id="x_b8">Mercurial can import CVS revision history.  However, there
+	are a few caveats that apply; these are true of every other
+	revision control tool's CVS importer, too.  Due to CVS's lack
+	of atomic changes and unversioned filesystem hierarchy, it is
+	not possible to reconstruct CVS history completely accurately;
+	some guesswork is involved, and renames will usually not show
+	up.  Because a lot of advanced CVS administration has to be
+	done by hand and is hence error-prone, it's common for CVS
+	importers to run into multiple problems with corrupted
+	repositories (completely bogus revision timestamps and files
+	that have remained locked for over a decade are just two of
+	the less interesting problems I can recall from personal
+	experience).</para>
+
+      <para id="x_b9">Mercurial can import revision history from a CVS
+	repository.</para>
+
+
+    </sect2>
+    <sect2>
+      <title>Commercial tools</title>
+
+      <para id="x_ba">Perforce has a centralised client/server architecture,
+	with no client-side caching of any data.  Unlike modern
+	revision control tools, Perforce requires that a user run a
+	command to inform the server about every file they intend to
+	edit.</para>
+
+      <para id="x_bb">The performance of Perforce is quite good for small teams,
+	but it falls off rapidly as the number of users grows beyond a
+	few dozen. Modestly large Perforce installations require the
+	deployment of proxies to cope with the load their users
+	generate.</para>
+
+
+    </sect2>
+    <sect2>
+      <title>Choosing a revision control tool</title>
+
+      <para id="x_bc">With the exception of CVS, all of the tools listed above
+	have unique strengths that suit them to particular styles of
+	work.  There is no single revision control tool that is best
+	in all situations.</para>
+
+      <para id="x_bd">As an example, Subversion is a good choice for working
+	with frequently edited binary files, due to its centralised
+	nature and support for file locking.</para>
+
+      <para id="x_be">I personally find Mercurial's properties of simplicity,
+	performance, and good merge support to be a compelling
+	combination that has served me well for several years.</para>
+
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Switching from another tool to Mercurial</title>
+
+    <para id="x_bf">Mercurial is bundled with an extension named <literal
+	role="hg-ext">convert</literal>, which can incrementally
+      import revision history from several other revision control
+      tools.  By <quote>incremental</quote>, I mean that you can
+      convert all of a project's history to date in one go, then rerun
+      the conversion later to obtain new changes that happened after
+      the initial conversion.</para>
+
+    <para id="x_c0">The revision control tools supported by <literal
+	role="hg-ext">convert</literal> are as follows:</para>
+    <itemizedlist>
+      <listitem><para id="x_c1">Subversion</para></listitem>
+      <listitem><para id="x_c2">CVS</para></listitem>
+      <listitem><para id="x_c3">Git</para></listitem>
+      <listitem><para id="x_c4">Darcs</para></listitem></itemizedlist>
+
+    <para id="x_c5">In addition, <literal role="hg-ext">convert</literal> can
+      export changes from Mercurial to Subversion.  This makes it
+      possible to try Subversion and Mercurial in parallel before
+      committing to a switchover, without risking the loss of any
+      work.</para>
+
+    <para id="x_c6">The <command role="hg-ext-convert">convert</command> command
+      is easy to use.  Simply point it at the path or URL of the
+      source repository, optionally give it the name of the
+      destination repository, and it will start working.  After the
+      initial conversion, just run the same command again to import
+      new changes.</para>
+  </sect1>
+
+  <sect1>
+    <title>A short history of revision control</title>
+
+    <para id="x_c7">The best known of the old-time revision control tools is
+      SCCS (Source Code Control System), which Marc Rochkind wrote at
+      Bell Labs, in the early 1970s.  SCCS operated on individual
+      files, and required every person working on a project to have
+      access to a shared workspace on a single system.  Only one
+      person could modify a file at any time; arbitration for access
+      to files was via locks.  It was common for people to lock files,
+      and later forget to unlock them, preventing anyone else from
+      modifying those files without the help of an
+      administrator.</para>
+
+    <para id="x_c8">Walter Tichy developed a free alternative to SCCS in the
+      early 1980s; he called his program RCS (Revision Control System).
+      Like SCCS, RCS required developers to work in a single shared
+      workspace, and to lock files to prevent multiple people from
+      modifying them simultaneously.</para>
+
+    <para id="x_c9">Later in the 1980s, Dick Grune used RCS as a building block
+      for a set of shell scripts he initially called cmt, but then
+      renamed to CVS (Concurrent Versions System).  The big innovation
+      of CVS was that it let developers work simultaneously and
+      somewhat independently in their own personal workspaces.  The
+      personal workspaces prevented developers from stepping on each
+      other's toes all the time, as was common with SCCS and RCS. Each
+      developer had a copy of every project file, and could modify
+      their copies independently.  They had to merge their edits prior
+      to committing changes to the central repository.</para>
+
+    <para id="x_ca">Brian Berliner took Grune's original scripts and rewrote
+      them in C, releasing in 1989 the code that has since developed
+      into the modern version of CVS.  CVS subsequently acquired the
+      ability to operate over a network connection, giving it a
+      client/server architecture.  CVS's architecture is centralised;
+      only the server has a copy of the history of the project. Client
+      workspaces just contain copies of recent versions of the
+      project's files, and a little metadata to tell them where the
+      server is.  CVS has been enormously successful; it is probably
+      the world's most widely used revision control system.</para>
+
+    <para id="x_cb">In the early 1990s, Sun Microsystems developed an early
+      distributed revision control system, called TeamWare.  A
+      TeamWare workspace contains a complete copy of the project's
+      history.  TeamWare has no notion of a central repository.  (CVS
+      relied upon RCS for its history storage; TeamWare used
+      SCCS.)</para>
+
+    <para id="x_cc">As the 1990s progressed, awareness grew of a number of
+      problems with CVS.  It records simultaneous changes to multiple
+      files individually, instead of grouping them together as a
+      single logically atomic operation.  It does not manage its file
+      hierarchy well; it is easy to make a mess of a repository by
+      renaming files and directories.  Worse, its source code is
+      difficult to read and maintain, which made the <quote>pain
+	level</quote> of fixing these architectural problems
+      prohibitive.</para>
+
+    <para id="x_cd">In 2001, Jim Blandy and Karl Fogel, two developers who had
+      worked on CVS, started a project to replace it with a tool that
+      would have a better architecture and cleaner code.  The result,
+      Subversion, does not stray from CVS's centralised client/server
+      model, but it adds multi-file atomic commits, better namespace
+      management, and a number of other features that make it a
+      generally better tool than CVS. Since its initial release, it
+      has rapidly grown in popularity.</para>
+
+    <para id="x_ce">More or less simultaneously, Graydon Hoare began working on
+      an ambitious distributed revision control system that he named
+      Monotone. While Monotone addresses many of CVS's design flaws
+      and has a peer-to-peer architecture, it goes beyond earlier (and
+      subsequent) revision control tools in a number of innovative
+      ways.  It uses cryptographic hashes as identifiers, and has an
+      integral notion of <quote>trust</quote> for code from different
+      sources.</para>
+
+    <para id="x_cf">Mercurial began life in 2005.  While a few aspects of its
+      design are influenced by Monotone, Mercurial focuses on ease of
+      use, high performance, and scalability to very large
+      projects.</para>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- a/en/ch01-tour-basic.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1035 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:tour-basic">
-  <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?>
-  <title>A tour of Mercurial: the basics</title>
-
-  <sect1 id="sec:tour:install">
-    <title>Installing Mercurial on your system</title>
-
-    <para id="x_1">Prebuilt binary packages of Mercurial are available for
-      every popular operating system.  These make it easy to start
-      using Mercurial on your computer immediately.</para>
-
-    <sect2>
-      <title>Windows</title>
-
-      <para id="x_c">The best version of Mercurial for Windows is
-	TortoiseHg, which can be found at <ulink
-	  url="http://bitbucket.org/tortoisehg/stable/wiki/Home">http://bitbucket.org/tortoisehg/stable/wiki/Home</ulink>. 
-	This package has no external dependencies; it <quote>just
-	  works</quote>.  It provides both command line and graphical
-	user interfaces.</para>
-
-    </sect2>
-
-    <sect2>
-      <title>Mac OS X</title>
-
-      <para id="x_a">Lee Cantey publishes an installer of Mercurial
-	for Mac OS X at <ulink
-	  url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>.</para>
-    </sect2>
-
-    <sect2>
-      <title>Linux</title>
-
-      <para id="x_2">Because each Linux distribution has its own packaging
-	tools, policies, and rate of development, it's difficult to
-	give a comprehensive set of instructions on how to install
-	Mercurial binaries.  The version of Mercurial that you will
-	end up with can vary depending on how active the person is who
-	maintains the package for your distribution.</para>
-
-      <para id="x_3">To keep things simple, I will focus on installing
-	Mercurial from the command line under the most popular Linux
-	distributions.  Most of these distributions provide graphical
-	package managers that will let you install Mercurial with a
-	single click; the package name to look for is
-	<literal>mercurial</literal>.</para>
-
-      <itemizedlist>
-	<listitem><para id="x_4">Ubuntu and Debian:</para>
-	  <programlisting>apt-get install mercurial</programlisting></listitem>
-	<listitem><para id="x_5">Fedora:</para>
-	  <programlisting>yum install mercurial</programlisting></listitem>
-	<listitem><para id="x_715">OpenSUSE:</para>
-	  <programlisting>zypper install mercurial</programlisting></listitem>
-	<listitem><para id="x_6">Gentoo:</para>
-	  <programlisting>emerge mercurial</programlisting></listitem>
-      </itemizedlist>
-
-    </sect2>
-    <sect2>
-      <title>Solaris</title>
-
-      <para id="x_9">SunFreeWare, at <ulink
-	  url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>, 
-	provides prebuilt packages of Mercurial.</para>
-
-    </sect2>
-
-  </sect1>
-
-  <sect1>
-    <title>Getting started</title>
-
-    <para id="x_e">To begin, we'll use the <command role="hg-cmd">hg
-	version</command> command to find out whether Mercurial is
-      installed properly.  The actual version information that it
-      prints isn't so important; we simply care whether the command
-      runs and prints anything at all.</para>
-
-    &interaction.tour.version;
-
-    <sect2>
-      <title>Built-in help</title>
-
-      <para id="x_f">Mercurial provides a built-in help system.  This is
-	  invaluable for those times when you find yourself stuck
-	  trying to remember how to run a command.  If you are
-	  completely stuck, simply run <command role="hg-cmd">hg
-	    help</command>; it will print a brief list of commands,
-	  along with a description of what each does.  If you ask for
-	  help on a specific command (as below), it prints more
-	  detailed information.</para>
-
-	&interaction.tour.help;
-
-	<para id="x_10">For a more impressive level of detail (which you won't
-	  usually need) run <command role="hg-cmd">hg help <option
-	      role="hg-opt-global">-v</option></command>.  The <option
-	    role="hg-opt-global">-v</option> option is short for
-	  <option role="hg-opt-global">--verbose</option>, and tells
-	  Mercurial to print more information than it usually
-	  would.</para>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Working with a repository</title>
-
-    <para id="x_11">In Mercurial, everything happens inside a
-      <emphasis>repository</emphasis>.  The repository for a project
-      contains all of the files that <quote>belong to</quote> that
-      project, along with a historical record of the project's
-      files.</para>
-
-    <para id="x_12">There's nothing particularly magical about a repository; it
-      is simply a directory tree in your filesystem that Mercurial
-      treats as special. You can rename or delete a repository any
-      time you like, using either the command line or your file
-      browser.</para>
-
-    <sect2>
-      <title>Making a local copy of a repository</title>
-
-      <para id="x_13"><emphasis>Copying</emphasis> a repository is just a little
-	bit special.  While you could use a normal file copying
-	command to make a copy of a repository, it's best to use a
-	built-in command that Mercurial provides.  This command is
-	called <command role="hg-cmd">hg clone</command>, because it
-	makes an identical copy of an existing repository.</para>
-
-      &interaction.tour.clone;
-
-      <para id="x_67c">One advantage of using <command role="hg-cmd">hg
-	  clone</command> is that, as we can see above, it lets us clone
-	repositories over the network.  Another is that it remembers
-	where we cloned from, which we'll find useful soon when we
-	want to fetch new changes from another repository.</para>
-
-      <para id="x_14">If our clone succeeded, we should now have a local
-	directory called <filename class="directory">hello</filename>.
-	This directory will contain some files.</para>
-
-      &interaction.tour.ls;
-
-      <para id="x_15">These files have the same contents and history in our
-	repository as they do in the repository we cloned.</para>
-
-      <para id="x_16">Every Mercurial repository is complete,
-	self-contained, and independent.  It contains its own private
-	copy of a project's files and history.  As we just mentioned,
-	a cloned repository remembers the location of the repository
-	it was cloned from, but Mercurial will not communicate with
-	that repository, or any other, unless you tell it to.</para>
-
-      <para id="x_17">What this means for now is that we're free to experiment
-	with our repository, safe in the knowledge that it's a private
-	<quote>sandbox</quote> that won't affect anyone else.</para>
-
-    </sect2>
-    <sect2>
-      <title>What's in a repository?</title>
-
-      <para id="x_18">When we take a more detailed look inside a repository, we
-	can see that it contains a directory named <filename
-	  class="directory">.hg</filename>.  This is where Mercurial
-	keeps all of its metadata for the repository.</para>
-
-      &interaction.tour.ls-a;
-
-      <para id="x_19">The contents of the <filename
-	  class="directory">.hg</filename> directory and its
-	subdirectories are private to Mercurial.  Every other file and
-	directory in the repository is yours to do with as you
-	please.</para>
-
-      <para id="x_1a">To introduce a little terminology, the <filename
-	  class="directory">.hg</filename> directory is the
-	<quote>real</quote> repository, and all of the files and
-	directories that coexist with it are said to live in the
-	<emphasis>working directory</emphasis>.  An easy way to
-	remember the distinction is that the
-	<emphasis>repository</emphasis> contains the
-	<emphasis>history</emphasis> of your project, while the
-	<emphasis>working directory</emphasis> contains a
-	<emphasis>snapshot</emphasis> of your project at a particular
-	point in history.</para>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>A tour through history</title>
-
-    <para id="x_1b">One of the first things we might want to do with a new,
-      unfamiliar repository is understand its history.  The <command
-	role="hg-cmd">hg log</command> command gives us a view of
-      the history of changes in the repository.</para>
-
-    &interaction.tour.log;
-
-    <para id="x_1c">By default, this command prints a brief paragraph of output
-      for each change to the project that was recorded.  In Mercurial
-      terminology, we call each of these recorded events a
-      <emphasis>changeset</emphasis>, because it can contain a record
-      of changes to several files.</para>
-
-    <para id="x_1d">The fields in a record of output from <command
-	role="hg-cmd">hg log</command> are as follows.</para>
-
-    <itemizedlist>
-      <listitem><para id="x_1e"><literal>changeset</literal>: This
-	  field has the format of a number, followed by a colon,
-	  followed by a hexadecimal (or <emphasis>hex</emphasis>)
-	  string.  These are <emphasis>identifiers</emphasis> for the
-	  changeset.  The hex string is a unique identifier: the same
-	  hex string will always refer to the same changeset in every
-	  copy of this repository. The
-	  number is shorter and easier to type than the hex string,
-	  but it isn't unique: the same number in two different clones
-	  of a repository may identify different changesets.</para>
-      </listitem>
-      <listitem><para id="x_1f"><literal>user</literal>: The identity of the
-	  person who created the changeset.  This is a free-form
-	  field, but it most often contains a person's name and email
-	  address.</para></listitem>
-      <listitem><para id="x_20"><literal>date</literal>: The date and time on
-	  which the changeset was created, and the timezone in which
-	  it was created.  (The date and time are local to that
-	  timezone; they display what time and date it was for the
-	  person who created the changeset.)</para></listitem>
-      <listitem><para id="x_21"><literal>summary</literal>: The first line of
-	  the text message that the creator of the changeset entered
-	  to describe the changeset.</para></listitem>
-      <listitem>
-	<para id="x_67d">Some changesets, such as the first in the list above,
-	  have a <literal>tag</literal> field.  A tag is another way
-	  to identify a changeset, by giving it an easy-to-remember
-	  name. (The tag named <literal>tip</literal> is special: it
-	  always refers to the newest change in a repository.)</para>
-      </listitem>
-    </itemizedlist>
-
-    <para id="x_22">The default output printed by <command
-	role="hg-cmd">hg log</command> is purely a summary; it is
-      missing a lot of detail.</para>
-
-    <para id="x_23"><xref linkend="fig:tour-basic:history"/> provides
-      a graphical representation of the history of the <filename
-	class="directory">hello</filename> repository, to make it a
-      little easier to see which direction history is
-      <quote>flowing</quote> in.  We'll be returning to this figure
-      several times in this chapter and the chapter that
-      follows.</para>
-
-    <figure id="fig:tour-basic:history">
-      <title>Graphical history of the <filename
-	  class="directory">hello</filename> repository</title>
-      <mediaobject>
-	<imageobject><imagedata fileref="figs/tour-history.png"/></imageobject>
-	<textobject><phrase>XXX add text</phrase></textobject>
-      </mediaobject>
-    </figure>
-
-    <sect2>
-      <title>Changesets, revisions, and talking to other
-	people</title>
-
-      <para id="x_25">As English is a notoriously sloppy language, and computer
-	science has a hallowed history of terminological confusion
-	(why use one term when four will do?), revision control has a
-	variety of words and phrases that mean the same thing.  If you
-	are talking about Mercurial history with other people, you
-	will find that the word <quote>changeset</quote> is often
-	compressed to <quote>change</quote> or (when written)
-	<quote>cset</quote>, and sometimes a changeset is referred to
-	as a <quote>revision</quote> or a <quote>rev</quote>.</para>
-
-      <para id="x_26">While it doesn't matter what <emphasis>word</emphasis> you
-	use to refer to the concept of <quote>a changeset</quote>, the
-	<emphasis>identifier</emphasis> that you use to refer to
-	<quote>a <emphasis>specific</emphasis> changeset</quote> is of
-	great importance. Recall that the <literal>changeset</literal>
-	field in the output from <command role="hg-cmd">hg
-	  log</command> identifies a changeset using both a number and
-	a hexadecimal string.</para>
-      <itemizedlist>
-	<listitem><para id="x_27">The revision number is a handy
-	    notation that is <emphasis>only valid in that
-	      repository</emphasis>.</para></listitem>
-	<listitem><para id="x_28">The hexadecimal string is the
-	    <emphasis>permanent, unchanging identifier</emphasis> that
-	    will always identify that exact changeset in
-	    <emphasis>every</emphasis> copy of the
-	    repository.</para></listitem></itemizedlist>
-
-      <para id="x_29">This distinction is important.  If you send
-	someone an email talking about <quote>revision 33</quote>,
-	there's a high likelihood that their revision 33 will
-	<emphasis>not be the same</emphasis> as yours.  The reason for
-	this is that a revision number depends on the order in which
-	changes arrived in a repository, and there is no guarantee
-	that the same changes will happen in the same order in
-	different repositories. Three changes <literal>a,b,c</literal>
-	can easily appear in one repository as
-	<literal>0,1,2</literal>, while in another as
-	<literal>0,2,1</literal>.</para>
-
-      <para id="x_2a">Mercurial uses revision numbers purely as a convenient
-	shorthand.  If you need to discuss a changeset with someone,
-	or make a record of a changeset for some other reason (for
-	example, in a bug report), use the hexadecimal
-	identifier.</para>
-
-    </sect2>
-    <sect2>
-      <title>Viewing specific revisions</title>
-
-      <para id="x_2b">To narrow the output of <command role="hg-cmd">hg
-	  log</command> down to a single revision, use the <option
-	  role="hg-opt-log">-r</option> (or <option
-	  role="hg-opt-log">--rev</option>) option.  You can use
-	either a revision number or a hexadecimal identifier,
-	and you can provide as many revisions as you want.</para>
-
-      &interaction.tour.log-r;
-
-      <para id="x_2c">If you want to see the history of several revisions
-	without having to list each one, you can use <emphasis>range
-	  notation</emphasis>; this lets you express the idea <quote>I
-	  want all revisions between <literal>abc</literal> and
-	  <literal>def</literal>, inclusive</quote>.</para>
-      
-	&interaction.tour.log.range;
-
-      <para id="x_2d">Mercurial also honours the order in which you specify
-	revisions, so <command role="hg-cmd">hg log -r 2:4</command>
-	prints 2, 3, and 4. while <command role="hg-cmd">hg log -r
-	  4:2</command> prints 4, 3, and 2.</para>
-
-    </sect2>
-    <sect2>
-      <title>More detailed information</title>
-
-      <para id="x_2e">While the summary information printed by <command
-	  role="hg-cmd">hg log</command> is useful if you already know
-	what you're looking for, you may need to see a complete
-	description of the change, or a list of the files changed, if
-	you're trying to decide whether a changeset is the one you're
-	looking for. The <command role="hg-cmd">hg log</command>
-	command's <option role="hg-opt-global">-v</option> (or <option
-	  role="hg-opt-global">--verbose</option>) option gives you
-	this extra detail.</para>
-
-      &interaction.tour.log-v;
-
-      <para id="x_2f">If you want to see both the description and
-	content of a change, add the <option
-	  role="hg-opt-log">-p</option> (or <option
-	  role="hg-opt-log">--patch</option>) option.  This displays
-	the content of a change as a <emphasis>unified diff</emphasis>
-	(if you've never seen a unified diff before, see <xref
-	  linkend="sec:mq:patch"/> for an overview).</para>
-
-      &interaction.tour.log-vp;
-
-      <para id="x_67e">The <option role="hg-opt-log">-p</option> option is
-	tremendously useful, so it's well worth remembering.</para>
-
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>All about command options</title>
-
-    <para id="x_30">Let's take a brief break from exploring Mercurial commands
-      to discuss a pattern in the way that they work; you may find
-      this useful to keep in mind as we continue our tour.</para>
-
-    <para id="x_31">Mercurial has a consistent and straightforward approach to
-      dealing with the options that you can pass to commands.  It
-      follows the conventions for options that are common to modern
-      Linux and Unix systems.</para>
-
-    <itemizedlist>
-      <listitem>
-	<para id="x_32">Every option has a long name.  For example, as
-	  we've already seen, the <command role="hg-cmd">hg
-	    log</command> command accepts a <option
-	    role="hg-opt-log">--rev</option> option.</para>
-      </listitem>
-      <listitem>
-	<para id="x_33">Most options have short names, too.  Instead
-	  of <option role="hg-opt-log">--rev</option>, we can use
-	  <option role="hg-opt-log">-r</option>.  (The reason that
-	  some options don't have short names is that the options in
-	  question are rarely used.)</para>
-      </listitem>
-      <listitem>
-	<para id="x_34">Long options start with two dashes (e.g.
-	  <option role="hg-opt-log">--rev</option>), while short
-	  options start with one (e.g. <option
-	    role="hg-opt-log">-r</option>).</para>
-      </listitem>
-      <listitem>
-	<para id="x_35">Option naming and usage is consistent across
-	  commands.  For example, every command that lets you specify
-	  a changeset ID or revision number accepts both <option
-	    role="hg-opt-log">-r</option> and <option
-	    role="hg-opt-log">--rev</option> arguments.</para>
-      </listitem>
-      <listitem>
-	<para id="x_67f">If you are using short options, you can save typing by
-	  running them together. For example, the command <command
-	    role="hg-cmd">hg log -v -p -r 2</command> can be written
-	  as <command role="hg-cmd">hg log -vpr2</command>.</para>
-      </listitem>
-    </itemizedlist>
-
-    <para id="x_36">In the examples throughout this book, I usually
-      use short options instead of long.  This simply reflects my own
-      preference, so don't read anything significant into it.</para>
-
-    <para id="x_37">Most commands that print output of some kind will print more
-      output when passed a <option role="hg-opt-global">-v</option>
-      (or <option role="hg-opt-global">--verbose</option>) option, and
-      less when passed <option role="hg-opt-global">-q</option> (or
-      <option role="hg-opt-global">--quiet</option>).</para>
-
-    <note>
-      <title>Option naming consistency</title>
-
-      <para id="x_680">Almost always, Mercurial commands use consistent option
-	names to refer to the same concepts.  For instance, if a
-	command deals with changesets, you'll always identify them
-	with <option role="hg-opt-log">--rev</option> or <option
-	  role="hg-opt-log">-r</option>.  This consistent use of
-	option names makes it easier to remember what options a
-	particular command takes.</para>
-    </note>
-
-  </sect1>
-  <sect1>
-    <title>Making and reviewing changes</title>
-
-    <para id="x_38">Now that we have a grasp of viewing history in Mercurial,
-      let's take a look at making some changes and examining
-      them.</para>
-
-    <para id="x_39">The first thing we'll do is isolate our experiment in a
-      repository of its own.  We use the <command role="hg-cmd">hg
-	clone</command> command, but we don't need to clone a copy of
-      the remote repository.  Since we already have a copy of it
-      locally, we can just clone that instead.  This is much faster
-      than cloning over the network, and cloning a local repository
-      uses less disk space in most cases, too<footnote>
-	<para id="x_681">The saving of space arises when source and destination
-	  repositories are on the same filesystem, in which case
-	  Mercurial will use hardlinks to do copy-on-write sharing of
-	  its internal metadata.  If that explanation meant nothing to
-	  you, don't worry: everything happens transparently and
-	  automatically, and you don't need to understand it.</para>
-	</footnote>.</para>
-
-    &interaction.tour.reclone;
-
-    <para id="x_3a">As an aside, it's often good practice to keep a
-      <quote>pristine</quote> copy of a remote repository around,
-      which you can then make temporary clones of to create sandboxes
-      for each task you want to work on.  This lets you work on
-      multiple tasks in parallel, each isolated from the others until
-      it's complete and you're ready to integrate it back.  Because
-      local clones are so cheap, there's almost no overhead to cloning
-      and destroying repositories whenever you want.</para>
-
-    <para id="x_3b">In our <filename class="directory">my-hello</filename>
-      repository, we have a file <filename>hello.c</filename> that
-      contains the classic <quote>hello, world</quote> program.</para>
-
-    &interaction.tour.cat1;
-
-    <para id="x_682">Let's edit this file so that it prints a second line of
-      output.</para>
-
-    &interaction.tour.cat2;
-
-    <para id="x_3c">Mercurial's <command role="hg-cmd">hg status</command>
-      command will tell us what Mercurial knows about the files in the
-      repository.</para>
-
-    &interaction.tour.status;
-
-    <para id="x_3d">The <command role="hg-cmd">hg status</command> command
-      prints no output for some files, but a line starting with
-      <quote><literal>M</literal></quote> for
-      <filename>hello.c</filename>.  Unless you tell it to, <command
-	role="hg-cmd">hg status</command> will not print any output
-      for files that have not been modified.</para>
-
-    <para id="x_3e">The <quote><literal>M</literal></quote> indicates that
-      Mercurial has noticed that we modified
-      <filename>hello.c</filename>.  We didn't need to
-      <emphasis>inform</emphasis> Mercurial that we were going to
-      modify the file before we started, or that we had modified the
-      file after we were done; it was able to figure this out
-      itself.</para>
-
-    <para id="x_3f">It's somewhat helpful to know that we've modified
-      <filename>hello.c</filename>, but we might prefer to know
-      exactly <emphasis>what</emphasis> changes we've made to it.  To
-      do this, we use the <command role="hg-cmd">hg diff</command>
-      command.</para>
-
-    &interaction.tour.diff;
-
-    <tip>
-      <title>Understanding patches</title>
-
-      <para id="x_683">Remember to take a look at <xref
-	  linkend="sec:mq:patch"/> if you don't know how to read
-	output above.</para>
-    </tip>
-  </sect1>
-  <sect1>
-    <title>Recording changes in a new changeset</title>
-
-    <para id="x_40">We can modify files, build and test our changes, and use
-      <command role="hg-cmd">hg status</command> and <command
-	role="hg-cmd">hg diff</command> to review our changes, until
-      we're satisfied with what we've done and arrive at a natural
-      stopping point where we want to record our work in a new
-      changeset.</para>
-
-    <para id="x_41">The <command role="hg-cmd">hg commit</command> command lets
-      us create a new changeset; we'll usually refer to this as
-      <quote>making a commit</quote> or
-      <quote>committing</quote>.</para>
-
-    <sect2>
-      <title>Setting up a username</title>
-
-      <para id="x_42">When you try to run <command role="hg-cmd">hg
-	  commit</command> for the first time, it is not guaranteed to
-	succeed.  Mercurial records your name and address with each
-	change that you commit, so that you and others will later be
-	able to tell who made each change.  Mercurial tries to
-	automatically figure out a sensible username to commit the
-	change with.  It will attempt each of the following methods,
-	in order:</para>
-      <orderedlist>
-	<listitem><para id="x_43">If you specify a <option
-	      role="hg-opt-commit">-u</option> option to the <command
-	      role="hg-cmd">hg commit</command> command on the command
-	    line, followed by a username, this is always given the
-	    highest precedence.</para></listitem>
-	<listitem><para id="x_44">If you have set the <envar>HGUSER</envar>
-	    environment variable, this is checked
-	    next.</para></listitem>
-	<listitem><para id="x_45">If you create a file in your home
-	    directory called <filename
-	      role="special">.hgrc</filename>, with a <envar
-	      role="rc-item-ui">username</envar> entry, that will be
-	    used next.  To see what the contents of this file should
-	    look like, refer to <xref
-	      linkend="sec:tour-basic:username"/>
-	    below.</para></listitem>
-	<listitem><para id="x_46">If you have set the <envar>EMAIL</envar>
-	    environment variable, this will be used
-	    next.</para></listitem>
-	<listitem><para id="x_47">Mercurial will query your system to find out
-	    your local user name and host name, and construct a
-	    username from these components. Since this often results
-	    in a username that is not very useful, it will print a
-	    warning if it has to do
-	    this.</para></listitem>
-      </orderedlist>
-      <para id="x_48">If all of these mechanisms fail, Mercurial will
-	  fail, printing an error message.  In this case, it will not
-	  let you commit until you set up a
-	  username.</para>
-      <para id="x_49">You should think of the <envar>HGUSER</envar> environment
-	variable and the <option role="hg-opt-commit">-u</option>
-	option to the <command role="hg-cmd">hg commit</command>
-	command as ways to <emphasis>override</emphasis> Mercurial's
-	default selection of username.  For normal use, the simplest
-	and most robust way to set a username for yourself is by
-	creating a <filename role="special">.hgrc</filename> file; see
-	below for details.</para>
-      <sect3 id="sec:tour-basic:username">
-	<title>Creating a Mercurial configuration file</title>
-
-	<para id="x_4a">To set a user name, use your favorite editor
-	  to create a file called <filename
-	    role="special">.hgrc</filename> in your home directory.
-	  Mercurial will use this file to look up your personalised
-	  configuration settings.  The initial contents of your
-	  <filename role="special">.hgrc</filename> should look like
-	  this.</para>
-
-	<tip>
-	  <title><quote>Home directory</quote> on Windows</title>
-
-	  <para id="x_716">When we refer to your home directory, on an English
-	    language installation of Windows this will usually be a
-	    folder named after your user name in
-	    <filename>C:\Documents and Settings</filename>.  You can
-	    find out the exact name of your home directory by opening
-	    a command prompt window and running the following
-	    command.</para>
-
-	  <screen><prompt>C:\></prompt> <userinput>echo %UserProfile%</userinput></screen>
-	</tip>
-
-	<programlisting># This is a Mercurial configuration file.
-[ui]
-username = Firstname Lastname &lt;email.address@example.net&gt;</programlisting>
-
-	<para id="x_4b">The <quote><literal>[ui]</literal></quote> line begins a
-	  <emphasis>section</emphasis> of the config file, so you can
-	  read the <quote><literal>username = ...</literal></quote>
-	  line as meaning <quote>set the value of the
-	    <literal>username</literal> item in the
-	    <literal>ui</literal> section</quote>. A section continues
-	  until a new section begins, or the end of the file.
-	  Mercurial ignores empty lines and treats any text from
-	  <quote><literal>#</literal></quote> to the end of a line as
-	  a comment.</para>
-      </sect3>
-
-      <sect3>
-	<title>Choosing a user name</title>
-
-	<para id="x_4c">You can use any text you like as the value of
-	  the <literal>username</literal> config item, since this
-	  information is for reading by other people, but will not be
-	  interpreted by Mercurial.  The convention that most people
-	  follow is to use their name and email address, as in the
-	  example above.</para>
-	<note>
-	  <para id="x_4d">Mercurial's built-in web server obfuscates
-	    email addresses, to make it more difficult for the email
-	    harvesting tools that spammers use. This reduces the
-	    likelihood that you'll start receiving more junk email if
-	    you publish a Mercurial repository on the
-	    web.</para></note>
-      </sect3>
-    </sect2>
-    <sect2>
-      <title>Writing a commit message</title>
-
-      <para id="x_4e">When we commit a change, Mercurial drops us into
-	a text editor, to enter a message that will describe the
-	modifications we've made in this changeset.  This is called
-	the <emphasis>commit message</emphasis>.  It will be a record
-	for readers of what we did and why, and it will be printed by
-	<command role="hg-cmd">hg log</command> after we've finished
-	committing.</para>
-
-       &interaction.tour.commit;
-
-      <para id="x_4f">The editor that the <command role="hg-cmd">hg
-	  commit</command> command drops us into will contain an empty
-	line or two, followed by a number of lines starting with
-	<quote><literal>HG:</literal></quote>.</para>
-
-    <programlisting>
-This is where I type my commit comment.
-
-HG: Enter commit message.  Lines beginning with 'HG:' are removed.
-HG: --
-HG: user: Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-HG: branch 'default'
-HG: changed hello.c</programlisting>
-
-      <para id="x_50">Mercurial ignores the lines that start with
-	<quote><literal>HG:</literal></quote>; it uses them only to
-	tell us which files it's recording changes to.  Modifying or
-	deleting these lines has no effect.</para>
-    </sect2>
-    <sect2>
-      <title>Writing a good commit message</title>
-
-      <para id="x_51">Since <command role="hg-cmd">hg log</command>
-	only prints the first line of a commit message by default,
-	it's best to write a commit message whose first line stands
-	alone.  Here's a real example of a commit message that
-	<emphasis>doesn't</emphasis> follow this guideline, and hence
-	has a summary that is not readable.</para>
-
-      <programlisting>
-changeset:   73:584af0e231be
-user:        Censored Person &lt;censored.person@example.org&gt;
-date:        Tue Sep 26 21:37:07 2006 -0700
-summary:     include buildmeister/commondefs. Add exports.</programlisting>
-
-      <para id="x_52">As far as the remainder of the contents of the
-	commit message are concerned, there are no hard-and-fast
-	rules.  Mercurial itself doesn't interpret or care about the
-	contents of the commit message, though your project may have
-	policies that dictate a certain kind of formatting.</para>
-      <para id="x_53">My personal preference is for short, but
-	informative, commit messages that tell me something that I
-	can't figure out with a quick glance at the output of <command
-	  role="hg-cmd">hg log --patch</command>.</para>
-      <para id="x_55">If we run the <command role="hg-cmd">hg
-	  commit</command> command without any arguments, it records
-	all of the changes we've made, as reported by <command
-	  role="hg-cmd">hg status</command> and <command
-	  role="hg-cmd">hg diff</command>.</para>
-
-      <note>
-	<title>A surprise for Subversion users</title>
-
-	<para id="x_717">Like other Mercurial commands, if we don't supply
-	  explicit names to commit to the <command role="hg-cmd">hg
-	    commit</command>, it will operate across a repository's
-	  entire working directory.  Be wary of this if you're coming
-	  from the Subversion or CVS world, since you might expect it
-	  to operate only on the current directory that you happen to
-	  be visiting and its subdirectories.</para>
-      </note>
-    </sect2>
-
-    <sect2>
-      <title>Aborting a commit</title>
-
-      <para id="x_54">If you decide that you don't want to commit
-	while in the middle of editing a commit message, simply exit
-	from your editor without saving the file that it's editing.
-	This will cause nothing to happen to either the repository or
-	the working directory.</para>
-    </sect2>
-
-    <sect2>
-      <title>Admiring our new handiwork</title>
-
-      <para id="x_56">Once we've finished the commit, we can use the
-	<command role="hg-cmd">hg tip</command> command to display the
-	changeset we just created.  This command produces output that
-	is identical to <command role="hg-cmd">hg log</command>, but
-	it only displays the newest revision in the repository.</para>
-
-      &interaction.tour.tip;
-
-      <para id="x_57">We refer to the newest revision in the
-	repository as the <emphasis>tip revision</emphasis>, or simply
-	the <emphasis>tip</emphasis>.</para>
-
-      <para id="x_684">By the way, the <command role="hg-cmd">hg tip</command>
-	command accepts many of the same options as <command
-	  role="hg-cmd">hg log</command>, so <option
-	  role="hg-opt-global">-v</option> above indicates <quote>be
-	  verbose</quote>, <option role="hg-opt-tip">-p</option>
-	specifies <quote>print a patch</quote>.  The use of <option
-	  role="hg-opt-tip">-p</option> to print patches is another
-	example of the consistent naming we mentioned earlier.</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>Sharing changes</title>
-
-    <para id="x_58">We mentioned earlier that repositories in
-      Mercurial are self-contained.  This means that the changeset we
-      just created exists only in our <filename
-	class="directory">my-hello</filename> repository.  Let's look
-      at a few ways that we can propagate this change into other
-      repositories.</para>
-
-    <sect2 id="sec:tour:pull">
-      <title>Pulling changes from another repository</title>
-
-      <para id="x_59">To get started, let's clone our original
-	<filename class="directory">hello</filename> repository, which
-	does not contain the change we just committed.  We'll call our
-	temporary repository <filename
-	  class="directory">hello-pull</filename>.</para>
-
-      &interaction.tour.clone-pull;
-
-      <para id="x_5a">We'll use the <command role="hg-cmd">hg
-	  pull</command> command to bring changes from <filename
-	  class="directory">my-hello</filename> into <filename
-	  class="directory">hello-pull</filename>.  However, blindly
-	pulling unknown changes into a repository is a somewhat scary
-	prospect.  Mercurial provides the <command role="hg-cmd">hg
-	  incoming</command> command to tell us what changes the
-	<command role="hg-cmd">hg pull</command> command
-	<emphasis>would</emphasis> pull into the repository, without
-	actually pulling the changes in.</para>
-
-      &interaction.tour.incoming;
-
-      <para id="x_5c">Bringing changes into a repository is a simple
-	matter of running the <command role="hg-cmd">hg pull</command>
-	command, and optionally telling it which repository to pull from.</para>
-
-      &interaction.tour.pull;
-
-      <para id="x_5d">As you can see from the before-and-after output
-	of <command role="hg-cmd">hg tip</command>, we have
-	successfully pulled changes into our repository.  However,
-	Mercurial separates pulling changes in from updating the
-	working directory. There remains one step before we will see
-	the changes that we just pulled appear in the working
-	directory.</para>
-
-      <tip>
-	<title>Pulling specific changes</title>
-
-	<para id="x_5b">It is possible that due to the delay between
-	  running <command role="hg-cmd">hg incoming</command> and
-	  <command role="hg-cmd">hg pull</command>, you may not see
-	  all changesets that will be brought from the other
-	  repository. Suppose you're pulling changes from a repository
-	  on the network somewhere. While you are looking at the
-	  <command role="hg-cmd">hg incoming</command> output, and
-	  before you pull those changes, someone might have committed
-	  something in the remote repository. This means that it's
-	  possible to pull more changes than you saw when using
-	  <command role="hg-cmd">hg incoming</command>.</para>
-
-	<para id="x_718">If you only want to pull precisely the changes that were
-	  listed by <command role="hg-cmd">hg incoming</command>, or
-	  you have some other reason to pull a subset of changes,
-	  simply identify the change that you want to pull by its
-	  changeset ID, e.g. <command>hg pull
-	    -r7e95bb</command>.</para>
-      </tip>
-    </sect2>
-
-    <sect2>
-      <title>Updating the working directory</title>
-
-      <para id="x_5e">We have so far glossed over the relationship
-	between a repository and its working directory.  The <command
-	  role="hg-cmd">hg pull</command> command that we ran in
-	<xref linkend="sec:tour:pull"/> brought changes into the
-	repository, but if we check, there's no sign of those changes
-	in the working directory.  This is because <command
-	  role="hg-cmd">hg pull</command> does not (by default) touch
-	the working directory.  Instead, we use the <command
-	  role="hg-cmd">hg update</command> command to do this.</para>
-
-      &interaction.tour.update;
-
-      <para id="x_5f">It might seem a bit strange that <command
-	  role="hg-cmd">hg pull</command> doesn't update the working
-	directory automatically.  There's actually a good reason for
-	this: you can use <command role="hg-cmd">hg update</command>
-	to update the working directory to the state it was in at
-	<emphasis>any revision</emphasis> in the history of the
-	repository.  If you had the working directory updated to an
-	old revision&emdash;to hunt down the origin of a bug,
-	say&emdash;and ran a <command role="hg-cmd">hg pull</command>
-	which automatically updated the working directory to a new
-	revision, you might not be terribly happy.</para>
-
-      <para id="x_60">Since pull-then-update is such a common sequence
-	of operations, Mercurial lets you combine the two by passing
-	the <option role="hg-opt-pull">-u</option> option to <command
-	  role="hg-cmd">hg pull</command>.</para>
-
-      <para id="x_61">If you look back at the output of <command
-	  role="hg-cmd">hg pull</command> in <xref
-	    linkend="sec:tour:pull"/> when we ran it without <option
-	  role="hg-opt-pull">-u</option>, you can see that it printed
-	a helpful reminder that we'd have to take an explicit step to
-	update the working directory.</para>
-
-      <para id="x_62">To find out what revision the working directory
-	is at, use the <command role="hg-cmd">hg parents</command>
-	command.</para>
-
-      &interaction.tour.parents;
-
-      <para id="x_63">If you look back at <xref
-	  linkend="fig:tour-basic:history"/>, you'll see arrows
-	connecting each changeset.  The node that the arrow leads
-	<emphasis>from</emphasis> in each case is a parent, and the
-	node that the arrow leads <emphasis>to</emphasis> is its
-	child.  The working directory has a parent in just the same
-	way; this is the changeset that the working directory
-	currently contains.</para>
-
-      <para id="x_64">To update the working directory to a particular
-	revision, give a revision number or changeset ID to the
-	<command role="hg-cmd">hg update</command> command.</para>
-
-      &interaction.tour.older;
-
-      <para id="x_65">If you omit an explicit revision, <command
-	  role="hg-cmd">hg update</command> will update to the tip
-	revision, as shown by the second call to <command
-	  role="hg-cmd">hg update</command> in the example
-	above.</para>
-    </sect2>
-
-    <sect2>
-      <title>Pushing changes to another repository</title>
-
-      <para id="x_66">Mercurial lets us push changes to another
-	repository, from the repository we're currently visiting. As
-	with the example of <command role="hg-cmd">hg pull</command>
-	above, we'll create a temporary repository to push our changes
-	into.</para>
-
-      &interaction.tour.clone-push;
-
-      <para id="x_67">The <command role="hg-cmd">hg outgoing</command>
-	command tells us what changes would be pushed into another
-	repository.</para>
-
-      &interaction.tour.outgoing;
-
-      <para id="x_68">And the <command role="hg-cmd">hg push</command>
-	command does the actual push.</para>
-
-      &interaction.tour.push;
-
-      <para id="x_69">As with <command role="hg-cmd">hg
-	  pull</command>, the <command role="hg-cmd">hg push</command>
-	command does not update the working directory in the
-	repository that it's pushing changes into. Unlike <command
-	  role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg
-	  push</command> does not provide a <literal>-u</literal>
-	option that updates the other repository's working directory.
-	This asymmetry is deliberate: the repository we're pushing to
-	might be on a remote server and shared between several people.
-	If we were to update its working directory while someone was
-	working in it, their work would be disrupted.</para>
-
-      <para id="x_6a">What happens if we try to pull or push changes
-	  and the receiving repository already has those changes?
-	  Nothing too exciting.</para>
-
-      &interaction.tour.push.nothing;
-    </sect2>
-
-    <sect2>
-      <title>Default locations</title>
-
-      <para id="x_719">When we clone a repository, Mercurial records the location
-	of the repository we cloned in the
-	<filename>.hg/hgrc</filename> file of the new repository.  If
-	we don't supply a location to <command>hg pull</command> from
-	or <command>hg push</command> to, those commands will use this
-	location as a default.  The <command>hg incoming</command>
-	and <command>hg outgoing</command> commands do so too.</para>
-
-      <para id="x_71a">If you open a repository's <filename>.hg/hgrc</filename>
-	file in a text editor, you will see contents like the
-	following.</para>
-
-      <programlisting>[paths]
-default = http://www.selenic.com/repo/hg</programlisting>
-
-      <para id="x_71b">It is possible&emdash;and often useful&emdash;to have the
-	default location for <command>hg push</command> and
-	<command>hg outgoing</command> be different from those for
-	<command>hg pull</command> and <command>hg incoming</command>.
-	We can do this by adding a <literal>default-push</literal>
-	entry to the <literal>[paths]</literal> section of the
-	<filename>.hg/hgrc</filename> file, as follows.</para>
-
-      <programlisting>[paths]
-default = http://www.selenic.com/repo/hg
-default-push = http://hg.example.com/hg</programlisting>
-    </sect2>
-
-    <sect2>
-      <title>Sharing changes over a network</title>
-
-      <para id="x_6b">The commands we have covered in the previous few
-	  sections are not limited to working with local repositories.
-	  Each works in exactly the same fashion over a network
-	  connection; simply pass in a URL instead of a local
-	  path.</para>
-	
-      &interaction.tour.outgoing.net;
-
-      <para id="x_6c">In this example, we can see what changes we
-	could push to the remote repository, but the repository is
-	understandably not set up to let anonymous users push to
-	it.</para>
-
-      &interaction.tour.push.net;
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>Starting a new project</title>
-
-    <para id="x_71c">It is just as easy to begin a new project as to work on one
-      that already exists.  The <command>hg init</command> command
-      creates a new, empty Mercurial repository.</para>
-
-    &interaction.ch01-new.init;
-
-    <para id="x_71d">This simply creates a repository named
-      <filename>myproject</filename> in the current directory.</para>
-
-    &interaction.ch01-new.ls;
-
-    <para id="x_71e">We can tell that <filename>myproject</filename> is a
-      Mercurial repository, because it contains a
-      <filename>.hg</filename> directory.</para>
-
-    &interaction.ch01-new.ls2;
-
-    <para id="x_71f">If we want to add some pre-existing files to the repository,
-      we copy them into place, and tell Mercurial to start tracking
-      them using the <command>hg add</command> command.</para>
-
-    &interaction.ch01-new.add;
-
-    <para id="x_720">Once we are satisfied that our project looks right, we
-      commit our changes.</para>
-
-    &interaction.ch01-new.commit;
-
-    <para id="x_721">It takes just a few moments to start using Mercurial on a
-      new project, which is part of its appeal. Revision control is
-      now so easy to work with, we can use it on the smallest of
-      projects that we might not have considered with a more
-      complicated tool.</para>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch02-tour-basic.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,1035 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:tour-basic">
+  <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?>
+  <title>A tour of Mercurial: the basics</title>
+
+  <sect1 id="sec:tour:install">
+    <title>Installing Mercurial on your system</title>
+
+    <para id="x_1">Prebuilt binary packages of Mercurial are available for
+      every popular operating system.  These make it easy to start
+      using Mercurial on your computer immediately.</para>
+
+    <sect2>
+      <title>Windows</title>
+
+      <para id="x_c">The best version of Mercurial for Windows is
+	TortoiseHg, which can be found at <ulink
+	  url="http://bitbucket.org/tortoisehg/stable/wiki/Home">http://bitbucket.org/tortoisehg/stable/wiki/Home</ulink>. 
+	This package has no external dependencies; it <quote>just
+	  works</quote>.  It provides both command line and graphical
+	user interfaces.</para>
+
+    </sect2>
+
+    <sect2>
+      <title>Mac OS X</title>
+
+      <para id="x_a">Lee Cantey publishes an installer of Mercurial
+	for Mac OS X at <ulink
+	  url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>.</para>
+    </sect2>
+
+    <sect2>
+      <title>Linux</title>
+
+      <para id="x_2">Because each Linux distribution has its own packaging
+	tools, policies, and rate of development, it's difficult to
+	give a comprehensive set of instructions on how to install
+	Mercurial binaries.  The version of Mercurial that you will
+	end up with can vary depending on how active the person is who
+	maintains the package for your distribution.</para>
+
+      <para id="x_3">To keep things simple, I will focus on installing
+	Mercurial from the command line under the most popular Linux
+	distributions.  Most of these distributions provide graphical
+	package managers that will let you install Mercurial with a
+	single click; the package name to look for is
+	<literal>mercurial</literal>.</para>
+
+      <itemizedlist>
+	<listitem><para id="x_4">Ubuntu and Debian:</para>
+	  <programlisting>apt-get install mercurial</programlisting></listitem>
+	<listitem><para id="x_5">Fedora:</para>
+	  <programlisting>yum install mercurial</programlisting></listitem>
+	<listitem><para id="x_715">OpenSUSE:</para>
+	  <programlisting>zypper install mercurial</programlisting></listitem>
+	<listitem><para id="x_6">Gentoo:</para>
+	  <programlisting>emerge mercurial</programlisting></listitem>
+      </itemizedlist>
+
+    </sect2>
+    <sect2>
+      <title>Solaris</title>
+
+      <para id="x_9">SunFreeWare, at <ulink
+	  url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>, 
+	provides prebuilt packages of Mercurial.</para>
+
+    </sect2>
+
+  </sect1>
+
+  <sect1>
+    <title>Getting started</title>
+
+    <para id="x_e">To begin, we'll use the <command role="hg-cmd">hg
+	version</command> command to find out whether Mercurial is
+      installed properly.  The actual version information that it
+      prints isn't so important; we simply care whether the command
+      runs and prints anything at all.</para>
+
+    &interaction.tour.version;
+
+    <sect2>
+      <title>Built-in help</title>
+
+      <para id="x_f">Mercurial provides a built-in help system.  This is
+	  invaluable for those times when you find yourself stuck
+	  trying to remember how to run a command.  If you are
+	  completely stuck, simply run <command role="hg-cmd">hg
+	    help</command>; it will print a brief list of commands,
+	  along with a description of what each does.  If you ask for
+	  help on a specific command (as below), it prints more
+	  detailed information.</para>
+
+	&interaction.tour.help;
+
+	<para id="x_10">For a more impressive level of detail (which you won't
+	  usually need) run <command role="hg-cmd">hg help <option
+	      role="hg-opt-global">-v</option></command>.  The <option
+	    role="hg-opt-global">-v</option> option is short for
+	  <option role="hg-opt-global">--verbose</option>, and tells
+	  Mercurial to print more information than it usually
+	  would.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Working with a repository</title>
+
+    <para id="x_11">In Mercurial, everything happens inside a
+      <emphasis>repository</emphasis>.  The repository for a project
+      contains all of the files that <quote>belong to</quote> that
+      project, along with a historical record of the project's
+      files.</para>
+
+    <para id="x_12">There's nothing particularly magical about a repository; it
+      is simply a directory tree in your filesystem that Mercurial
+      treats as special. You can rename or delete a repository any
+      time you like, using either the command line or your file
+      browser.</para>
+
+    <sect2>
+      <title>Making a local copy of a repository</title>
+
+      <para id="x_13"><emphasis>Copying</emphasis> a repository is just a little
+	bit special.  While you could use a normal file copying
+	command to make a copy of a repository, it's best to use a
+	built-in command that Mercurial provides.  This command is
+	called <command role="hg-cmd">hg clone</command>, because it
+	makes an identical copy of an existing repository.</para>
+
+      &interaction.tour.clone;
+
+      <para id="x_67c">One advantage of using <command role="hg-cmd">hg
+	  clone</command> is that, as we can see above, it lets us clone
+	repositories over the network.  Another is that it remembers
+	where we cloned from, which we'll find useful soon when we
+	want to fetch new changes from another repository.</para>
+
+      <para id="x_14">If our clone succeeded, we should now have a local
+	directory called <filename class="directory">hello</filename>.
+	This directory will contain some files.</para>
+
+      &interaction.tour.ls;
+
+      <para id="x_15">These files have the same contents and history in our
+	repository as they do in the repository we cloned.</para>
+
+      <para id="x_16">Every Mercurial repository is complete,
+	self-contained, and independent.  It contains its own private
+	copy of a project's files and history.  As we just mentioned,
+	a cloned repository remembers the location of the repository
+	it was cloned from, but Mercurial will not communicate with
+	that repository, or any other, unless you tell it to.</para>
+
+      <para id="x_17">What this means for now is that we're free to experiment
+	with our repository, safe in the knowledge that it's a private
+	<quote>sandbox</quote> that won't affect anyone else.</para>
+
+    </sect2>
+    <sect2>
+      <title>What's in a repository?</title>
+
+      <para id="x_18">When we take a more detailed look inside a repository, we
+	can see that it contains a directory named <filename
+	  class="directory">.hg</filename>.  This is where Mercurial
+	keeps all of its metadata for the repository.</para>
+
+      &interaction.tour.ls-a;
+
+      <para id="x_19">The contents of the <filename
+	  class="directory">.hg</filename> directory and its
+	subdirectories are private to Mercurial.  Every other file and
+	directory in the repository is yours to do with as you
+	please.</para>
+
+      <para id="x_1a">To introduce a little terminology, the <filename
+	  class="directory">.hg</filename> directory is the
+	<quote>real</quote> repository, and all of the files and
+	directories that coexist with it are said to live in the
+	<emphasis>working directory</emphasis>.  An easy way to
+	remember the distinction is that the
+	<emphasis>repository</emphasis> contains the
+	<emphasis>history</emphasis> of your project, while the
+	<emphasis>working directory</emphasis> contains a
+	<emphasis>snapshot</emphasis> of your project at a particular
+	point in history.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>A tour through history</title>
+
+    <para id="x_1b">One of the first things we might want to do with a new,
+      unfamiliar repository is understand its history.  The <command
+	role="hg-cmd">hg log</command> command gives us a view of
+      the history of changes in the repository.</para>
+
+    &interaction.tour.log;
+
+    <para id="x_1c">By default, this command prints a brief paragraph of output
+      for each change to the project that was recorded.  In Mercurial
+      terminology, we call each of these recorded events a
+      <emphasis>changeset</emphasis>, because it can contain a record
+      of changes to several files.</para>
+
+    <para id="x_1d">The fields in a record of output from <command
+	role="hg-cmd">hg log</command> are as follows.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_1e"><literal>changeset</literal>: This
+	  field has the format of a number, followed by a colon,
+	  followed by a hexadecimal (or <emphasis>hex</emphasis>)
+	  string.  These are <emphasis>identifiers</emphasis> for the
+	  changeset.  The hex string is a unique identifier: the same
+	  hex string will always refer to the same changeset in every
+	  copy of this repository. The
+	  number is shorter and easier to type than the hex string,
+	  but it isn't unique: the same number in two different clones
+	  of a repository may identify different changesets.</para>
+      </listitem>
+      <listitem><para id="x_1f"><literal>user</literal>: The identity of the
+	  person who created the changeset.  This is a free-form
+	  field, but it most often contains a person's name and email
+	  address.</para></listitem>
+      <listitem><para id="x_20"><literal>date</literal>: The date and time on
+	  which the changeset was created, and the timezone in which
+	  it was created.  (The date and time are local to that
+	  timezone; they display what time and date it was for the
+	  person who created the changeset.)</para></listitem>
+      <listitem><para id="x_21"><literal>summary</literal>: The first line of
+	  the text message that the creator of the changeset entered
+	  to describe the changeset.</para></listitem>
+      <listitem>
+	<para id="x_67d">Some changesets, such as the first in the list above,
+	  have a <literal>tag</literal> field.  A tag is another way
+	  to identify a changeset, by giving it an easy-to-remember
+	  name. (The tag named <literal>tip</literal> is special: it
+	  always refers to the newest change in a repository.)</para>
+      </listitem>
+    </itemizedlist>
+
+    <para id="x_22">The default output printed by <command
+	role="hg-cmd">hg log</command> is purely a summary; it is
+      missing a lot of detail.</para>
+
+    <para id="x_23"><xref linkend="fig:tour-basic:history"/> provides
+      a graphical representation of the history of the <filename
+	class="directory">hello</filename> repository, to make it a
+      little easier to see which direction history is
+      <quote>flowing</quote> in.  We'll be returning to this figure
+      several times in this chapter and the chapter that
+      follows.</para>
+
+    <figure id="fig:tour-basic:history">
+      <title>Graphical history of the <filename
+	  class="directory">hello</filename> repository</title>
+      <mediaobject>
+	<imageobject><imagedata fileref="figs/tour-history.png"/></imageobject>
+	<textobject><phrase>XXX add text</phrase></textobject>
+      </mediaobject>
+    </figure>
+
+    <sect2>
+      <title>Changesets, revisions, and talking to other
+	people</title>
+
+      <para id="x_25">As English is a notoriously sloppy language, and computer
+	science has a hallowed history of terminological confusion
+	(why use one term when four will do?), revision control has a
+	variety of words and phrases that mean the same thing.  If you
+	are talking about Mercurial history with other people, you
+	will find that the word <quote>changeset</quote> is often
+	compressed to <quote>change</quote> or (when written)
+	<quote>cset</quote>, and sometimes a changeset is referred to
+	as a <quote>revision</quote> or a <quote>rev</quote>.</para>
+
+      <para id="x_26">While it doesn't matter what <emphasis>word</emphasis> you
+	use to refer to the concept of <quote>a changeset</quote>, the
+	<emphasis>identifier</emphasis> that you use to refer to
+	<quote>a <emphasis>specific</emphasis> changeset</quote> is of
+	great importance. Recall that the <literal>changeset</literal>
+	field in the output from <command role="hg-cmd">hg
+	  log</command> identifies a changeset using both a number and
+	a hexadecimal string.</para>
+      <itemizedlist>
+	<listitem><para id="x_27">The revision number is a handy
+	    notation that is <emphasis>only valid in that
+	      repository</emphasis>.</para></listitem>
+	<listitem><para id="x_28">The hexadecimal string is the
+	    <emphasis>permanent, unchanging identifier</emphasis> that
+	    will always identify that exact changeset in
+	    <emphasis>every</emphasis> copy of the
+	    repository.</para></listitem></itemizedlist>
+
+      <para id="x_29">This distinction is important.  If you send
+	someone an email talking about <quote>revision 33</quote>,
+	there's a high likelihood that their revision 33 will
+	<emphasis>not be the same</emphasis> as yours.  The reason for
+	this is that a revision number depends on the order in which
+	changes arrived in a repository, and there is no guarantee
+	that the same changes will happen in the same order in
+	different repositories. Three changes <literal>a,b,c</literal>
+	can easily appear in one repository as
+	<literal>0,1,2</literal>, while in another as
+	<literal>0,2,1</literal>.</para>
+
+      <para id="x_2a">Mercurial uses revision numbers purely as a convenient
+	shorthand.  If you need to discuss a changeset with someone,
+	or make a record of a changeset for some other reason (for
+	example, in a bug report), use the hexadecimal
+	identifier.</para>
+
+    </sect2>
+    <sect2>
+      <title>Viewing specific revisions</title>
+
+      <para id="x_2b">To narrow the output of <command role="hg-cmd">hg
+	  log</command> down to a single revision, use the <option
+	  role="hg-opt-log">-r</option> (or <option
+	  role="hg-opt-log">--rev</option>) option.  You can use
+	either a revision number or a hexadecimal identifier,
+	and you can provide as many revisions as you want.</para>
+
+      &interaction.tour.log-r;
+
+      <para id="x_2c">If you want to see the history of several revisions
+	without having to list each one, you can use <emphasis>range
+	  notation</emphasis>; this lets you express the idea <quote>I
+	  want all revisions between <literal>abc</literal> and
+	  <literal>def</literal>, inclusive</quote>.</para>
+      
+	&interaction.tour.log.range;
+
+      <para id="x_2d">Mercurial also honours the order in which you specify
+	revisions, so <command role="hg-cmd">hg log -r 2:4</command>
+	prints 2, 3, and 4. while <command role="hg-cmd">hg log -r
+	  4:2</command> prints 4, 3, and 2.</para>
+
+    </sect2>
+    <sect2>
+      <title>More detailed information</title>
+
+      <para id="x_2e">While the summary information printed by <command
+	  role="hg-cmd">hg log</command> is useful if you already know
+	what you're looking for, you may need to see a complete
+	description of the change, or a list of the files changed, if
+	you're trying to decide whether a changeset is the one you're
+	looking for. The <command role="hg-cmd">hg log</command>
+	command's <option role="hg-opt-global">-v</option> (or <option
+	  role="hg-opt-global">--verbose</option>) option gives you
+	this extra detail.</para>
+
+      &interaction.tour.log-v;
+
+      <para id="x_2f">If you want to see both the description and
+	content of a change, add the <option
+	  role="hg-opt-log">-p</option> (or <option
+	  role="hg-opt-log">--patch</option>) option.  This displays
+	the content of a change as a <emphasis>unified diff</emphasis>
+	(if you've never seen a unified diff before, see <xref
+	  linkend="sec:mq:patch"/> for an overview).</para>
+
+      &interaction.tour.log-vp;
+
+      <para id="x_67e">The <option role="hg-opt-log">-p</option> option is
+	tremendously useful, so it's well worth remembering.</para>
+
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>All about command options</title>
+
+    <para id="x_30">Let's take a brief break from exploring Mercurial commands
+      to discuss a pattern in the way that they work; you may find
+      this useful to keep in mind as we continue our tour.</para>
+
+    <para id="x_31">Mercurial has a consistent and straightforward approach to
+      dealing with the options that you can pass to commands.  It
+      follows the conventions for options that are common to modern
+      Linux and Unix systems.</para>
+
+    <itemizedlist>
+      <listitem>
+	<para id="x_32">Every option has a long name.  For example, as
+	  we've already seen, the <command role="hg-cmd">hg
+	    log</command> command accepts a <option
+	    role="hg-opt-log">--rev</option> option.</para>
+      </listitem>
+      <listitem>
+	<para id="x_33">Most options have short names, too.  Instead
+	  of <option role="hg-opt-log">--rev</option>, we can use
+	  <option role="hg-opt-log">-r</option>.  (The reason that
+	  some options don't have short names is that the options in
+	  question are rarely used.)</para>
+      </listitem>
+      <listitem>
+	<para id="x_34">Long options start with two dashes (e.g.
+	  <option role="hg-opt-log">--rev</option>), while short
+	  options start with one (e.g. <option
+	    role="hg-opt-log">-r</option>).</para>
+      </listitem>
+      <listitem>
+	<para id="x_35">Option naming and usage is consistent across
+	  commands.  For example, every command that lets you specify
+	  a changeset ID or revision number accepts both <option
+	    role="hg-opt-log">-r</option> and <option
+	    role="hg-opt-log">--rev</option> arguments.</para>
+      </listitem>
+      <listitem>
+	<para id="x_67f">If you are using short options, you can save typing by
+	  running them together. For example, the command <command
+	    role="hg-cmd">hg log -v -p -r 2</command> can be written
+	  as <command role="hg-cmd">hg log -vpr2</command>.</para>
+      </listitem>
+    </itemizedlist>
+
+    <para id="x_36">In the examples throughout this book, I usually
+      use short options instead of long.  This simply reflects my own
+      preference, so don't read anything significant into it.</para>
+
+    <para id="x_37">Most commands that print output of some kind will print more
+      output when passed a <option role="hg-opt-global">-v</option>
+      (or <option role="hg-opt-global">--verbose</option>) option, and
+      less when passed <option role="hg-opt-global">-q</option> (or
+      <option role="hg-opt-global">--quiet</option>).</para>
+
+    <note>
+      <title>Option naming consistency</title>
+
+      <para id="x_680">Almost always, Mercurial commands use consistent option
+	names to refer to the same concepts.  For instance, if a
+	command deals with changesets, you'll always identify them
+	with <option role="hg-opt-log">--rev</option> or <option
+	  role="hg-opt-log">-r</option>.  This consistent use of
+	option names makes it easier to remember what options a
+	particular command takes.</para>
+    </note>
+
+  </sect1>
+  <sect1>
+    <title>Making and reviewing changes</title>
+
+    <para id="x_38">Now that we have a grasp of viewing history in Mercurial,
+      let's take a look at making some changes and examining
+      them.</para>
+
+    <para id="x_39">The first thing we'll do is isolate our experiment in a
+      repository of its own.  We use the <command role="hg-cmd">hg
+	clone</command> command, but we don't need to clone a copy of
+      the remote repository.  Since we already have a copy of it
+      locally, we can just clone that instead.  This is much faster
+      than cloning over the network, and cloning a local repository
+      uses less disk space in most cases, too<footnote>
+	<para id="x_681">The saving of space arises when source and destination
+	  repositories are on the same filesystem, in which case
+	  Mercurial will use hardlinks to do copy-on-write sharing of
+	  its internal metadata.  If that explanation meant nothing to
+	  you, don't worry: everything happens transparently and
+	  automatically, and you don't need to understand it.</para>
+	</footnote>.</para>
+
+    &interaction.tour.reclone;
+
+    <para id="x_3a">As an aside, it's often good practice to keep a
+      <quote>pristine</quote> copy of a remote repository around,
+      which you can then make temporary clones of to create sandboxes
+      for each task you want to work on.  This lets you work on
+      multiple tasks in parallel, each isolated from the others until
+      it's complete and you're ready to integrate it back.  Because
+      local clones are so cheap, there's almost no overhead to cloning
+      and destroying repositories whenever you want.</para>
+
+    <para id="x_3b">In our <filename class="directory">my-hello</filename>
+      repository, we have a file <filename>hello.c</filename> that
+      contains the classic <quote>hello, world</quote> program.</para>
+
+    &interaction.tour.cat1;
+
+    <para id="x_682">Let's edit this file so that it prints a second line of
+      output.</para>
+
+    &interaction.tour.cat2;
+
+    <para id="x_3c">Mercurial's <command role="hg-cmd">hg status</command>
+      command will tell us what Mercurial knows about the files in the
+      repository.</para>
+
+    &interaction.tour.status;
+
+    <para id="x_3d">The <command role="hg-cmd">hg status</command> command
+      prints no output for some files, but a line starting with
+      <quote><literal>M</literal></quote> for
+      <filename>hello.c</filename>.  Unless you tell it to, <command
+	role="hg-cmd">hg status</command> will not print any output
+      for files that have not been modified.</para>
+
+    <para id="x_3e">The <quote><literal>M</literal></quote> indicates that
+      Mercurial has noticed that we modified
+      <filename>hello.c</filename>.  We didn't need to
+      <emphasis>inform</emphasis> Mercurial that we were going to
+      modify the file before we started, or that we had modified the
+      file after we were done; it was able to figure this out
+      itself.</para>
+
+    <para id="x_3f">It's somewhat helpful to know that we've modified
+      <filename>hello.c</filename>, but we might prefer to know
+      exactly <emphasis>what</emphasis> changes we've made to it.  To
+      do this, we use the <command role="hg-cmd">hg diff</command>
+      command.</para>
+
+    &interaction.tour.diff;
+
+    <tip>
+      <title>Understanding patches</title>
+
+      <para id="x_683">Remember to take a look at <xref
+	  linkend="sec:mq:patch"/> if you don't know how to read
+	output above.</para>
+    </tip>
+  </sect1>
+  <sect1>
+    <title>Recording changes in a new changeset</title>
+
+    <para id="x_40">We can modify files, build and test our changes, and use
+      <command role="hg-cmd">hg status</command> and <command
+	role="hg-cmd">hg diff</command> to review our changes, until
+      we're satisfied with what we've done and arrive at a natural
+      stopping point where we want to record our work in a new
+      changeset.</para>
+
+    <para id="x_41">The <command role="hg-cmd">hg commit</command> command lets
+      us create a new changeset; we'll usually refer to this as
+      <quote>making a commit</quote> or
+      <quote>committing</quote>.</para>
+
+    <sect2>
+      <title>Setting up a username</title>
+
+      <para id="x_42">When you try to run <command role="hg-cmd">hg
+	  commit</command> for the first time, it is not guaranteed to
+	succeed.  Mercurial records your name and address with each
+	change that you commit, so that you and others will later be
+	able to tell who made each change.  Mercurial tries to
+	automatically figure out a sensible username to commit the
+	change with.  It will attempt each of the following methods,
+	in order:</para>
+      <orderedlist>
+	<listitem><para id="x_43">If you specify a <option
+	      role="hg-opt-commit">-u</option> option to the <command
+	      role="hg-cmd">hg commit</command> command on the command
+	    line, followed by a username, this is always given the
+	    highest precedence.</para></listitem>
+	<listitem><para id="x_44">If you have set the <envar>HGUSER</envar>
+	    environment variable, this is checked
+	    next.</para></listitem>
+	<listitem><para id="x_45">If you create a file in your home
+	    directory called <filename
+	      role="special">.hgrc</filename>, with a <envar
+	      role="rc-item-ui">username</envar> entry, that will be
+	    used next.  To see what the contents of this file should
+	    look like, refer to <xref
+	      linkend="sec:tour-basic:username"/>
+	    below.</para></listitem>
+	<listitem><para id="x_46">If you have set the <envar>EMAIL</envar>
+	    environment variable, this will be used
+	    next.</para></listitem>
+	<listitem><para id="x_47">Mercurial will query your system to find out
+	    your local user name and host name, and construct a
+	    username from these components. Since this often results
+	    in a username that is not very useful, it will print a
+	    warning if it has to do
+	    this.</para></listitem>
+      </orderedlist>
+      <para id="x_48">If all of these mechanisms fail, Mercurial will
+	  fail, printing an error message.  In this case, it will not
+	  let you commit until you set up a
+	  username.</para>
+      <para id="x_49">You should think of the <envar>HGUSER</envar> environment
+	variable and the <option role="hg-opt-commit">-u</option>
+	option to the <command role="hg-cmd">hg commit</command>
+	command as ways to <emphasis>override</emphasis> Mercurial's
+	default selection of username.  For normal use, the simplest
+	and most robust way to set a username for yourself is by
+	creating a <filename role="special">.hgrc</filename> file; see
+	below for details.</para>
+      <sect3 id="sec:tour-basic:username">
+	<title>Creating a Mercurial configuration file</title>
+
+	<para id="x_4a">To set a user name, use your favorite editor
+	  to create a file called <filename
+	    role="special">.hgrc</filename> in your home directory.
+	  Mercurial will use this file to look up your personalised
+	  configuration settings.  The initial contents of your
+	  <filename role="special">.hgrc</filename> should look like
+	  this.</para>
+
+	<tip>
+	  <title><quote>Home directory</quote> on Windows</title>
+
+	  <para id="x_716">When we refer to your home directory, on an English
+	    language installation of Windows this will usually be a
+	    folder named after your user name in
+	    <filename>C:\Documents and Settings</filename>.  You can
+	    find out the exact name of your home directory by opening
+	    a command prompt window and running the following
+	    command.</para>
+
+	  <screen><prompt>C:\></prompt> <userinput>echo %UserProfile%</userinput></screen>
+	</tip>
+
+	<programlisting># This is a Mercurial configuration file.
+[ui]
+username = Firstname Lastname &lt;email.address@example.net&gt;</programlisting>
+
+	<para id="x_4b">The <quote><literal>[ui]</literal></quote> line begins a
+	  <emphasis>section</emphasis> of the config file, so you can
+	  read the <quote><literal>username = ...</literal></quote>
+	  line as meaning <quote>set the value of the
+	    <literal>username</literal> item in the
+	    <literal>ui</literal> section</quote>. A section continues
+	  until a new section begins, or the end of the file.
+	  Mercurial ignores empty lines and treats any text from
+	  <quote><literal>#</literal></quote> to the end of a line as
+	  a comment.</para>
+      </sect3>
+
+      <sect3>
+	<title>Choosing a user name</title>
+
+	<para id="x_4c">You can use any text you like as the value of
+	  the <literal>username</literal> config item, since this
+	  information is for reading by other people, but will not be
+	  interpreted by Mercurial.  The convention that most people
+	  follow is to use their name and email address, as in the
+	  example above.</para>
+	<note>
+	  <para id="x_4d">Mercurial's built-in web server obfuscates
+	    email addresses, to make it more difficult for the email
+	    harvesting tools that spammers use. This reduces the
+	    likelihood that you'll start receiving more junk email if
+	    you publish a Mercurial repository on the
+	    web.</para></note>
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Writing a commit message</title>
+
+      <para id="x_4e">When we commit a change, Mercurial drops us into
+	a text editor, to enter a message that will describe the
+	modifications we've made in this changeset.  This is called
+	the <emphasis>commit message</emphasis>.  It will be a record
+	for readers of what we did and why, and it will be printed by
+	<command role="hg-cmd">hg log</command> after we've finished
+	committing.</para>
+
+       &interaction.tour.commit;
+
+      <para id="x_4f">The editor that the <command role="hg-cmd">hg
+	  commit</command> command drops us into will contain an empty
+	line or two, followed by a number of lines starting with
+	<quote><literal>HG:</literal></quote>.</para>
+
+    <programlisting>
+This is where I type my commit comment.
+
+HG: Enter commit message.  Lines beginning with 'HG:' are removed.
+HG: --
+HG: user: Bryan O'Sullivan &lt;bos@serpentine.com&gt;
+HG: branch 'default'
+HG: changed hello.c</programlisting>
+
+      <para id="x_50">Mercurial ignores the lines that start with
+	<quote><literal>HG:</literal></quote>; it uses them only to
+	tell us which files it's recording changes to.  Modifying or
+	deleting these lines has no effect.</para>
+    </sect2>
+    <sect2>
+      <title>Writing a good commit message</title>
+
+      <para id="x_51">Since <command role="hg-cmd">hg log</command>
+	only prints the first line of a commit message by default,
+	it's best to write a commit message whose first line stands
+	alone.  Here's a real example of a commit message that
+	<emphasis>doesn't</emphasis> follow this guideline, and hence
+	has a summary that is not readable.</para>
+
+      <programlisting>
+changeset:   73:584af0e231be
+user:        Censored Person &lt;censored.person@example.org&gt;
+date:        Tue Sep 26 21:37:07 2006 -0700
+summary:     include buildmeister/commondefs. Add exports.</programlisting>
+
+      <para id="x_52">As far as the remainder of the contents of the
+	commit message are concerned, there are no hard-and-fast
+	rules.  Mercurial itself doesn't interpret or care about the
+	contents of the commit message, though your project may have
+	policies that dictate a certain kind of formatting.</para>
+      <para id="x_53">My personal preference is for short, but
+	informative, commit messages that tell me something that I
+	can't figure out with a quick glance at the output of <command
+	  role="hg-cmd">hg log --patch</command>.</para>
+      <para id="x_55">If we run the <command role="hg-cmd">hg
+	  commit</command> command without any arguments, it records
+	all of the changes we've made, as reported by <command
+	  role="hg-cmd">hg status</command> and <command
+	  role="hg-cmd">hg diff</command>.</para>
+
+      <note>
+	<title>A surprise for Subversion users</title>
+
+	<para id="x_717">Like other Mercurial commands, if we don't supply
+	  explicit names to commit to the <command role="hg-cmd">hg
+	    commit</command>, it will operate across a repository's
+	  entire working directory.  Be wary of this if you're coming
+	  from the Subversion or CVS world, since you might expect it
+	  to operate only on the current directory that you happen to
+	  be visiting and its subdirectories.</para>
+      </note>
+    </sect2>
+
+    <sect2>
+      <title>Aborting a commit</title>
+
+      <para id="x_54">If you decide that you don't want to commit
+	while in the middle of editing a commit message, simply exit
+	from your editor without saving the file that it's editing.
+	This will cause nothing to happen to either the repository or
+	the working directory.</para>
+    </sect2>
+
+    <sect2>
+      <title>Admiring our new handiwork</title>
+
+      <para id="x_56">Once we've finished the commit, we can use the
+	<command role="hg-cmd">hg tip</command> command to display the
+	changeset we just created.  This command produces output that
+	is identical to <command role="hg-cmd">hg log</command>, but
+	it only displays the newest revision in the repository.</para>
+
+      &interaction.tour.tip;
+
+      <para id="x_57">We refer to the newest revision in the
+	repository as the <emphasis>tip revision</emphasis>, or simply
+	the <emphasis>tip</emphasis>.</para>
+
+      <para id="x_684">By the way, the <command role="hg-cmd">hg tip</command>
+	command accepts many of the same options as <command
+	  role="hg-cmd">hg log</command>, so <option
+	  role="hg-opt-global">-v</option> above indicates <quote>be
+	  verbose</quote>, <option role="hg-opt-tip">-p</option>
+	specifies <quote>print a patch</quote>.  The use of <option
+	  role="hg-opt-tip">-p</option> to print patches is another
+	example of the consistent naming we mentioned earlier.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Sharing changes</title>
+
+    <para id="x_58">We mentioned earlier that repositories in
+      Mercurial are self-contained.  This means that the changeset we
+      just created exists only in our <filename
+	class="directory">my-hello</filename> repository.  Let's look
+      at a few ways that we can propagate this change into other
+      repositories.</para>
+
+    <sect2 id="sec:tour:pull">
+      <title>Pulling changes from another repository</title>
+
+      <para id="x_59">To get started, let's clone our original
+	<filename class="directory">hello</filename> repository, which
+	does not contain the change we just committed.  We'll call our
+	temporary repository <filename
+	  class="directory">hello-pull</filename>.</para>
+
+      &interaction.tour.clone-pull;
+
+      <para id="x_5a">We'll use the <command role="hg-cmd">hg
+	  pull</command> command to bring changes from <filename
+	  class="directory">my-hello</filename> into <filename
+	  class="directory">hello-pull</filename>.  However, blindly
+	pulling unknown changes into a repository is a somewhat scary
+	prospect.  Mercurial provides the <command role="hg-cmd">hg
+	  incoming</command> command to tell us what changes the
+	<command role="hg-cmd">hg pull</command> command
+	<emphasis>would</emphasis> pull into the repository, without
+	actually pulling the changes in.</para>
+
+      &interaction.tour.incoming;
+
+      <para id="x_5c">Bringing changes into a repository is a simple
+	matter of running the <command role="hg-cmd">hg pull</command>
+	command, and optionally telling it which repository to pull from.</para>
+
+      &interaction.tour.pull;
+
+      <para id="x_5d">As you can see from the before-and-after output
+	of <command role="hg-cmd">hg tip</command>, we have
+	successfully pulled changes into our repository.  However,
+	Mercurial separates pulling changes in from updating the
+	working directory. There remains one step before we will see
+	the changes that we just pulled appear in the working
+	directory.</para>
+
+      <tip>
+	<title>Pulling specific changes</title>
+
+	<para id="x_5b">It is possible that due to the delay between
+	  running <command role="hg-cmd">hg incoming</command> and
+	  <command role="hg-cmd">hg pull</command>, you may not see
+	  all changesets that will be brought from the other
+	  repository. Suppose you're pulling changes from a repository
+	  on the network somewhere. While you are looking at the
+	  <command role="hg-cmd">hg incoming</command> output, and
+	  before you pull those changes, someone might have committed
+	  something in the remote repository. This means that it's
+	  possible to pull more changes than you saw when using
+	  <command role="hg-cmd">hg incoming</command>.</para>
+
+	<para id="x_718">If you only want to pull precisely the changes that were
+	  listed by <command role="hg-cmd">hg incoming</command>, or
+	  you have some other reason to pull a subset of changes,
+	  simply identify the change that you want to pull by its
+	  changeset ID, e.g. <command>hg pull
+	    -r7e95bb</command>.</para>
+      </tip>
+    </sect2>
+
+    <sect2>
+      <title>Updating the working directory</title>
+
+      <para id="x_5e">We have so far glossed over the relationship
+	between a repository and its working directory.  The <command
+	  role="hg-cmd">hg pull</command> command that we ran in
+	<xref linkend="sec:tour:pull"/> brought changes into the
+	repository, but if we check, there's no sign of those changes
+	in the working directory.  This is because <command
+	  role="hg-cmd">hg pull</command> does not (by default) touch
+	the working directory.  Instead, we use the <command
+	  role="hg-cmd">hg update</command> command to do this.</para>
+
+      &interaction.tour.update;
+
+      <para id="x_5f">It might seem a bit strange that <command
+	  role="hg-cmd">hg pull</command> doesn't update the working
+	directory automatically.  There's actually a good reason for
+	this: you can use <command role="hg-cmd">hg update</command>
+	to update the working directory to the state it was in at
+	<emphasis>any revision</emphasis> in the history of the
+	repository.  If you had the working directory updated to an
+	old revision&emdash;to hunt down the origin of a bug,
+	say&emdash;and ran a <command role="hg-cmd">hg pull</command>
+	which automatically updated the working directory to a new
+	revision, you might not be terribly happy.</para>
+
+      <para id="x_60">Since pull-then-update is such a common sequence
+	of operations, Mercurial lets you combine the two by passing
+	the <option role="hg-opt-pull">-u</option> option to <command
+	  role="hg-cmd">hg pull</command>.</para>
+
+      <para id="x_61">If you look back at the output of <command
+	  role="hg-cmd">hg pull</command> in <xref
+	    linkend="sec:tour:pull"/> when we ran it without <option
+	  role="hg-opt-pull">-u</option>, you can see that it printed
+	a helpful reminder that we'd have to take an explicit step to
+	update the working directory.</para>
+
+      <para id="x_62">To find out what revision the working directory
+	is at, use the <command role="hg-cmd">hg parents</command>
+	command.</para>
+
+      &interaction.tour.parents;
+
+      <para id="x_63">If you look back at <xref
+	  linkend="fig:tour-basic:history"/>, you'll see arrows
+	connecting each changeset.  The node that the arrow leads
+	<emphasis>from</emphasis> in each case is a parent, and the
+	node that the arrow leads <emphasis>to</emphasis> is its
+	child.  The working directory has a parent in just the same
+	way; this is the changeset that the working directory
+	currently contains.</para>
+
+      <para id="x_64">To update the working directory to a particular
+	revision, give a revision number or changeset ID to the
+	<command role="hg-cmd">hg update</command> command.</para>
+
+      &interaction.tour.older;
+
+      <para id="x_65">If you omit an explicit revision, <command
+	  role="hg-cmd">hg update</command> will update to the tip
+	revision, as shown by the second call to <command
+	  role="hg-cmd">hg update</command> in the example
+	above.</para>
+    </sect2>
+
+    <sect2>
+      <title>Pushing changes to another repository</title>
+
+      <para id="x_66">Mercurial lets us push changes to another
+	repository, from the repository we're currently visiting. As
+	with the example of <command role="hg-cmd">hg pull</command>
+	above, we'll create a temporary repository to push our changes
+	into.</para>
+
+      &interaction.tour.clone-push;
+
+      <para id="x_67">The <command role="hg-cmd">hg outgoing</command>
+	command tells us what changes would be pushed into another
+	repository.</para>
+
+      &interaction.tour.outgoing;
+
+      <para id="x_68">And the <command role="hg-cmd">hg push</command>
+	command does the actual push.</para>
+
+      &interaction.tour.push;
+
+      <para id="x_69">As with <command role="hg-cmd">hg
+	  pull</command>, the <command role="hg-cmd">hg push</command>
+	command does not update the working directory in the
+	repository that it's pushing changes into. Unlike <command
+	  role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg
+	  push</command> does not provide a <literal>-u</literal>
+	option that updates the other repository's working directory.
+	This asymmetry is deliberate: the repository we're pushing to
+	might be on a remote server and shared between several people.
+	If we were to update its working directory while someone was
+	working in it, their work would be disrupted.</para>
+
+      <para id="x_6a">What happens if we try to pull or push changes
+	  and the receiving repository already has those changes?
+	  Nothing too exciting.</para>
+
+      &interaction.tour.push.nothing;
+    </sect2>
+
+    <sect2>
+      <title>Default locations</title>
+
+      <para id="x_719">When we clone a repository, Mercurial records the location
+	of the repository we cloned in the
+	<filename>.hg/hgrc</filename> file of the new repository.  If
+	we don't supply a location to <command>hg pull</command> from
+	or <command>hg push</command> to, those commands will use this
+	location as a default.  The <command>hg incoming</command>
+	and <command>hg outgoing</command> commands do so too.</para>
+
+      <para id="x_71a">If you open a repository's <filename>.hg/hgrc</filename>
+	file in a text editor, you will see contents like the
+	following.</para>
+
+      <programlisting>[paths]
+default = http://www.selenic.com/repo/hg</programlisting>
+
+      <para id="x_71b">It is possible&emdash;and often useful&emdash;to have the
+	default location for <command>hg push</command> and
+	<command>hg outgoing</command> be different from those for
+	<command>hg pull</command> and <command>hg incoming</command>.
+	We can do this by adding a <literal>default-push</literal>
+	entry to the <literal>[paths]</literal> section of the
+	<filename>.hg/hgrc</filename> file, as follows.</para>
+
+      <programlisting>[paths]
+default = http://www.selenic.com/repo/hg
+default-push = http://hg.example.com/hg</programlisting>
+    </sect2>
+
+    <sect2>
+      <title>Sharing changes over a network</title>
+
+      <para id="x_6b">The commands we have covered in the previous few
+	  sections are not limited to working with local repositories.
+	  Each works in exactly the same fashion over a network
+	  connection; simply pass in a URL instead of a local
+	  path.</para>
+	
+      &interaction.tour.outgoing.net;
+
+      <para id="x_6c">In this example, we can see what changes we
+	could push to the remote repository, but the repository is
+	understandably not set up to let anonymous users push to
+	it.</para>
+
+      &interaction.tour.push.net;
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Starting a new project</title>
+
+    <para id="x_71c">It is just as easy to begin a new project as to work on one
+      that already exists.  The <command>hg init</command> command
+      creates a new, empty Mercurial repository.</para>
+
+    &interaction.ch01-new.init;
+
+    <para id="x_71d">This simply creates a repository named
+      <filename>myproject</filename> in the current directory.</para>
+
+    &interaction.ch01-new.ls;
+
+    <para id="x_71e">We can tell that <filename>myproject</filename> is a
+      Mercurial repository, because it contains a
+      <filename>.hg</filename> directory.</para>
+
+    &interaction.ch01-new.ls2;
+
+    <para id="x_71f">If we want to add some pre-existing files to the repository,
+      we copy them into place, and tell Mercurial to start tracking
+      them using the <command>hg add</command> command.</para>
+
+    &interaction.ch01-new.add;
+
+    <para id="x_720">Once we are satisfied that our project looks right, we
+      commit our changes.</para>
+
+    &interaction.ch01-new.commit;
+
+    <para id="x_721">It takes just a few moments to start using Mercurial on a
+      new project, which is part of its appeal. Revision control is
+      now so easy to work with, we can use it on the smallest of
+      projects that we might not have considered with a more
+      complicated tool.</para>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- a/en/ch02-tour-merge.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,454 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:tour-merge">
-  <?dbhtml filename="a-tour-of-mercurial-merging-work.html"?>
-  <title>A tour of Mercurial: merging work</title>
-
-  <para id="x_338">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 <emphasis>merging</emphasis>
-    changes from separate repositories.</para>
-
-  <sect1>
-    <title>Merging streams of work</title>
-
-    <para id="x_339">Merging is a fundamental part of working with a distributed
-      revision control tool.  Here are a few cases in which the need
-      to merge work arises.</para>
-    <itemizedlist>
-      <listitem>
-	<para id="x_33a">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.</para>
-      </listitem>
-      <listitem>
-	<para id="x_33b">Cynthia frequently works on several different
-	  tasks for a single project at once, each safely isolated in
-	  its own repository. Working this way means that she often
-	  needs to merge one piece of her own work with
-	  another.</para>
-      </listitem>
-    </itemizedlist>
-
-    <para id="x_33c">Because we need to merge often, Mercurial makes
-      the process easy.  Let's walk through a merge.  We'll begin by
-      cloning yet another repository (see how often they spring up?)
-      and making a change in it.</para>
-
-    &interaction.tour.merge.clone;
-
-    <para id="x_33d">We should now have two copies of
-      <filename>hello.c</filename> with different contents.  The
-      histories of the two repositories have also diverged, as
-      illustrated in <xref
-	linkend="fig:tour-merge:sep-repos"/>.  Here is a copy of our
-      file from one repository.</para>
-
-    &interaction.tour.merge.cat1;
-
-    <para id="x_722">And here is our slightly different version from the other
-      repository.</para>
-
-    &interaction.tour.merge.cat2;
-
-    <figure id="fig:tour-merge:sep-repos">
-      <title>Divergent recent histories of the <filename
-	  class="directory">my-hello</filename> and <filename
-	  class="directory">my-new-hello</filename>
-	repositories</title>
-      <mediaobject>
-	<imageobject><imagedata fileref="figs/tour-merge-sep-repos.png"/></imageobject>
-	<textobject><phrase>XXX add text</phrase></textobject>
-      </mediaobject>
-    </figure>
-
-    <para id="x_33f">We already know that pulling changes from our <filename
-	class="directory">my-hello</filename> repository will have no
-      effect on the working directory.</para>
-
-    &interaction.tour.merge.pull;
-
-    <para id="x_340">However, the <command role="hg-cmd">hg pull</command>
-      command says something about <quote>heads</quote>.</para>
-
-    <sect2>
-      <title>Head changesets</title>
-
-      <para id="x_341">Remember that Mercurial records what the parent
-	of each change is.  If a change has a parent, we call it a
-	child or descendant of the parent.  A head is a change that
-	has no children.  The tip revision is thus a head, because the
-	newest revision in a repository doesn't have any children.
-	There are times when a repository can contain more than one
-	head.</para>
-
-      <figure id="fig:tour-merge:pull">
-	<title>Repository contents after pulling from <filename
-	    class="directory">my-hello</filename> into <filename
-	    class="directory">my-new-hello</filename></title>
-	<mediaobject>
-	  <imageobject>
-	    <imagedata fileref="figs/tour-merge-pull.png"/>
-	  </imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_343">In <xref linkend="fig:tour-merge:pull"/>, you can
-	see the effect of the pull from <filename
-	  class="directory">my-hello</filename> into <filename
-	  class="directory">my-new-hello</filename>.  The history that
-	was already present in <filename
-	  class="directory">my-new-hello</filename> is untouched, but
-	a new revision has been added.  By referring to <xref
-	  linkend="fig:tour-merge:sep-repos"/>, we can see that the
-	<emphasis>changeset ID</emphasis> remains the same in the new
-	repository, but the <emphasis>revision number</emphasis> 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 <command
-	  role="hg-cmd">hg heads</command> command.</para>
-
-      &interaction.tour.merge.heads;
-    </sect2>
-
-    <sect2>
-      <title>Performing the merge</title>
-
-      <para id="x_344">What happens if we try to use the normal <command
-	  role="hg-cmd">hg update</command> command to update to the
-	new tip?</para>
-
-      &interaction.tour.merge.update;
-
-      <para id="x_345">Mercurial is telling us that the <command
-	  role="hg-cmd">hg update</command> command won't do a merge;
-	it won't update the working directory when it thinks we might
-	want to do a merge, unless we force it to do so.
-	(Incidentally, forcing the update with <command>hg update
-	  -C</command> would revert any uncommitted changes in the
-	working directory.)</para>
-
-      <para id="x_723">To start a merge between the two heads, we use the
-	<command role="hg-cmd">hg merge</command> command.</para>
-
-      &interaction.tour.merge.merge;
-
-      <para id="x_347">We resolve the contents of <filename>hello.c</filename>
-
-This updates the working directory so that it
-	contains changes from <emphasis>both</emphasis> heads, which
-	is reflected in both the output of <command role="hg-cmd">hg
-	  parents</command> and the contents of
-	<filename>hello.c</filename>.</para>
-
-      &interaction.tour.merge.parents;
-    </sect2>
-
-    <sect2>
-      <title>Committing the results of the merge</title>
-
-      <para id="x_348">Whenever we've done a merge, <command role="hg-cmd">hg
-	  parents</command> will display two parents until we <command
-	  role="hg-cmd">hg commit</command> the results of the
-	  merge.</para>
-
-	&interaction.tour.merge.commit;
-
-      <para id="x_349">We now have a new tip revision; notice that it has
-	<emphasis>both</emphasis> of our former heads as its parents.
-	These are the same revisions that were previously displayed by
-	<command role="hg-cmd">hg parents</command>.</para>
-
-      &interaction.tour.merge.tip;
-
-      <para id="x_34a">In <xref
-	  linkend="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.</para>
-
-      <figure id="fig:tour-merge:merge">
-	<title>Working directory and repository during merge, and
-	  following commit</title>
-	<mediaobject>
-	  <imageobject>
-	    <imagedata fileref="figs/tour-merge-merge.png"/>
-	  </imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_69c">We sometimes talk about a merge having
-	<emphasis>sides</emphasis>: the left side is the first parent
-	in the output of <command role="hg-cmd">hg parents</command>,
-	and the right side is the second.  If the working directory
-	was at e.g. revision 5 before we began a merge, that revision
-	will become the left side of the merge.</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>Merging conflicting changes</title>
-
-    <para id="x_34b">Most merges are simple affairs, but sometimes you'll find
-      yourself merging changes where each side modifies the same portions
-      of the same files.  Unless both modifications are identical,
-      this results in a <emphasis>conflict</emphasis>, where you have
-      to decide how to reconcile the different changes into something
-      coherent.</para>
-
-    <figure id="fig:tour-merge:conflict">
-      <title>Conflicting changes to a document</title>
-      <mediaobject>
-	<imageobject><imagedata fileref="figs/tour-merge-conflict.png"/></imageobject>
-	<textobject><phrase>XXX add text</phrase></textobject>
-      </mediaobject>
-    </figure>
-
-    <para id="x_34d"><xref linkend="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.</para>
-
-    <para id="x_34e">Mercurial doesn't have a built-in facility for handling
-      conflicts. Instead, it runs an external program, usually one
-      that displays some kind of graphical conflict resolution
-      interface.  By default, Mercurial tries 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, it tries a few
-      different graphical merging tools.</para>
-
-    <para id="x_34f">It's also possible to get Mercurial to run a
-      specific program or script, by setting the
-      <envar>HGMERGE</envar> environment variable to the name of your
-      preferred program.</para>
-
-    <sect2>
-      <title>Using a graphical merge tool</title>
-
-      <para id="x_350">My preferred graphical merge tool is
-	<command>kdiff3</command>, which I'll use to describe the
-	features that are common to graphical file merging tools.  You
-	can see a screenshot of <command>kdiff3</command> in action in
-	<xref linkend="fig:tour-merge:kdiff3"/>.  The kind of
-	merge it is performing is called a <emphasis>three-way
-	  merge</emphasis>, 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:</para>
-      <itemizedlist>
-	<listitem><para id="x_351">At the left is the <emphasis>base</emphasis>
-	    version of the file, i.e. the most recent version from
-	    which the two versions we're trying to merge are
-	    descended.</para>
-	</listitem>
-	<listitem><para id="x_352">In the middle is <quote>our</quote> version of
-	    the file, with the contents that we modified.</para>
-	</listitem>
-	<listitem><para id="x_353">On the right is <quote>their</quote> version
-	    of the file, the one that from the changeset that we're
-	    trying to merge with.</para>
-	</listitem></itemizedlist>
-      <para id="x_354">In the pane below these is the current
-	<emphasis>result</emphasis> of the merge. Our task is to
-	replace all of the red text, which indicates unresolved
-	conflicts, with some sensible merger of the
-	<quote>ours</quote> and <quote>theirs</quote> versions of the
-	file.</para>
-
-      <para id="x_355">All four of these panes are <emphasis>locked
-	  together</emphasis>; if we scroll vertically or horizontally
-	in any of them, the others are updated to display the
-	corresponding sections of their respective files.</para>
-
-      <figure id="fig:tour-merge:kdiff3">
-	<title>Using <command>kdiff3</command> to merge versions of a
-	  file</title>
-	<mediaobject>
-	  <imageobject>
-	    <imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject>
-	  <textobject>
-	    <phrase>XXX add text</phrase>
-	  </textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_357">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.</para>
-
-      <para id="x_358">There are <emphasis>many</emphasis> 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).</para>
-    </sect2>
-
-    <sect2>
-      <title>A worked example</title>
-
-      <para id="x_359">In this example, we will reproduce the file modification
-	history of <xref linkend="fig:tour-merge:conflict"/>
-	above.  Let's begin by creating a repository with a base
-	version of our document.</para>
-
-      &interaction.tour-merge-conflict.wife;
-
-      <para id="x_35a">We'll clone the repository and make a change to the
-	file.</para>
-
-      &interaction.tour-merge-conflict.cousin;
-
-      <para id="x_35b">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.)</para>
-
-      &interaction.tour-merge-conflict.son;
-
-      <para id="x_35c">Having created two
-	different versions of the file, we'll set up an environment
-	suitable for running our merge.</para>
-
-      &interaction.tour-merge-conflict.pull;
-
-      <para id="x_35d">In this example, I'll set
-	<envar>HGMERGE</envar> to tell Mercurial to use the
-	non-interactive <command>merge</command> command.  This is
-	bundled with many Unix-like systems. (If you're following this
-	example on your computer, don't bother setting
-	<envar>HGMERGE</envar>.  You'll get dropped into a GUI file
-	merge tool instead, which is much preferable.)</para>
-
-      &interaction.tour-merge-conflict.merge;
-
-      <para id="x_35f">Because <command>merge</command> can't resolve the
-	conflicting changes, it leaves <emphasis>merge
-	  markers</emphasis> inside the file that has conflicts,
-	indicating which lines have conflicts, and whether they came
-	from our version of the file or theirs.</para>
-
-      <para id="x_360">Mercurial can tell from the way <command>merge</command>
-	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.</para>
-
-      <para id="x_361">If automatic or manual merges fail, there's nothing to
-	prevent us from <quote>fixing up</quote> the affected files
-	ourselves, and committing the results of our merge:</para>
-
-      &interaction.tour-merge-conflict.commit;
-
-      <note>
-	<title>Where is the <command>hg resolve</command> command?</title>
-
-	<para id="x_724">The <command>hg resolve</command> command was introduced
-	  in Mercurial 1.1, which was released in December 2008. If
-	  you are using an older version of Mercurial (run <command>hg
-	    version</command> to see), this command will not be
-	  present.  If your version of Mercurial is older than 1.1,
-	  you should strongly consider upgrading to a newer version
-	  before trying to tackle complicated merges.</para>
-      </note>
-    </sect2>
-  </sect1>
-
-  <sect1 id="sec:tour-merge:fetch">
-    <title>Simplifying the pull-merge-commit sequence</title>
-
-    <para id="x_362">The process of merging changes as outlined above is
-      straightforward, but requires running three commands in
-      sequence.</para>
-    <programlisting>hg pull -u
-hg merge
-hg commit -m 'Merged remote changes'</programlisting>
-    <para id="x_363">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 <quote>boilerplate</quote> text.</para>
-
-    <para id="x_364">It would be nice to reduce the number of steps needed, if
-      this were possible.  Indeed, Mercurial is distributed with an
-      extension called <literal role="hg-ext">fetch</literal> that
-      does just this.</para>
-
-    <para id="x_365">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 <quote>behind the scenes,</quote> for example adding
-      capabilities to Mercurial's built-in server mode.</para>
-
-    <para id="x_366">The <literal role="hg-ext">fetch</literal>
-      extension adds a new command called, not surprisingly, <command
-	role="hg-cmd">hg fetch</command>.  This extension acts as a
-      combination of <command role="hg-cmd">hg pull -u</command>,
-      <command role="hg-cmd">hg merge</command> and <command
-	role="hg-cmd">hg commit</command>.  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
-      updates to the new head, begins a merge, then (if the merge
-      succeeded) 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.</para>
-
-    <para id="x_367">Enabling the <literal
-	role="hg-ext">fetch</literal> extension is easy.  Edit the
-      <filename role="special">.hgrc</filename> file in your home
-      directory, and either go to the <literal
-	role="rc-extensions">extensions</literal> section or create an
-      <literal role="rc-extensions">extensions</literal> section. Then
-      add a line that simply reads
-      <quote><literal>fetch=</literal></quote>.</para>
-
-    <programlisting>[extensions]
-fetch =</programlisting>
-
-    <para id="x_368">(Normally, the right-hand side of the
-      <quote><literal>=</literal></quote> would indicate where to find
-      the extension, but since the <literal
-	role="hg-ext">fetch</literal> extension is in the standard
-      distribution, Mercurial knows where to search for it.)</para>
-  </sect1>
-
-  <sect1>
-    <title>Renaming, copying, and merging</title>
-
-    <para id="x_729">During the life of a project, we will often want to change
-      the layout of its files and directories. This can be as simple
-      as renaming a single file, or as complex as restructuring the
-      entire hierarchy of files within the project.</para>
-
-    <para id="x_72a">Mercurial supports these kinds of complex changes fluently,
-      provided we tell it what we're doing.  If we want to rename a
-      file, we should use the <command>hg rename</command><footnote>
-	<para id="x_72b">If you're a Unix user, you'll be glad to know that the
-	  <command>hg rename</command> command can be abbreviated as
-	  <command>hg mv</command>.</para>
-      </footnote> command to rename it, so that Mercurial can do the
-      right thing later when we merge.</para>
-
-    <para id="x_72c">We will cover the use of these commands in more detail in
-      <xref linkend="chap:daily.copy"/>.</para>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- a/en/ch03-concepts.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,778 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:concepts">
-  <?dbhtml filename="behind-the-scenes.html"?>
-  <title>Behind the scenes</title>
-
-  <para id="x_2e8">Unlike many revision control systems, the concepts
-    upon which Mercurial is built are simple enough that it's easy to
-    understand how the software really works.  Knowing these details
-    certainly isn't necessary, so it is certainly safe to skip this
-    chapter.  However, I think you will get more out of the software
-    with a <quote>mental model</quote> of what's going on.</para>
-
-  <para id="x_2e9">Being able to understand what's going on behind the
-    scenes gives me confidence that Mercurial has been carefully
-    designed to be both <emphasis>safe</emphasis> and
-    <emphasis>efficient</emphasis>.  And just as importantly, if it's
-    easy for me to retain a good idea of what the software is doing
-    when I perform a revision control task, I'm less likely to be
-    surprised by its behavior.</para>
-
-  <para id="x_2ea">In this chapter, we'll initially cover the core concepts
-    behind Mercurial's design, then continue to discuss some of the
-    interesting details of its implementation.</para>
-
-  <sect1>
-    <title>Mercurial's historical record</title>
-
-    <sect2>
-      <title>Tracking the history of a single file</title>
-
-      <para id="x_2eb">When Mercurial tracks modifications to a file, it stores
-	the history of that file in a metadata object called a
-	<emphasis>filelog</emphasis>.  Each entry in the filelog
-	contains enough information to reconstruct one revision of the
-	file that is being tracked.  Filelogs are stored as files in
-	the <filename role="special"
-	  class="directory">.hg/store/data</filename> directory.  A
-	filelog contains two kinds of information: revision data, and
-	an index to help Mercurial to find a revision
-	efficiently.</para>
-
-      <para id="x_2ec">A file that is large, or has a lot of history, has its
-	filelog stored in separate data
-	(<quote><literal>.d</literal></quote> suffix) and index
-	(<quote><literal>.i</literal></quote> suffix) files.  For
-	small files without much history, the revision data and index
-	are combined in a single <quote><literal>.i</literal></quote>
-	file.  The correspondence between a file in the working
-	directory and the filelog that tracks its history in the
-	repository is illustrated in <xref
-	  linkend="fig:concepts:filelog"/>.</para>
-
-      <figure id="fig:concepts:filelog">
-	<title>Relationships between files in working directory and
-	  filelogs in repository</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/filelog.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-    </sect2>
-    <sect2>
-      <title>Managing tracked files</title>
-
-      <para id="x_2ee">Mercurial uses a structure called a
-	<emphasis>manifest</emphasis> to collect together information
-	about the files that it tracks.  Each entry in the manifest
-	contains information about the files present in a single
-	changeset.  An entry records which files are present in the
-	changeset, the revision of each file, and a few other pieces
-	of file metadata.</para>
-
-    </sect2>
-    <sect2>
-      <title>Recording changeset information</title>
-
-      <para id="x_2ef">The <emphasis>changelog</emphasis> contains information
-	about each changeset.  Each revision records who committed a
-	change, the changeset comment, other pieces of
-	changeset-related information, and the revision of the
-	manifest to use.</para>
-
-    </sect2>
-    <sect2>
-      <title>Relationships between revisions</title>
-
-      <para id="x_2f0">Within a changelog, a manifest, or a filelog, each
-	revision stores a pointer to its immediate parent (or to its
-	two parents, if it's a merge revision).  As I mentioned above,
-	there are also relationships between revisions
-	<emphasis>across</emphasis> these structures, and they are
-	hierarchical in nature.</para>
-
-      <para id="x_2f1">For every changeset in a repository, there is exactly one
-	revision stored in the changelog.  Each revision of the
-	changelog contains a pointer to a single revision of the
-	manifest.  A revision of the manifest stores a pointer to a
-	single revision of each filelog tracked when that changeset
-	was created.  These relationships are illustrated in
-	<xref linkend="fig:concepts:metadata"/>.</para>
-
-      <figure id="fig:concepts:metadata">
-	<title>Metadata relationships</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/metadata.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_2f3">As the illustration shows, there is
-	<emphasis>not</emphasis> a <quote>one to one</quote>
-	relationship between revisions in the changelog, manifest, or
-	filelog. If a file that
-	Mercurial tracks hasn't changed between two changesets, the
-	entry for that file in the two revisions of the manifest will
-	point to the same revision of its filelog<footnote>
-	  <para id="x_725">It is possible (though unusual) for the manifest to
-	    remain the same between two changesets, in which case the
-	    changelog entries for those changesets will point to the
-	    same revision of the manifest.</para>
-	</footnote>.</para>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Safe, efficient storage</title>
-
-    <para id="x_2f4">The underpinnings of changelogs, manifests, and filelogs are
-      provided by a single structure called the
-      <emphasis>revlog</emphasis>.</para>
-
-    <sect2>
-      <title>Efficient storage</title>
-
-      <para id="x_2f5">The revlog provides efficient storage of revisions using a
-	<emphasis>delta</emphasis> mechanism.  Instead of storing a
-	complete copy of a file for each revision, it stores the
-	changes needed to transform an older revision into the new
-	revision.  For many kinds of file data, these deltas are
-	typically a fraction of a percent of the size of a full copy
-	of a file.</para>
-
-      <para id="x_2f6">Some obsolete revision control systems can only work with
-	deltas of text files.  They must either store binary files as
-	complete snapshots or encoded into a text representation, both
-	of which are wasteful approaches.  Mercurial can efficiently
-	handle deltas of files with arbitrary binary contents; it
-	doesn't need to treat text as special.</para>
-
-    </sect2>
-    <sect2 id="sec:concepts:txn">
-      <title>Safe operation</title>
-
-      <para id="x_2f7">Mercurial only ever <emphasis>appends</emphasis> data to
-	the end of a revlog file. It never modifies a section of a
-	file after it has written it.  This is both more robust and
-	efficient than schemes that need to modify or rewrite
-	data.</para>
-
-      <para id="x_2f8">In addition, Mercurial treats every write as part of a
-	<emphasis>transaction</emphasis> that can span a number of
-	files.  A transaction is <emphasis>atomic</emphasis>: either
-	the entire transaction succeeds and its effects are all
-	visible to readers in one go, or the whole thing is undone.
-	This guarantee of atomicity means that if you're running two
-	copies of Mercurial, where one is reading data and one is
-	writing it, the reader will never see a partially written
-	result that might confuse it.</para>
-
-      <para id="x_2f9">The fact that Mercurial only appends to files makes it
-	easier to provide this transactional guarantee.  The easier it
-	is to do stuff like this, the more confident you should be
-	that it's done correctly.</para>
-
-    </sect2>
-    <sect2>
-      <title>Fast retrieval</title>
-
-      <para id="x_2fa">Mercurial cleverly avoids a pitfall common to
-	all earlier revision control systems: the problem of
-	<emphasis>inefficient retrieval</emphasis>. Most revision
-	control systems store the contents of a revision as an
-	incremental series of modifications against a
-	<quote>snapshot</quote>.  (Some base the snapshot on the
-	oldest revision, others on the newest.)  To reconstruct a
-	specific revision, you must first read the snapshot, and then
-	every one of the revisions between the snapshot and your
-	target revision.  The more history that a file accumulates,
-	the more revisions you must read, hence the longer it takes to
-	reconstruct a particular revision.</para>
-
-      <figure id="fig:concepts:snapshot">
-	<title>Snapshot of a revlog, with incremental deltas</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/snapshot.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_2fc">The innovation that Mercurial applies to this problem is
-	simple but effective.  Once the cumulative amount of delta
-	information stored since the last snapshot exceeds a fixed
-	threshold, it stores a new snapshot (compressed, of course),
-	instead of another delta.  This makes it possible to
-	reconstruct <emphasis>any</emphasis> revision of a file
-	quickly.  This approach works so well that it has since been
-	copied by several other revision control systems.</para>
-
-      <para id="x_2fd"><xref linkend="fig:concepts:snapshot"/> illustrates
-	the idea.  In an entry in a revlog's index file, Mercurial
-	stores the range of entries from the data file that it must
-	read to reconstruct a particular revision.</para>
-
-      <sect3>
-	<title>Aside: the influence of video compression</title>
-
-	<para id="x_2fe">If you're familiar with video compression or
-	  have ever watched a TV feed through a digital cable or
-	  satellite service, you may know that most video compression
-	  schemes store each frame of video as a delta against its
-	  predecessor frame.</para>
-
-	<para id="x_2ff">Mercurial borrows this idea to make it
-	  possible to reconstruct a revision from a snapshot and a
-	  small number of deltas.</para>
-
-      </sect3>
-    </sect2>
-    <sect2>
-      <title>Identification and strong integrity</title>
-
-      <para id="x_300">Along with delta or snapshot information, a revlog entry
-	contains a cryptographic hash of the data that it represents.
-	This makes it difficult to forge the contents of a revision,
-	and easy to detect accidental corruption.</para>
-
-      <para id="x_301">Hashes provide more than a mere check against corruption;
-	they are used as the identifiers for revisions.  The changeset
-	identification hashes that you see as an end user are from
-	revisions of the changelog.  Although filelogs and the
-	manifest also use hashes, Mercurial only uses these behind the
-	scenes.</para>
-
-      <para id="x_302">Mercurial verifies that hashes are correct when it
-	retrieves file revisions and when it pulls changes from
-	another repository.  If it encounters an integrity problem, it
-	will complain and stop whatever it's doing.</para>
-
-      <para id="x_303">In addition to the effect it has on retrieval efficiency,
-	Mercurial's use of periodic snapshots makes it more robust
-	against partial data corruption.  If a revlog becomes partly
-	corrupted due to a hardware error or system bug, it's often
-	possible to reconstruct some or most revisions from the
-	uncorrupted sections of the revlog, both before and after the
-	corrupted section.  This would not be possible with a
-	delta-only storage model.</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>Revision history, branching, and merging</title>
-
-    <para id="x_304">Every entry in a Mercurial revlog knows the identity of its
-      immediate ancestor revision, usually referred to as its
-      <emphasis>parent</emphasis>.  In fact, a revision contains room
-      for not one parent, but two.  Mercurial uses a special hash,
-      called the <quote>null ID</quote>, to represent the idea
-      <quote>there is no parent here</quote>.  This hash is simply a
-      string of zeroes.</para>
-
-    <para id="x_305">In <xref linkend="fig:concepts:revlog"/>, you can see
-      an example of the conceptual structure of a revlog.  Filelogs,
-      manifests, and changelogs all have this same structure; they
-      differ only in the kind of data stored in each delta or
-      snapshot.</para>
-
-    <para id="x_306">The first revision in a revlog (at the bottom of the image)
-      has the null ID in both of its parent slots.  For a
-      <quote>normal</quote> revision, its first parent slot contains
-      the ID of its parent revision, and its second contains the null
-      ID, indicating that the revision has only one real parent.  Any
-      two revisions that have the same parent ID are branches.  A
-      revision that represents a merge between branches has two normal
-      revision IDs in its parent slots.</para>
-
-    <figure id="fig:concepts:revlog">
-      <title>The conceptual structure of a revlog</title>
-      <mediaobject>
-	<imageobject><imagedata fileref="figs/revlog.png"/></imageobject>
-	<textobject><phrase>XXX add text</phrase></textobject>
-      </mediaobject>
-    </figure>
-
-  </sect1>
-  <sect1>
-    <title>The working directory</title>
-
-    <para id="x_307">In the working directory, Mercurial stores a snapshot of the
-      files from the repository as of a particular changeset.</para>
-
-    <para id="x_308">The working directory <quote>knows</quote> which changeset
-      it contains.  When you update the working directory to contain a
-      particular changeset, Mercurial looks up the appropriate
-      revision of the manifest to find out which files it was tracking
-      at the time that changeset was committed, and which revision of
-      each file was then current.  It then recreates a copy of each of
-      those files, with the same contents it had when the changeset
-      was committed.</para>
-
-    <para id="x_309">The <emphasis>dirstate</emphasis> is a special
-      structure that contains Mercurial's knowledge of the working
-      directory.  It is maintained as a file named
-      <filename>.hg/dirstate</filename> inside a repository.  The
-      dirstate details which changeset the working directory is
-      updated to, and all of the files that Mercurial is tracking in
-      the working directory. It also lets Mercurial quickly notice
-      changed files, by recording their checkout times and
-      sizes.</para>
-
-    <para id="x_30a">Just as a revision of a revlog has room for two parents, so
-      that it can represent either a normal revision (with one parent)
-      or a merge of two earlier revisions, the dirstate has slots for
-      two parents.  When you use the <command role="hg-cmd">hg
-	update</command> command, the changeset that you update to is
-      stored in the <quote>first parent</quote> slot, and the null ID
-      in the second. When you <command role="hg-cmd">hg
-	merge</command> with another changeset, the first parent
-      remains unchanged, and the second parent is filled in with the
-      changeset you're merging with.  The <command role="hg-cmd">hg
-	parents</command> command tells you what the parents of the
-      dirstate are.</para>
-
-    <sect2>
-      <title>What happens when you commit</title>
-
-      <para id="x_30b">The dirstate stores parent information for more than just
-	book-keeping purposes.  Mercurial uses the parents of the
-	dirstate as <emphasis>the parents of a new
-	  changeset</emphasis> when you perform a commit.</para>
-
-      <figure id="fig:concepts:wdir">
-	<title>The working directory can have two parents</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/wdir.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_30d"><xref linkend="fig:concepts:wdir"/> shows the
-	normal state of the working directory, where it has a single
-	changeset as parent.  That changeset is the
-	<emphasis>tip</emphasis>, the newest changeset in the
-	repository that has no children.</para>
-
-      <figure id="fig:concepts:wdir-after-commit">
-	<title>The working directory gains new parents after a
-	  commit</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/wdir-after-commit.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_30f">It's useful to think of the working directory as
-	<quote>the changeset I'm about to commit</quote>.  Any files
-	that you tell Mercurial that you've added, removed, renamed,
-	or copied will be reflected in that changeset, as will
-	modifications to any files that Mercurial is already tracking;
-	the new changeset will have the parents of the working
-	directory as its parents.</para>
-
-      <para id="x_310">After a commit, Mercurial will update the
-	parents of the working directory, so that the first parent is
-	the ID of the new changeset, and the second is the null ID.
-	This is shown in <xref
-	  linkend="fig:concepts:wdir-after-commit"/>. Mercurial
-	doesn't touch any of the files in the working directory when
-	you commit; it just modifies the dirstate to note its new
-	parents.</para>
-
-    </sect2>
-    <sect2>
-      <title>Creating a new head</title>
-
-      <para id="x_311">It's perfectly normal to update the working directory to a
-	changeset other than the current tip.  For example, you might
-	want to know what your project looked like last Tuesday, or
-	you could be looking through changesets to see which one
-	introduced a bug.  In cases like this, the natural thing to do
-	is update the working directory to the changeset you're
-	interested in, and then examine the files in the working
-	directory directly to see their contents as they were when you
-	committed that changeset.  The effect of this is shown in
-	<xref linkend="fig:concepts:wdir-pre-branch"/>.</para>
-
-      <figure id="fig:concepts:wdir-pre-branch">
-	<title>The working directory, updated to an older
-	  changeset</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/wdir-pre-branch.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_313">Having updated the working directory to an
-	older changeset, what happens if you make some changes, and
-	then commit?  Mercurial behaves in the same way as I outlined
-	above.  The parents of the working directory become the
-	parents of the new changeset.  This new changeset has no
-	children, so it becomes the new tip.  And the repository now
-	contains two changesets that have no children; we call these
-	<emphasis>heads</emphasis>.  You can see the structure that
-	this creates in <xref
-	  linkend="fig:concepts:wdir-branch"/>.</para>
-
-      <figure id="fig:concepts:wdir-branch">
-	<title>After a commit made while synced to an older
-	  changeset</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/wdir-branch.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <note>
-	<para id="x_315">If you're new to Mercurial, you should keep
-	  in mind a common <quote>error</quote>, which is to use the
-	  <command role="hg-cmd">hg pull</command> command without any
-	  options.  By default, the <command role="hg-cmd">hg
-	    pull</command> command <emphasis>does not</emphasis>
-	  update the working directory, so you'll bring new changesets
-	  into your repository, but the working directory will stay
-	  synced at the same changeset as before the pull.  If you
-	  make some changes and commit afterwards, you'll thus create
-	  a new head, because your working directory isn't synced to
-	  whatever the current tip is.  To combine the operation of a
-	  pull, followed by an update, run <command>hg pull
-	    -u</command>.</para>
-
-	<para id="x_316">I put the word <quote>error</quote> in quotes
-	  because all that you need to do to rectify the situation
-	  where you created a new head by accident is
-	  <command role="hg-cmd">hg merge</command>, then <command
-	    role="hg-cmd">hg commit</command>.  In other words, this
-	  almost never has negative consequences; it's just something
-	  of a surprise for newcomers.  I'll discuss other ways to
-	  avoid this behavior, and why Mercurial behaves in this
-	  initially surprising way, later on.</para>
-      </note>
-
-    </sect2>
-    <sect2>
-      <title>Merging changes</title>
-
-      <para id="x_317">When you run the <command role="hg-cmd">hg
-	  merge</command> command, Mercurial leaves the first parent
-	of the working directory unchanged, and sets the second parent
-	to the changeset you're merging with, as shown in <xref
-	  linkend="fig:concepts:wdir-merge"/>.</para>
-
-      <figure id="fig:concepts:wdir-merge">
-	<title>Merging two heads</title>
-	<mediaobject>
-	  <imageobject>
-	    <imagedata fileref="figs/wdir-merge.png"/>
-	  </imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_319">Mercurial also has to modify the working directory, to
-	merge the files managed in the two changesets.  Simplified a
-	little, the merging process goes like this, for every file in
-	the manifests of both changesets.</para>
-      <itemizedlist>
-	<listitem><para id="x_31a">If neither changeset has modified a file, do
-	    nothing with that file.</para>
-	</listitem>
-	<listitem><para id="x_31b">If one changeset has modified a file, and the
-	    other hasn't, create the modified copy of the file in the
-	    working directory.</para>
-	</listitem>
-	<listitem><para id="x_31c">If one changeset has removed a file, and the
-	    other hasn't (or has also deleted it), delete the file
-	    from the working directory.</para>
-	</listitem>
-	<listitem><para id="x_31d">If one changeset has removed a file, but the
-	    other has modified the file, ask the user what to do: keep
-	    the modified file, or remove it?</para>
-	</listitem>
-	<listitem><para id="x_31e">If both changesets have modified a file,
-	    invoke an external merge program to choose the new
-	    contents for the merged file.  This may require input from
-	    the user.</para>
-	</listitem>
-	<listitem><para id="x_31f">If one changeset has modified a file, and the
-	    other has renamed or copied the file, make sure that the
-	    changes follow the new name of the file.</para>
-	</listitem></itemizedlist>
-      <para id="x_320">There are more details&emdash;merging has plenty of corner
-	cases&emdash;but these are the most common choices that are
-	involved in a merge.  As you can see, most cases are
-	completely automatic, and indeed most merges finish
-	automatically, without requiring your input to resolve any
-	conflicts.</para>
-
-      <para id="x_321">When you're thinking about what happens when you commit
-	after a merge, once again the working directory is <quote>the
-	  changeset I'm about to commit</quote>.  After the <command
-	  role="hg-cmd">hg merge</command> command completes, the
-	working directory has two parents; these will become the
-	parents of the new changeset.</para>
-
-      <para id="x_322">Mercurial lets you perform multiple merges, but
-	you must commit the results of each individual merge as you
-	go.  This is necessary because Mercurial only tracks two
-	parents for both revisions and the working directory.  While
-	it would be technically feasible to merge multiple changesets
-	at once, Mercurial avoids this for simplicity.  With multi-way
-	merges, the risks of user confusion, nasty conflict
-	resolution, and making a terrible mess of a merge would grow
-	intolerable.</para>
-
-    </sect2>
-
-    <sect2>
-      <title>Merging and renames</title>
-
-      <para id="x_69a">A surprising number of revision control systems pay little
-	or no attention to a file's <emphasis>name</emphasis> over
-	time.  For instance, it used to be common that if a file got
-	renamed on one side of a merge, the changes from the other
-	side would be silently dropped.</para>
-
-      <para id="x_69b">Mercurial records metadata when you tell it to perform a
-	rename or copy. It uses this metadata during a merge to do the
-	right thing in the case of a merge.  For instance, if I rename
-	a file, and you edit it without renaming it, when we merge our
-	work the file will be renamed and have your edits
-	applied.</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>Other interesting design features</title>
-
-    <para id="x_323">In the sections above, I've tried to highlight some of the
-      most important aspects of Mercurial's design, to illustrate that
-      it pays careful attention to reliability and performance.
-      However, the attention to detail doesn't stop there.  There are
-      a number of other aspects of Mercurial's construction that I
-      personally find interesting.  I'll detail a few of them here,
-      separate from the <quote>big ticket</quote> items above, so that
-      if you're interested, you can gain a better idea of the amount
-      of thinking that goes into a well-designed system.</para>
-
-    <sect2>
-      <title>Clever compression</title>
-
-      <para id="x_324">When appropriate, Mercurial will store both snapshots and
-	deltas in compressed form.  It does this by always
-	<emphasis>trying to</emphasis> compress a snapshot or delta,
-	but only storing the compressed version if it's smaller than
-	the uncompressed version.</para>
-
-      <para id="x_325">This means that Mercurial does <quote>the right
-	  thing</quote> when storing a file whose native form is
-	compressed, such as a <literal>zip</literal> archive or a JPEG
-	image.  When these types of files are compressed a second
-	time, the resulting file is usually bigger than the
-	once-compressed form, and so Mercurial will store the plain
-	<literal>zip</literal> or JPEG.</para>
-
-      <para id="x_326">Deltas between revisions of a compressed file are usually
-	larger than snapshots of the file, and Mercurial again does
-	<quote>the right thing</quote> in these cases.  It finds that
-	such a delta exceeds the threshold at which it should store a
-	complete snapshot of the file, so it stores the snapshot,
-	again saving space compared to a naive delta-only
-	approach.</para>
-
-      <sect3>
-	<title>Network recompression</title>
-
-	<para id="x_327">When storing revisions on disk, Mercurial uses the
-	  <quote>deflate</quote> compression algorithm (the same one
-	  used by the popular <literal>zip</literal> archive format),
-	  which balances good speed with a respectable compression
-	  ratio.  However, when transmitting revision data over a
-	  network connection, Mercurial uncompresses the compressed
-	  revision data.</para>
-
-	<para id="x_328">If the connection is over HTTP, Mercurial recompresses
-	  the entire stream of data using a compression algorithm that
-	  gives a better compression ratio (the Burrows-Wheeler
-	  algorithm from the widely used <literal>bzip2</literal>
-	  compression package).  This combination of algorithm and
-	  compression of the entire stream (instead of a revision at a
-	  time) substantially reduces the number of bytes to be
-	  transferred, yielding better network performance over most
-	  kinds of network.</para>
-
-	<para id="x_329">If the connection is over
-	  <command>ssh</command>, Mercurial
-	  <emphasis>doesn't</emphasis> recompress the stream, because
-	  <command>ssh</command> can already do this itself.  You can
-	  tell Mercurial to always use <command>ssh</command>'s
-	  compression feature by editing the
-	  <filename>.hgrc</filename> file in your home directory as
-	  follows.</para>
-
-	<programlisting>[ui]
-ssh = ssh -C</programlisting>
-
-      </sect3>
-    </sect2>
-    <sect2>
-      <title>Read/write ordering and atomicity</title>
-
-      <para id="x_32a">Appending to files isn't the whole story when
-	it comes to guaranteeing that a reader won't see a partial
-	write.  If you recall <xref linkend="fig:concepts:metadata"/>,
-	revisions in the changelog point to revisions in the manifest,
-	and revisions in the manifest point to revisions in filelogs.
-	This hierarchy is deliberate.</para>
-
-      <para id="x_32b">A writer starts a transaction by writing filelog and
-	manifest data, and doesn't write any changelog data until
-	those are finished.  A reader starts by reading changelog
-	data, then manifest data, followed by filelog data.</para>
-
-      <para id="x_32c">Since the writer has always finished writing filelog and
-	manifest data before it writes to the changelog, a reader will
-	never read a pointer to a partially written manifest revision
-	from the changelog, and it will never read a pointer to a
-	partially written filelog revision from the manifest.</para>
-
-    </sect2>
-    <sect2>
-      <title>Concurrent access</title>
-
-      <para id="x_32d">The read/write ordering and atomicity guarantees mean that
-	Mercurial never needs to <emphasis>lock</emphasis> a
-	repository when it's reading data, even if the repository is
-	being written to while the read is occurring. This has a big
-	effect on scalability; you can have an arbitrary number of
-	Mercurial processes safely reading data from a repository
-	all at once, no matter whether it's being written to or
-	not.</para>
-
-      <para id="x_32e">The lockless nature of reading means that if you're
-	sharing a repository on a multi-user system, you don't need to
-	grant other local users permission to
-	<emphasis>write</emphasis> to your repository in order for
-	them to be able to clone it or pull changes from it; they only
-	need <emphasis>read</emphasis> permission.  (This is
-	<emphasis>not</emphasis> a common feature among revision
-	control systems, so don't take it for granted!  Most require
-	readers to be able to lock a repository to access it safely,
-	and this requires write permission on at least one directory,
-	which of course makes for all kinds of nasty and annoying
-	security and administrative problems.)</para>
-
-      <para id="x_32f">Mercurial uses locks to ensure that only one process can
-	write to a repository at a time (the locking mechanism is safe
-	even over filesystems that are notoriously hostile to locking,
-	such as NFS).  If a repository is locked, a writer will wait
-	for a while to retry if the repository becomes unlocked, but
-	if the repository remains locked for too long, the process
-	attempting to write will time out after a while. This means
-	that your daily automated scripts won't get stuck forever and
-	pile up if a system crashes unnoticed, for example.  (Yes, the
-	timeout is configurable, from zero to infinity.)</para>
-
-      <sect3>
-	<title>Safe dirstate access</title>
-
-	<para id="x_330">As with revision data, Mercurial doesn't take a lock to
-	  read the dirstate file; it does acquire a lock to write it.
-	  To avoid the possibility of reading a partially written copy
-	  of the dirstate file, Mercurial writes to a file with a
-	  unique name in the same directory as the dirstate file, then
-	  renames the temporary file atomically to
-	  <filename>dirstate</filename>.  The file named
-	  <filename>dirstate</filename> is thus guaranteed to be
-	  complete, not partially written.</para>
-
-      </sect3>
-    </sect2>
-    <sect2>
-      <title>Avoiding seeks</title>
-
-      <para id="x_331">Critical to Mercurial's performance is the avoidance of
-	seeks of the disk head, since any seek is far more expensive
-	than even a comparatively large read operation.</para>
-
-      <para id="x_332">This is why, for example, the dirstate is stored in a
-	single file.  If there were a dirstate file per directory that
-	Mercurial tracked, the disk would seek once per directory.
-	Instead, Mercurial reads the entire single dirstate file in
-	one step.</para>
-
-      <para id="x_333">Mercurial also uses a <quote>copy on write</quote> scheme
-	when cloning a repository on local storage.  Instead of
-	copying every revlog file from the old repository into the new
-	repository, it makes a <quote>hard link</quote>, which is a
-	shorthand way to say <quote>these two names point to the same
-	  file</quote>.  When Mercurial is about to write to one of a
-	revlog's files, it checks to see if the number of names
-	pointing at the file is greater than one.  If it is, more than
-	one repository is using the file, so Mercurial makes a new
-	copy of the file that is private to this repository.</para>
-
-      <para id="x_334">A few revision control developers have pointed out that
-	this idea of making a complete private copy of a file is not
-	very efficient in its use of storage.  While this is true,
-	storage is cheap, and this method gives the highest
-	performance while deferring most book-keeping to the operating
-	system.  An alternative scheme would most likely reduce
-	performance and increase the complexity of the software, but
-	speed and simplicity are key to the <quote>feel</quote> of
-	day-to-day use.</para>
-
-    </sect2>
-    <sect2>
-      <title>Other contents of the dirstate</title>
-
-      <para id="x_335">Because Mercurial doesn't force you to tell it when you're
-	modifying a file, it uses the dirstate to store some extra
-	information so it can determine efficiently whether you have
-	modified a file.  For each file in the working directory, it
-	stores the time that it last modified the file itself, and the
-	size of the file at that time.</para>
-
-      <para id="x_336">When you explicitly <command role="hg-cmd">hg
-	  add</command>, <command role="hg-cmd">hg remove</command>,
-	<command role="hg-cmd">hg rename</command> or <command
-	  role="hg-cmd">hg copy</command> files, Mercurial updates the
-	dirstate so that it knows what to do with those files when you
-	commit.</para>
-
-      <para id="x_337">The dirstate helps Mercurial to efficiently
-	  check the status of files in a repository.</para>
-
-      <itemizedlist>
-	<listitem>
-	  <para id="x_726">When Mercurial checks the state of a file in the
-	    working directory, it first checks a file's modification
-	    time against the time in the dirstate that records when
-	    Mercurial last wrote the file. If the last modified time
-	    is the same as the time when Mercurial wrote the file, the
-	    file must not have been modified, so Mercurial does not
-	    need to check any further.</para>
-	</listitem>
-	<listitem>
-	  <para id="x_727">If the file's size has changed, the file must have
-	    been modified.  If the modification time has changed, but
-	    the size has not, only then does Mercurial need to
-	    actually read the contents of the file to see if it has
-	    changed.</para>
-	</listitem>
-      </itemizedlist>
-
-      <para id="x_728">Storing the modification time and size dramatically
-	reduces the number of read operations that Mercurial needs to
-	perform when we run commands like <command>hg status</command>.
-	This results in large performance improvements.</para>
-    </sect2>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch03-tour-merge.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,454 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:tour-merge">
+  <?dbhtml filename="a-tour-of-mercurial-merging-work.html"?>
+  <title>A tour of Mercurial: merging work</title>
+
+  <para id="x_338">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 <emphasis>merging</emphasis>
+    changes from separate repositories.</para>
+
+  <sect1>
+    <title>Merging streams of work</title>
+
+    <para id="x_339">Merging is a fundamental part of working with a distributed
+      revision control tool.  Here are a few cases in which the need
+      to merge work arises.</para>
+    <itemizedlist>
+      <listitem>
+	<para id="x_33a">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.</para>
+      </listitem>
+      <listitem>
+	<para id="x_33b">Cynthia frequently works on several different
+	  tasks for a single project at once, each safely isolated in
+	  its own repository. Working this way means that she often
+	  needs to merge one piece of her own work with
+	  another.</para>
+      </listitem>
+    </itemizedlist>
+
+    <para id="x_33c">Because we need to merge often, Mercurial makes
+      the process easy.  Let's walk through a merge.  We'll begin by
+      cloning yet another repository (see how often they spring up?)
+      and making a change in it.</para>
+
+    &interaction.tour.merge.clone;
+
+    <para id="x_33d">We should now have two copies of
+      <filename>hello.c</filename> with different contents.  The
+      histories of the two repositories have also diverged, as
+      illustrated in <xref
+	linkend="fig:tour-merge:sep-repos"/>.  Here is a copy of our
+      file from one repository.</para>
+
+    &interaction.tour.merge.cat1;
+
+    <para id="x_722">And here is our slightly different version from the other
+      repository.</para>
+
+    &interaction.tour.merge.cat2;
+
+    <figure id="fig:tour-merge:sep-repos">
+      <title>Divergent recent histories of the <filename
+	  class="directory">my-hello</filename> and <filename
+	  class="directory">my-new-hello</filename>
+	repositories</title>
+      <mediaobject>
+	<imageobject><imagedata fileref="figs/tour-merge-sep-repos.png"/></imageobject>
+	<textobject><phrase>XXX add text</phrase></textobject>
+      </mediaobject>
+    </figure>
+
+    <para id="x_33f">We already know that pulling changes from our <filename
+	class="directory">my-hello</filename> repository will have no
+      effect on the working directory.</para>
+
+    &interaction.tour.merge.pull;
+
+    <para id="x_340">However, the <command role="hg-cmd">hg pull</command>
+      command says something about <quote>heads</quote>.</para>
+
+    <sect2>
+      <title>Head changesets</title>
+
+      <para id="x_341">Remember that Mercurial records what the parent
+	of each change is.  If a change has a parent, we call it a
+	child or descendant of the parent.  A head is a change that
+	has no children.  The tip revision is thus a head, because the
+	newest revision in a repository doesn't have any children.
+	There are times when a repository can contain more than one
+	head.</para>
+
+      <figure id="fig:tour-merge:pull">
+	<title>Repository contents after pulling from <filename
+	    class="directory">my-hello</filename> into <filename
+	    class="directory">my-new-hello</filename></title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="figs/tour-merge-pull.png"/>
+	  </imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_343">In <xref linkend="fig:tour-merge:pull"/>, you can
+	see the effect of the pull from <filename
+	  class="directory">my-hello</filename> into <filename
+	  class="directory">my-new-hello</filename>.  The history that
+	was already present in <filename
+	  class="directory">my-new-hello</filename> is untouched, but
+	a new revision has been added.  By referring to <xref
+	  linkend="fig:tour-merge:sep-repos"/>, we can see that the
+	<emphasis>changeset ID</emphasis> remains the same in the new
+	repository, but the <emphasis>revision number</emphasis> 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 <command
+	  role="hg-cmd">hg heads</command> command.</para>
+
+      &interaction.tour.merge.heads;
+    </sect2>
+
+    <sect2>
+      <title>Performing the merge</title>
+
+      <para id="x_344">What happens if we try to use the normal <command
+	  role="hg-cmd">hg update</command> command to update to the
+	new tip?</para>
+
+      &interaction.tour.merge.update;
+
+      <para id="x_345">Mercurial is telling us that the <command
+	  role="hg-cmd">hg update</command> command won't do a merge;
+	it won't update the working directory when it thinks we might
+	want to do a merge, unless we force it to do so.
+	(Incidentally, forcing the update with <command>hg update
+	  -C</command> would revert any uncommitted changes in the
+	working directory.)</para>
+
+      <para id="x_723">To start a merge between the two heads, we use the
+	<command role="hg-cmd">hg merge</command> command.</para>
+
+      &interaction.tour.merge.merge;
+
+      <para id="x_347">We resolve the contents of <filename>hello.c</filename>
+
+This updates the working directory so that it
+	contains changes from <emphasis>both</emphasis> heads, which
+	is reflected in both the output of <command role="hg-cmd">hg
+	  parents</command> and the contents of
+	<filename>hello.c</filename>.</para>
+
+      &interaction.tour.merge.parents;
+    </sect2>
+
+    <sect2>
+      <title>Committing the results of the merge</title>
+
+      <para id="x_348">Whenever we've done a merge, <command role="hg-cmd">hg
+	  parents</command> will display two parents until we <command
+	  role="hg-cmd">hg commit</command> the results of the
+	  merge.</para>
+
+	&interaction.tour.merge.commit;
+
+      <para id="x_349">We now have a new tip revision; notice that it has
+	<emphasis>both</emphasis> of our former heads as its parents.
+	These are the same revisions that were previously displayed by
+	<command role="hg-cmd">hg parents</command>.</para>
+
+      &interaction.tour.merge.tip;
+
+      <para id="x_34a">In <xref
+	  linkend="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.</para>
+
+      <figure id="fig:tour-merge:merge">
+	<title>Working directory and repository during merge, and
+	  following commit</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="figs/tour-merge-merge.png"/>
+	  </imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_69c">We sometimes talk about a merge having
+	<emphasis>sides</emphasis>: the left side is the first parent
+	in the output of <command role="hg-cmd">hg parents</command>,
+	and the right side is the second.  If the working directory
+	was at e.g. revision 5 before we began a merge, that revision
+	will become the left side of the merge.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Merging conflicting changes</title>
+
+    <para id="x_34b">Most merges are simple affairs, but sometimes you'll find
+      yourself merging changes where each side modifies the same portions
+      of the same files.  Unless both modifications are identical,
+      this results in a <emphasis>conflict</emphasis>, where you have
+      to decide how to reconcile the different changes into something
+      coherent.</para>
+
+    <figure id="fig:tour-merge:conflict">
+      <title>Conflicting changes to a document</title>
+      <mediaobject>
+	<imageobject><imagedata fileref="figs/tour-merge-conflict.png"/></imageobject>
+	<textobject><phrase>XXX add text</phrase></textobject>
+      </mediaobject>
+    </figure>
+
+    <para id="x_34d"><xref linkend="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.</para>
+
+    <para id="x_34e">Mercurial doesn't have a built-in facility for handling
+      conflicts. Instead, it runs an external program, usually one
+      that displays some kind of graphical conflict resolution
+      interface.  By default, Mercurial tries 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, it tries a few
+      different graphical merging tools.</para>
+
+    <para id="x_34f">It's also possible to get Mercurial to run a
+      specific program or script, by setting the
+      <envar>HGMERGE</envar> environment variable to the name of your
+      preferred program.</para>
+
+    <sect2>
+      <title>Using a graphical merge tool</title>
+
+      <para id="x_350">My preferred graphical merge tool is
+	<command>kdiff3</command>, which I'll use to describe the
+	features that are common to graphical file merging tools.  You
+	can see a screenshot of <command>kdiff3</command> in action in
+	<xref linkend="fig:tour-merge:kdiff3"/>.  The kind of
+	merge it is performing is called a <emphasis>three-way
+	  merge</emphasis>, 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:</para>
+      <itemizedlist>
+	<listitem><para id="x_351">At the left is the <emphasis>base</emphasis>
+	    version of the file, i.e. the most recent version from
+	    which the two versions we're trying to merge are
+	    descended.</para>
+	</listitem>
+	<listitem><para id="x_352">In the middle is <quote>our</quote> version of
+	    the file, with the contents that we modified.</para>
+	</listitem>
+	<listitem><para id="x_353">On the right is <quote>their</quote> version
+	    of the file, the one that from the changeset that we're
+	    trying to merge with.</para>
+	</listitem></itemizedlist>
+      <para id="x_354">In the pane below these is the current
+	<emphasis>result</emphasis> of the merge. Our task is to
+	replace all of the red text, which indicates unresolved
+	conflicts, with some sensible merger of the
+	<quote>ours</quote> and <quote>theirs</quote> versions of the
+	file.</para>
+
+      <para id="x_355">All four of these panes are <emphasis>locked
+	  together</emphasis>; if we scroll vertically or horizontally
+	in any of them, the others are updated to display the
+	corresponding sections of their respective files.</para>
+
+      <figure id="fig:tour-merge:kdiff3">
+	<title>Using <command>kdiff3</command> to merge versions of a
+	  file</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject>
+	  <textobject>
+	    <phrase>XXX add text</phrase>
+	  </textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_357">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.</para>
+
+      <para id="x_358">There are <emphasis>many</emphasis> 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).</para>
+    </sect2>
+
+    <sect2>
+      <title>A worked example</title>
+
+      <para id="x_359">In this example, we will reproduce the file modification
+	history of <xref linkend="fig:tour-merge:conflict"/>
+	above.  Let's begin by creating a repository with a base
+	version of our document.</para>
+
+      &interaction.tour-merge-conflict.wife;
+
+      <para id="x_35a">We'll clone the repository and make a change to the
+	file.</para>
+
+      &interaction.tour-merge-conflict.cousin;
+
+      <para id="x_35b">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.)</para>
+
+      &interaction.tour-merge-conflict.son;
+
+      <para id="x_35c">Having created two
+	different versions of the file, we'll set up an environment
+	suitable for running our merge.</para>
+
+      &interaction.tour-merge-conflict.pull;
+
+      <para id="x_35d">In this example, I'll set
+	<envar>HGMERGE</envar> to tell Mercurial to use the
+	non-interactive <command>merge</command> command.  This is
+	bundled with many Unix-like systems. (If you're following this
+	example on your computer, don't bother setting
+	<envar>HGMERGE</envar>.  You'll get dropped into a GUI file
+	merge tool instead, which is much preferable.)</para>
+
+      &interaction.tour-merge-conflict.merge;
+
+      <para id="x_35f">Because <command>merge</command> can't resolve the
+	conflicting changes, it leaves <emphasis>merge
+	  markers</emphasis> inside the file that has conflicts,
+	indicating which lines have conflicts, and whether they came
+	from our version of the file or theirs.</para>
+
+      <para id="x_360">Mercurial can tell from the way <command>merge</command>
+	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.</para>
+
+      <para id="x_361">If automatic or manual merges fail, there's nothing to
+	prevent us from <quote>fixing up</quote> the affected files
+	ourselves, and committing the results of our merge:</para>
+
+      &interaction.tour-merge-conflict.commit;
+
+      <note>
+	<title>Where is the <command>hg resolve</command> command?</title>
+
+	<para id="x_724">The <command>hg resolve</command> command was introduced
+	  in Mercurial 1.1, which was released in December 2008. If
+	  you are using an older version of Mercurial (run <command>hg
+	    version</command> to see), this command will not be
+	  present.  If your version of Mercurial is older than 1.1,
+	  you should strongly consider upgrading to a newer version
+	  before trying to tackle complicated merges.</para>
+      </note>
+    </sect2>
+  </sect1>
+
+  <sect1 id="sec:tour-merge:fetch">
+    <title>Simplifying the pull-merge-commit sequence</title>
+
+    <para id="x_362">The process of merging changes as outlined above is
+      straightforward, but requires running three commands in
+      sequence.</para>
+    <programlisting>hg pull -u
+hg merge
+hg commit -m 'Merged remote changes'</programlisting>
+    <para id="x_363">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 <quote>boilerplate</quote> text.</para>
+
+    <para id="x_364">It would be nice to reduce the number of steps needed, if
+      this were possible.  Indeed, Mercurial is distributed with an
+      extension called <literal role="hg-ext">fetch</literal> that
+      does just this.</para>
+
+    <para id="x_365">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 <quote>behind the scenes,</quote> for example adding
+      capabilities to Mercurial's built-in server mode.</para>
+
+    <para id="x_366">The <literal role="hg-ext">fetch</literal>
+      extension adds a new command called, not surprisingly, <command
+	role="hg-cmd">hg fetch</command>.  This extension acts as a
+      combination of <command role="hg-cmd">hg pull -u</command>,
+      <command role="hg-cmd">hg merge</command> and <command
+	role="hg-cmd">hg commit</command>.  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
+      updates to the new head, begins a merge, then (if the merge
+      succeeded) 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.</para>
+
+    <para id="x_367">Enabling the <literal
+	role="hg-ext">fetch</literal> extension is easy.  Edit the
+      <filename role="special">.hgrc</filename> file in your home
+      directory, and either go to the <literal
+	role="rc-extensions">extensions</literal> section or create an
+      <literal role="rc-extensions">extensions</literal> section. Then
+      add a line that simply reads
+      <quote><literal>fetch=</literal></quote>.</para>
+
+    <programlisting>[extensions]
+fetch =</programlisting>
+
+    <para id="x_368">(Normally, the right-hand side of the
+      <quote><literal>=</literal></quote> would indicate where to find
+      the extension, but since the <literal
+	role="hg-ext">fetch</literal> extension is in the standard
+      distribution, Mercurial knows where to search for it.)</para>
+  </sect1>
+
+  <sect1>
+    <title>Renaming, copying, and merging</title>
+
+    <para id="x_729">During the life of a project, we will often want to change
+      the layout of its files and directories. This can be as simple
+      as renaming a single file, or as complex as restructuring the
+      entire hierarchy of files within the project.</para>
+
+    <para id="x_72a">Mercurial supports these kinds of complex changes fluently,
+      provided we tell it what we're doing.  If we want to rename a
+      file, we should use the <command>hg rename</command><footnote>
+	<para id="x_72b">If you're a Unix user, you'll be glad to know that the
+	  <command>hg rename</command> command can be abbreviated as
+	  <command>hg mv</command>.</para>
+      </footnote> command to rename it, so that Mercurial can do the
+      right thing later when we merge.</para>
+
+    <para id="x_72c">We will cover the use of these commands in more detail in
+      <xref linkend="chap:daily.copy"/>.</para>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch04-concepts.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,778 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:concepts">
+  <?dbhtml filename="behind-the-scenes.html"?>
+  <title>Behind the scenes</title>
+
+  <para id="x_2e8">Unlike many revision control systems, the concepts
+    upon which Mercurial is built are simple enough that it's easy to
+    understand how the software really works.  Knowing these details
+    certainly isn't necessary, so it is certainly safe to skip this
+    chapter.  However, I think you will get more out of the software
+    with a <quote>mental model</quote> of what's going on.</para>
+
+  <para id="x_2e9">Being able to understand what's going on behind the
+    scenes gives me confidence that Mercurial has been carefully
+    designed to be both <emphasis>safe</emphasis> and
+    <emphasis>efficient</emphasis>.  And just as importantly, if it's
+    easy for me to retain a good idea of what the software is doing
+    when I perform a revision control task, I'm less likely to be
+    surprised by its behavior.</para>
+
+  <para id="x_2ea">In this chapter, we'll initially cover the core concepts
+    behind Mercurial's design, then continue to discuss some of the
+    interesting details of its implementation.</para>
+
+  <sect1>
+    <title>Mercurial's historical record</title>
+
+    <sect2>
+      <title>Tracking the history of a single file</title>
+
+      <para id="x_2eb">When Mercurial tracks modifications to a file, it stores
+	the history of that file in a metadata object called a
+	<emphasis>filelog</emphasis>.  Each entry in the filelog
+	contains enough information to reconstruct one revision of the
+	file that is being tracked.  Filelogs are stored as files in
+	the <filename role="special"
+	  class="directory">.hg/store/data</filename> directory.  A
+	filelog contains two kinds of information: revision data, and
+	an index to help Mercurial to find a revision
+	efficiently.</para>
+
+      <para id="x_2ec">A file that is large, or has a lot of history, has its
+	filelog stored in separate data
+	(<quote><literal>.d</literal></quote> suffix) and index
+	(<quote><literal>.i</literal></quote> suffix) files.  For
+	small files without much history, the revision data and index
+	are combined in a single <quote><literal>.i</literal></quote>
+	file.  The correspondence between a file in the working
+	directory and the filelog that tracks its history in the
+	repository is illustrated in <xref
+	  linkend="fig:concepts:filelog"/>.</para>
+
+      <figure id="fig:concepts:filelog">
+	<title>Relationships between files in working directory and
+	  filelogs in repository</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/filelog.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+    </sect2>
+    <sect2>
+      <title>Managing tracked files</title>
+
+      <para id="x_2ee">Mercurial uses a structure called a
+	<emphasis>manifest</emphasis> to collect together information
+	about the files that it tracks.  Each entry in the manifest
+	contains information about the files present in a single
+	changeset.  An entry records which files are present in the
+	changeset, the revision of each file, and a few other pieces
+	of file metadata.</para>
+
+    </sect2>
+    <sect2>
+      <title>Recording changeset information</title>
+
+      <para id="x_2ef">The <emphasis>changelog</emphasis> contains information
+	about each changeset.  Each revision records who committed a
+	change, the changeset comment, other pieces of
+	changeset-related information, and the revision of the
+	manifest to use.</para>
+
+    </sect2>
+    <sect2>
+      <title>Relationships between revisions</title>
+
+      <para id="x_2f0">Within a changelog, a manifest, or a filelog, each
+	revision stores a pointer to its immediate parent (or to its
+	two parents, if it's a merge revision).  As I mentioned above,
+	there are also relationships between revisions
+	<emphasis>across</emphasis> these structures, and they are
+	hierarchical in nature.</para>
+
+      <para id="x_2f1">For every changeset in a repository, there is exactly one
+	revision stored in the changelog.  Each revision of the
+	changelog contains a pointer to a single revision of the
+	manifest.  A revision of the manifest stores a pointer to a
+	single revision of each filelog tracked when that changeset
+	was created.  These relationships are illustrated in
+	<xref linkend="fig:concepts:metadata"/>.</para>
+
+      <figure id="fig:concepts:metadata">
+	<title>Metadata relationships</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/metadata.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_2f3">As the illustration shows, there is
+	<emphasis>not</emphasis> a <quote>one to one</quote>
+	relationship between revisions in the changelog, manifest, or
+	filelog. If a file that
+	Mercurial tracks hasn't changed between two changesets, the
+	entry for that file in the two revisions of the manifest will
+	point to the same revision of its filelog<footnote>
+	  <para id="x_725">It is possible (though unusual) for the manifest to
+	    remain the same between two changesets, in which case the
+	    changelog entries for those changesets will point to the
+	    same revision of the manifest.</para>
+	</footnote>.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Safe, efficient storage</title>
+
+    <para id="x_2f4">The underpinnings of changelogs, manifests, and filelogs are
+      provided by a single structure called the
+      <emphasis>revlog</emphasis>.</para>
+
+    <sect2>
+      <title>Efficient storage</title>
+
+      <para id="x_2f5">The revlog provides efficient storage of revisions using a
+	<emphasis>delta</emphasis> mechanism.  Instead of storing a
+	complete copy of a file for each revision, it stores the
+	changes needed to transform an older revision into the new
+	revision.  For many kinds of file data, these deltas are
+	typically a fraction of a percent of the size of a full copy
+	of a file.</para>
+
+      <para id="x_2f6">Some obsolete revision control systems can only work with
+	deltas of text files.  They must either store binary files as
+	complete snapshots or encoded into a text representation, both
+	of which are wasteful approaches.  Mercurial can efficiently
+	handle deltas of files with arbitrary binary contents; it
+	doesn't need to treat text as special.</para>
+
+    </sect2>
+    <sect2 id="sec:concepts:txn">
+      <title>Safe operation</title>
+
+      <para id="x_2f7">Mercurial only ever <emphasis>appends</emphasis> data to
+	the end of a revlog file. It never modifies a section of a
+	file after it has written it.  This is both more robust and
+	efficient than schemes that need to modify or rewrite
+	data.</para>
+
+      <para id="x_2f8">In addition, Mercurial treats every write as part of a
+	<emphasis>transaction</emphasis> that can span a number of
+	files.  A transaction is <emphasis>atomic</emphasis>: either
+	the entire transaction succeeds and its effects are all
+	visible to readers in one go, or the whole thing is undone.
+	This guarantee of atomicity means that if you're running two
+	copies of Mercurial, where one is reading data and one is
+	writing it, the reader will never see a partially written
+	result that might confuse it.</para>
+
+      <para id="x_2f9">The fact that Mercurial only appends to files makes it
+	easier to provide this transactional guarantee.  The easier it
+	is to do stuff like this, the more confident you should be
+	that it's done correctly.</para>
+
+    </sect2>
+    <sect2>
+      <title>Fast retrieval</title>
+
+      <para id="x_2fa">Mercurial cleverly avoids a pitfall common to
+	all earlier revision control systems: the problem of
+	<emphasis>inefficient retrieval</emphasis>. Most revision
+	control systems store the contents of a revision as an
+	incremental series of modifications against a
+	<quote>snapshot</quote>.  (Some base the snapshot on the
+	oldest revision, others on the newest.)  To reconstruct a
+	specific revision, you must first read the snapshot, and then
+	every one of the revisions between the snapshot and your
+	target revision.  The more history that a file accumulates,
+	the more revisions you must read, hence the longer it takes to
+	reconstruct a particular revision.</para>
+
+      <figure id="fig:concepts:snapshot">
+	<title>Snapshot of a revlog, with incremental deltas</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/snapshot.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_2fc">The innovation that Mercurial applies to this problem is
+	simple but effective.  Once the cumulative amount of delta
+	information stored since the last snapshot exceeds a fixed
+	threshold, it stores a new snapshot (compressed, of course),
+	instead of another delta.  This makes it possible to
+	reconstruct <emphasis>any</emphasis> revision of a file
+	quickly.  This approach works so well that it has since been
+	copied by several other revision control systems.</para>
+
+      <para id="x_2fd"><xref linkend="fig:concepts:snapshot"/> illustrates
+	the idea.  In an entry in a revlog's index file, Mercurial
+	stores the range of entries from the data file that it must
+	read to reconstruct a particular revision.</para>
+
+      <sect3>
+	<title>Aside: the influence of video compression</title>
+
+	<para id="x_2fe">If you're familiar with video compression or
+	  have ever watched a TV feed through a digital cable or
+	  satellite service, you may know that most video compression
+	  schemes store each frame of video as a delta against its
+	  predecessor frame.</para>
+
+	<para id="x_2ff">Mercurial borrows this idea to make it
+	  possible to reconstruct a revision from a snapshot and a
+	  small number of deltas.</para>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Identification and strong integrity</title>
+
+      <para id="x_300">Along with delta or snapshot information, a revlog entry
+	contains a cryptographic hash of the data that it represents.
+	This makes it difficult to forge the contents of a revision,
+	and easy to detect accidental corruption.</para>
+
+      <para id="x_301">Hashes provide more than a mere check against corruption;
+	they are used as the identifiers for revisions.  The changeset
+	identification hashes that you see as an end user are from
+	revisions of the changelog.  Although filelogs and the
+	manifest also use hashes, Mercurial only uses these behind the
+	scenes.</para>
+
+      <para id="x_302">Mercurial verifies that hashes are correct when it
+	retrieves file revisions and when it pulls changes from
+	another repository.  If it encounters an integrity problem, it
+	will complain and stop whatever it's doing.</para>
+
+      <para id="x_303">In addition to the effect it has on retrieval efficiency,
+	Mercurial's use of periodic snapshots makes it more robust
+	against partial data corruption.  If a revlog becomes partly
+	corrupted due to a hardware error or system bug, it's often
+	possible to reconstruct some or most revisions from the
+	uncorrupted sections of the revlog, both before and after the
+	corrupted section.  This would not be possible with a
+	delta-only storage model.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Revision history, branching, and merging</title>
+
+    <para id="x_304">Every entry in a Mercurial revlog knows the identity of its
+      immediate ancestor revision, usually referred to as its
+      <emphasis>parent</emphasis>.  In fact, a revision contains room
+      for not one parent, but two.  Mercurial uses a special hash,
+      called the <quote>null ID</quote>, to represent the idea
+      <quote>there is no parent here</quote>.  This hash is simply a
+      string of zeroes.</para>
+
+    <para id="x_305">In <xref linkend="fig:concepts:revlog"/>, you can see
+      an example of the conceptual structure of a revlog.  Filelogs,
+      manifests, and changelogs all have this same structure; they
+      differ only in the kind of data stored in each delta or
+      snapshot.</para>
+
+    <para id="x_306">The first revision in a revlog (at the bottom of the image)
+      has the null ID in both of its parent slots.  For a
+      <quote>normal</quote> revision, its first parent slot contains
+      the ID of its parent revision, and its second contains the null
+      ID, indicating that the revision has only one real parent.  Any
+      two revisions that have the same parent ID are branches.  A
+      revision that represents a merge between branches has two normal
+      revision IDs in its parent slots.</para>
+
+    <figure id="fig:concepts:revlog">
+      <title>The conceptual structure of a revlog</title>
+      <mediaobject>
+	<imageobject><imagedata fileref="figs/revlog.png"/></imageobject>
+	<textobject><phrase>XXX add text</phrase></textobject>
+      </mediaobject>
+    </figure>
+
+  </sect1>
+  <sect1>
+    <title>The working directory</title>
+
+    <para id="x_307">In the working directory, Mercurial stores a snapshot of the
+      files from the repository as of a particular changeset.</para>
+
+    <para id="x_308">The working directory <quote>knows</quote> which changeset
+      it contains.  When you update the working directory to contain a
+      particular changeset, Mercurial looks up the appropriate
+      revision of the manifest to find out which files it was tracking
+      at the time that changeset was committed, and which revision of
+      each file was then current.  It then recreates a copy of each of
+      those files, with the same contents it had when the changeset
+      was committed.</para>
+
+    <para id="x_309">The <emphasis>dirstate</emphasis> is a special
+      structure that contains Mercurial's knowledge of the working
+      directory.  It is maintained as a file named
+      <filename>.hg/dirstate</filename> inside a repository.  The
+      dirstate details which changeset the working directory is
+      updated to, and all of the files that Mercurial is tracking in
+      the working directory. It also lets Mercurial quickly notice
+      changed files, by recording their checkout times and
+      sizes.</para>
+
+    <para id="x_30a">Just as a revision of a revlog has room for two parents, so
+      that it can represent either a normal revision (with one parent)
+      or a merge of two earlier revisions, the dirstate has slots for
+      two parents.  When you use the <command role="hg-cmd">hg
+	update</command> command, the changeset that you update to is
+      stored in the <quote>first parent</quote> slot, and the null ID
+      in the second. When you <command role="hg-cmd">hg
+	merge</command> with another changeset, the first parent
+      remains unchanged, and the second parent is filled in with the
+      changeset you're merging with.  The <command role="hg-cmd">hg
+	parents</command> command tells you what the parents of the
+      dirstate are.</para>
+
+    <sect2>
+      <title>What happens when you commit</title>
+
+      <para id="x_30b">The dirstate stores parent information for more than just
+	book-keeping purposes.  Mercurial uses the parents of the
+	dirstate as <emphasis>the parents of a new
+	  changeset</emphasis> when you perform a commit.</para>
+
+      <figure id="fig:concepts:wdir">
+	<title>The working directory can have two parents</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/wdir.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_30d"><xref linkend="fig:concepts:wdir"/> shows the
+	normal state of the working directory, where it has a single
+	changeset as parent.  That changeset is the
+	<emphasis>tip</emphasis>, the newest changeset in the
+	repository that has no children.</para>
+
+      <figure id="fig:concepts:wdir-after-commit">
+	<title>The working directory gains new parents after a
+	  commit</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/wdir-after-commit.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_30f">It's useful to think of the working directory as
+	<quote>the changeset I'm about to commit</quote>.  Any files
+	that you tell Mercurial that you've added, removed, renamed,
+	or copied will be reflected in that changeset, as will
+	modifications to any files that Mercurial is already tracking;
+	the new changeset will have the parents of the working
+	directory as its parents.</para>
+
+      <para id="x_310">After a commit, Mercurial will update the
+	parents of the working directory, so that the first parent is
+	the ID of the new changeset, and the second is the null ID.
+	This is shown in <xref
+	  linkend="fig:concepts:wdir-after-commit"/>. Mercurial
+	doesn't touch any of the files in the working directory when
+	you commit; it just modifies the dirstate to note its new
+	parents.</para>
+
+    </sect2>
+    <sect2>
+      <title>Creating a new head</title>
+
+      <para id="x_311">It's perfectly normal to update the working directory to a
+	changeset other than the current tip.  For example, you might
+	want to know what your project looked like last Tuesday, or
+	you could be looking through changesets to see which one
+	introduced a bug.  In cases like this, the natural thing to do
+	is update the working directory to the changeset you're
+	interested in, and then examine the files in the working
+	directory directly to see their contents as they were when you
+	committed that changeset.  The effect of this is shown in
+	<xref linkend="fig:concepts:wdir-pre-branch"/>.</para>
+
+      <figure id="fig:concepts:wdir-pre-branch">
+	<title>The working directory, updated to an older
+	  changeset</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/wdir-pre-branch.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_313">Having updated the working directory to an
+	older changeset, what happens if you make some changes, and
+	then commit?  Mercurial behaves in the same way as I outlined
+	above.  The parents of the working directory become the
+	parents of the new changeset.  This new changeset has no
+	children, so it becomes the new tip.  And the repository now
+	contains two changesets that have no children; we call these
+	<emphasis>heads</emphasis>.  You can see the structure that
+	this creates in <xref
+	  linkend="fig:concepts:wdir-branch"/>.</para>
+
+      <figure id="fig:concepts:wdir-branch">
+	<title>After a commit made while synced to an older
+	  changeset</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/wdir-branch.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <note>
+	<para id="x_315">If you're new to Mercurial, you should keep
+	  in mind a common <quote>error</quote>, which is to use the
+	  <command role="hg-cmd">hg pull</command> command without any
+	  options.  By default, the <command role="hg-cmd">hg
+	    pull</command> command <emphasis>does not</emphasis>
+	  update the working directory, so you'll bring new changesets
+	  into your repository, but the working directory will stay
+	  synced at the same changeset as before the pull.  If you
+	  make some changes and commit afterwards, you'll thus create
+	  a new head, because your working directory isn't synced to
+	  whatever the current tip is.  To combine the operation of a
+	  pull, followed by an update, run <command>hg pull
+	    -u</command>.</para>
+
+	<para id="x_316">I put the word <quote>error</quote> in quotes
+	  because all that you need to do to rectify the situation
+	  where you created a new head by accident is
+	  <command role="hg-cmd">hg merge</command>, then <command
+	    role="hg-cmd">hg commit</command>.  In other words, this
+	  almost never has negative consequences; it's just something
+	  of a surprise for newcomers.  I'll discuss other ways to
+	  avoid this behavior, and why Mercurial behaves in this
+	  initially surprising way, later on.</para>
+      </note>
+
+    </sect2>
+    <sect2>
+      <title>Merging changes</title>
+
+      <para id="x_317">When you run the <command role="hg-cmd">hg
+	  merge</command> command, Mercurial leaves the first parent
+	of the working directory unchanged, and sets the second parent
+	to the changeset you're merging with, as shown in <xref
+	  linkend="fig:concepts:wdir-merge"/>.</para>
+
+      <figure id="fig:concepts:wdir-merge">
+	<title>Merging two heads</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="figs/wdir-merge.png"/>
+	  </imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_319">Mercurial also has to modify the working directory, to
+	merge the files managed in the two changesets.  Simplified a
+	little, the merging process goes like this, for every file in
+	the manifests of both changesets.</para>
+      <itemizedlist>
+	<listitem><para id="x_31a">If neither changeset has modified a file, do
+	    nothing with that file.</para>
+	</listitem>
+	<listitem><para id="x_31b">If one changeset has modified a file, and the
+	    other hasn't, create the modified copy of the file in the
+	    working directory.</para>
+	</listitem>
+	<listitem><para id="x_31c">If one changeset has removed a file, and the
+	    other hasn't (or has also deleted it), delete the file
+	    from the working directory.</para>
+	</listitem>
+	<listitem><para id="x_31d">If one changeset has removed a file, but the
+	    other has modified the file, ask the user what to do: keep
+	    the modified file, or remove it?</para>
+	</listitem>
+	<listitem><para id="x_31e">If both changesets have modified a file,
+	    invoke an external merge program to choose the new
+	    contents for the merged file.  This may require input from
+	    the user.</para>
+	</listitem>
+	<listitem><para id="x_31f">If one changeset has modified a file, and the
+	    other has renamed or copied the file, make sure that the
+	    changes follow the new name of the file.</para>
+	</listitem></itemizedlist>
+      <para id="x_320">There are more details&emdash;merging has plenty of corner
+	cases&emdash;but these are the most common choices that are
+	involved in a merge.  As you can see, most cases are
+	completely automatic, and indeed most merges finish
+	automatically, without requiring your input to resolve any
+	conflicts.</para>
+
+      <para id="x_321">When you're thinking about what happens when you commit
+	after a merge, once again the working directory is <quote>the
+	  changeset I'm about to commit</quote>.  After the <command
+	  role="hg-cmd">hg merge</command> command completes, the
+	working directory has two parents; these will become the
+	parents of the new changeset.</para>
+
+      <para id="x_322">Mercurial lets you perform multiple merges, but
+	you must commit the results of each individual merge as you
+	go.  This is necessary because Mercurial only tracks two
+	parents for both revisions and the working directory.  While
+	it would be technically feasible to merge multiple changesets
+	at once, Mercurial avoids this for simplicity.  With multi-way
+	merges, the risks of user confusion, nasty conflict
+	resolution, and making a terrible mess of a merge would grow
+	intolerable.</para>
+
+    </sect2>
+
+    <sect2>
+      <title>Merging and renames</title>
+
+      <para id="x_69a">A surprising number of revision control systems pay little
+	or no attention to a file's <emphasis>name</emphasis> over
+	time.  For instance, it used to be common that if a file got
+	renamed on one side of a merge, the changes from the other
+	side would be silently dropped.</para>
+
+      <para id="x_69b">Mercurial records metadata when you tell it to perform a
+	rename or copy. It uses this metadata during a merge to do the
+	right thing in the case of a merge.  For instance, if I rename
+	a file, and you edit it without renaming it, when we merge our
+	work the file will be renamed and have your edits
+	applied.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Other interesting design features</title>
+
+    <para id="x_323">In the sections above, I've tried to highlight some of the
+      most important aspects of Mercurial's design, to illustrate that
+      it pays careful attention to reliability and performance.
+      However, the attention to detail doesn't stop there.  There are
+      a number of other aspects of Mercurial's construction that I
+      personally find interesting.  I'll detail a few of them here,
+      separate from the <quote>big ticket</quote> items above, so that
+      if you're interested, you can gain a better idea of the amount
+      of thinking that goes into a well-designed system.</para>
+
+    <sect2>
+      <title>Clever compression</title>
+
+      <para id="x_324">When appropriate, Mercurial will store both snapshots and
+	deltas in compressed form.  It does this by always
+	<emphasis>trying to</emphasis> compress a snapshot or delta,
+	but only storing the compressed version if it's smaller than
+	the uncompressed version.</para>
+
+      <para id="x_325">This means that Mercurial does <quote>the right
+	  thing</quote> when storing a file whose native form is
+	compressed, such as a <literal>zip</literal> archive or a JPEG
+	image.  When these types of files are compressed a second
+	time, the resulting file is usually bigger than the
+	once-compressed form, and so Mercurial will store the plain
+	<literal>zip</literal> or JPEG.</para>
+
+      <para id="x_326">Deltas between revisions of a compressed file are usually
+	larger than snapshots of the file, and Mercurial again does
+	<quote>the right thing</quote> in these cases.  It finds that
+	such a delta exceeds the threshold at which it should store a
+	complete snapshot of the file, so it stores the snapshot,
+	again saving space compared to a naive delta-only
+	approach.</para>
+
+      <sect3>
+	<title>Network recompression</title>
+
+	<para id="x_327">When storing revisions on disk, Mercurial uses the
+	  <quote>deflate</quote> compression algorithm (the same one
+	  used by the popular <literal>zip</literal> archive format),
+	  which balances good speed with a respectable compression
+	  ratio.  However, when transmitting revision data over a
+	  network connection, Mercurial uncompresses the compressed
+	  revision data.</para>
+
+	<para id="x_328">If the connection is over HTTP, Mercurial recompresses
+	  the entire stream of data using a compression algorithm that
+	  gives a better compression ratio (the Burrows-Wheeler
+	  algorithm from the widely used <literal>bzip2</literal>
+	  compression package).  This combination of algorithm and
+	  compression of the entire stream (instead of a revision at a
+	  time) substantially reduces the number of bytes to be
+	  transferred, yielding better network performance over most
+	  kinds of network.</para>
+
+	<para id="x_329">If the connection is over
+	  <command>ssh</command>, Mercurial
+	  <emphasis>doesn't</emphasis> recompress the stream, because
+	  <command>ssh</command> can already do this itself.  You can
+	  tell Mercurial to always use <command>ssh</command>'s
+	  compression feature by editing the
+	  <filename>.hgrc</filename> file in your home directory as
+	  follows.</para>
+
+	<programlisting>[ui]
+ssh = ssh -C</programlisting>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Read/write ordering and atomicity</title>
+
+      <para id="x_32a">Appending to files isn't the whole story when
+	it comes to guaranteeing that a reader won't see a partial
+	write.  If you recall <xref linkend="fig:concepts:metadata"/>,
+	revisions in the changelog point to revisions in the manifest,
+	and revisions in the manifest point to revisions in filelogs.
+	This hierarchy is deliberate.</para>
+
+      <para id="x_32b">A writer starts a transaction by writing filelog and
+	manifest data, and doesn't write any changelog data until
+	those are finished.  A reader starts by reading changelog
+	data, then manifest data, followed by filelog data.</para>
+
+      <para id="x_32c">Since the writer has always finished writing filelog and
+	manifest data before it writes to the changelog, a reader will
+	never read a pointer to a partially written manifest revision
+	from the changelog, and it will never read a pointer to a
+	partially written filelog revision from the manifest.</para>
+
+    </sect2>
+    <sect2>
+      <title>Concurrent access</title>
+
+      <para id="x_32d">The read/write ordering and atomicity guarantees mean that
+	Mercurial never needs to <emphasis>lock</emphasis> a
+	repository when it's reading data, even if the repository is
+	being written to while the read is occurring. This has a big
+	effect on scalability; you can have an arbitrary number of
+	Mercurial processes safely reading data from a repository
+	all at once, no matter whether it's being written to or
+	not.</para>
+
+      <para id="x_32e">The lockless nature of reading means that if you're
+	sharing a repository on a multi-user system, you don't need to
+	grant other local users permission to
+	<emphasis>write</emphasis> to your repository in order for
+	them to be able to clone it or pull changes from it; they only
+	need <emphasis>read</emphasis> permission.  (This is
+	<emphasis>not</emphasis> a common feature among revision
+	control systems, so don't take it for granted!  Most require
+	readers to be able to lock a repository to access it safely,
+	and this requires write permission on at least one directory,
+	which of course makes for all kinds of nasty and annoying
+	security and administrative problems.)</para>
+
+      <para id="x_32f">Mercurial uses locks to ensure that only one process can
+	write to a repository at a time (the locking mechanism is safe
+	even over filesystems that are notoriously hostile to locking,
+	such as NFS).  If a repository is locked, a writer will wait
+	for a while to retry if the repository becomes unlocked, but
+	if the repository remains locked for too long, the process
+	attempting to write will time out after a while. This means
+	that your daily automated scripts won't get stuck forever and
+	pile up if a system crashes unnoticed, for example.  (Yes, the
+	timeout is configurable, from zero to infinity.)</para>
+
+      <sect3>
+	<title>Safe dirstate access</title>
+
+	<para id="x_330">As with revision data, Mercurial doesn't take a lock to
+	  read the dirstate file; it does acquire a lock to write it.
+	  To avoid the possibility of reading a partially written copy
+	  of the dirstate file, Mercurial writes to a file with a
+	  unique name in the same directory as the dirstate file, then
+	  renames the temporary file atomically to
+	  <filename>dirstate</filename>.  The file named
+	  <filename>dirstate</filename> is thus guaranteed to be
+	  complete, not partially written.</para>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Avoiding seeks</title>
+
+      <para id="x_331">Critical to Mercurial's performance is the avoidance of
+	seeks of the disk head, since any seek is far more expensive
+	than even a comparatively large read operation.</para>
+
+      <para id="x_332">This is why, for example, the dirstate is stored in a
+	single file.  If there were a dirstate file per directory that
+	Mercurial tracked, the disk would seek once per directory.
+	Instead, Mercurial reads the entire single dirstate file in
+	one step.</para>
+
+      <para id="x_333">Mercurial also uses a <quote>copy on write</quote> scheme
+	when cloning a repository on local storage.  Instead of
+	copying every revlog file from the old repository into the new
+	repository, it makes a <quote>hard link</quote>, which is a
+	shorthand way to say <quote>these two names point to the same
+	  file</quote>.  When Mercurial is about to write to one of a
+	revlog's files, it checks to see if the number of names
+	pointing at the file is greater than one.  If it is, more than
+	one repository is using the file, so Mercurial makes a new
+	copy of the file that is private to this repository.</para>
+
+      <para id="x_334">A few revision control developers have pointed out that
+	this idea of making a complete private copy of a file is not
+	very efficient in its use of storage.  While this is true,
+	storage is cheap, and this method gives the highest
+	performance while deferring most book-keeping to the operating
+	system.  An alternative scheme would most likely reduce
+	performance and increase the complexity of the software, but
+	speed and simplicity are key to the <quote>feel</quote> of
+	day-to-day use.</para>
+
+    </sect2>
+    <sect2>
+      <title>Other contents of the dirstate</title>
+
+      <para id="x_335">Because Mercurial doesn't force you to tell it when you're
+	modifying a file, it uses the dirstate to store some extra
+	information so it can determine efficiently whether you have
+	modified a file.  For each file in the working directory, it
+	stores the time that it last modified the file itself, and the
+	size of the file at that time.</para>
+
+      <para id="x_336">When you explicitly <command role="hg-cmd">hg
+	  add</command>, <command role="hg-cmd">hg remove</command>,
+	<command role="hg-cmd">hg rename</command> or <command
+	  role="hg-cmd">hg copy</command> files, Mercurial updates the
+	dirstate so that it knows what to do with those files when you
+	commit.</para>
+
+      <para id="x_337">The dirstate helps Mercurial to efficiently
+	  check the status of files in a repository.</para>
+
+      <itemizedlist>
+	<listitem>
+	  <para id="x_726">When Mercurial checks the state of a file in the
+	    working directory, it first checks a file's modification
+	    time against the time in the dirstate that records when
+	    Mercurial last wrote the file. If the last modified time
+	    is the same as the time when Mercurial wrote the file, the
+	    file must not have been modified, so Mercurial does not
+	    need to check any further.</para>
+	</listitem>
+	<listitem>
+	  <para id="x_727">If the file's size has changed, the file must have
+	    been modified.  If the modification time has changed, but
+	    the size has not, only then does Mercurial need to
+	    actually read the contents of the file to see if it has
+	    changed.</para>
+	</listitem>
+      </itemizedlist>
+
+      <para id="x_728">Storing the modification time and size dramatically
+	reduces the number of read operations that Mercurial needs to
+	perform when we run commands like <command>hg status</command>.
+	This results in large performance improvements.</para>
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- a/en/ch04-daily.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,840 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:daily">
-  <?dbhtml filename="mercurial-in-daily-use.html"?>
-  <title>Mercurial in daily use</title>
-
-  <sect1>
-    <title>Telling Mercurial which files to track</title>
-
-    <para id="x_1a3">Mercurial does not work with files in your repository unless
-      you tell it to manage them.  The <command role="hg-cmd">hg
-	status</command> command will tell you which files Mercurial
-      doesn't know about; it uses a
-      <quote><literal>?</literal></quote> to display such
-      files.</para>
-
-    <para id="x_1a4">To tell Mercurial to track a file, use the <command
-	role="hg-cmd">hg add</command> command.  Once you have added a
-      file, the entry in the output of <command role="hg-cmd">hg
-	status</command> for that file changes from
-      <quote><literal>?</literal></quote> to
-      <quote><literal>A</literal></quote>.</para>
-
-      &interaction.daily.files.add;
-
-    <para id="x_1a5">After you run a <command role="hg-cmd">hg commit</command>,
-      the files that you added before the commit will no longer be
-      listed in the output of <command role="hg-cmd">hg
-	status</command>.  The reason for this is that by default, <command
-	role="hg-cmd">hg status</command> only tells you about
-      <quote>interesting</quote> files&emdash;those that you have (for
-      example) modified, removed, or renamed.  If you have a repository
-      that contains thousands of files, you will rarely want to know
-      about files that Mercurial is tracking, but that have not
-      changed.  (You can still get this information; we'll return to
-      this later.)</para>
-
-    <para id="x_1a6">Once you add a file, Mercurial doesn't do anything with it
-      immediately.  Instead, it will take a snapshot of the file's
-      state the next time you perform a commit.  It will then continue
-      to track the changes you make to the file every time you commit,
-      until you remove the file.</para>
-
-    <sect2>
-      <title>Explicit versus implicit file naming</title>
-
-      <para id="x_1a7">A useful behavior that Mercurial has is that if you pass
-	the name of a directory to a command, every Mercurial command
-	will treat this as <quote>I want to operate on every file in
-	  this directory and its subdirectories</quote>.</para>
-
-      &interaction.daily.files.add-dir;
-
-      <para id="x_1a8">Notice in this example that Mercurial printed
-	the names of the files it added, whereas it didn't do so when
-	we added the file named <filename>myfile.txt</filename> in the
-	earlier example.</para>
-
-      <para id="x_1a9">What's going on is that in the former case, we explicitly
-	named the file to add on the command line.  The assumption
-	that Mercurial makes in such cases is that we know what we
-	are doing, and it doesn't print any output.</para>
-
-      <para id="x_1aa">However, when we <emphasis>imply</emphasis> the names of
-	files by giving the name of a directory, Mercurial takes the
-	extra step of printing the name of each file that it does
-	something with.  This makes it more clear what is happening,
-	and reduces the likelihood of a silent and nasty surprise.
-	This behavior is common to most Mercurial commands.</para>
-    </sect2>
-
-    <sect2>
-      <title>Mercurial tracks files, not directories</title>
-
-      <para id="x_1ab">Mercurial does not track directory information.  Instead,
-	it tracks the path to a file.  Before creating a file, it
-	first creates any missing directory components of the path.
-	After it deletes a file, it then deletes any empty directories
-	that were in the deleted file's path.  This sounds like a
-	trivial distinction, but it has one minor practical
-	consequence: it is not possible to represent a completely
-	empty directory in Mercurial.</para>
-
-      <para id="x_1ac">Empty directories are rarely useful, and there are
-	unintrusive workarounds that you can use to achieve an
-	appropriate effect.  The developers of Mercurial thus felt
-	that the complexity that would be required to manage empty
-	directories was not worth the limited benefit this feature
-	would bring.</para>
-
-      <para id="x_1ad">If you need an empty directory in your repository, there
-	are a few ways to achieve this. One is to create a directory,
-	then <command role="hg-cmd">hg add</command> a
-	<quote>hidden</quote> file to that directory.  On Unix-like
-	systems, any file name that begins with a period
-	(<quote><literal>.</literal></quote>) is treated as hidden by
-	most commands and GUI tools.  This approach is illustrated
-	below.</para>
-
-&interaction.daily.files.hidden;
-
-      <para id="x_1ae">Another way to tackle a need for an empty directory is to
-	simply create one in your automated build scripts before they
-	will need it.</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>How to stop tracking a file</title>
-
-    <para id="x_1af">Once you decide that a file no longer belongs in
-      your repository, use the <command role="hg-cmd">hg
-	remove</command> command. This deletes the file, and tells
-      Mercurial to stop tracking it (which will occur at the next
-      commit).  A removed file is represented in the output of
-      <command role="hg-cmd">hg status</command> with a
-      <quote><literal>R</literal></quote>.</para>
-
-    &interaction.daily.files.remove;
-
-    <para id="x_1b0">After you <command role="hg-cmd">hg remove</command> a file,
-      Mercurial will no longer track changes to that file, even if you
-      recreate a file with the same name in your working directory.
-      If you do recreate a file with the same name and want Mercurial
-      to track the new file, simply <command role="hg-cmd">hg
-	add</command> it. Mercurial will know that the newly added
-      file is not related to the old file of the same name.</para>
-
-    <sect2>
-      <title>Removing a file does not affect its history</title>
-
-      <para id="x_1b1">It is important to understand that removing a file has
-	only two effects.</para>
-      <itemizedlist>
-	<listitem><para id="x_1b2">It removes the current version of the file
-	    from the working directory.</para>
-	</listitem>
-	<listitem><para id="x_1b3">It stops Mercurial from tracking changes to
-	    the file, from the time of the next commit.</para>
-	</listitem></itemizedlist>
-      <para id="x_1b4">Removing a file <emphasis>does not</emphasis> in any way
-	alter the <emphasis>history</emphasis> of the file.</para>
-
-      <para id="x_1b5">If you update the working directory to a
-	changeset that was committed when it was still tracking a file
-	that you later removed, the file will reappear in the working
-	directory, with the contents it had when you committed that
-	changeset.  If you then update the working directory to a
-	later changeset, in which the file had been removed, Mercurial
-	will once again remove the file from the working
-	directory.</para>
-    </sect2>
-
-    <sect2>
-      <title>Missing files</title>
-
-      <para id="x_1b6">Mercurial considers a file that you have deleted, but not
-	used <command role="hg-cmd">hg remove</command> to delete, to
-	be <emphasis>missing</emphasis>.  A missing file is
-	represented with <quote><literal>!</literal></quote> in the
-	output of <command role="hg-cmd">hg status</command>.
-	Mercurial commands will not generally do anything with missing
-	files.</para>
-
-      &interaction.daily.files.missing;
-
-      <para id="x_1b7">If your repository contains a file that <command
-	  role="hg-cmd">hg status</command> reports as missing, and
-	you want the file to stay gone, you can run <command
-	  role="hg-cmd">hg remove <option
-	    role="hg-opt-remove">--after</option></command> at any
-	time later on, to tell Mercurial that you really did mean to
-	remove the file.</para>
-
-      &interaction.daily.files.remove-after;
-
-      <para id="x_1b8">On the other hand, if you deleted the missing file by
-	accident, give <command role="hg-cmd">hg revert</command> the
-	name of the file to recover.  It will reappear, in unmodified
-	form.</para>
-
-      &interaction.daily.files.recover-missing;
-    </sect2>
-
-    <sect2>
-      <title>Aside: why tell Mercurial explicitly to remove a
-	file?</title>
-
-      <para id="x_1b9">You might wonder why Mercurial requires you to explicitly
-	tell it that you are deleting a file.  Early during the
-	development of Mercurial, it let you delete a file however you
-	pleased; Mercurial would notice the absence of the file
-	automatically when you next ran a <command role="hg-cmd">hg
-	  commit</command>, and stop tracking the file.  In practice,
-	this made it too easy to accidentally remove a file without
-	noticing.</para>
-    </sect2>
-
-    <sect2>
-      <title>Useful shorthand&emdash;adding and removing files in one
-	step</title>
-
-      <para id="x_1ba">Mercurial offers a combination command, <command
-	  role="hg-cmd">hg addremove</command>, that adds untracked
-	files and marks missing files as removed.</para>
-
-      &interaction.daily.files.addremove;
-
-      <para id="x_1bb">The <command role="hg-cmd">hg commit</command> command
-	also provides a <option role="hg-opt-commit">-A</option>
-	option that performs this same add-and-remove, immediately
-	followed by a commit.</para>
-
-      &interaction.daily.files.commit-addremove;
-    </sect2>
-  </sect1>
-
-  <sect1 id="chap:daily.copy">
-    <title>Copying files</title>
-
-    <para id="x_1bc">Mercurial provides a <command role="hg-cmd">hg
-	copy</command> command that lets you make a new copy of a
-      file.  When you copy a file using this command, Mercurial makes
-      a record of the fact that the new file is a copy of the original
-      file.  It treats these copied files specially when you merge
-      your work with someone else's.</para>
-
-    <sect2>
-      <title>The results of copying during a merge</title>
-
-      <para id="x_1bd">What happens during a merge is that changes
-	<quote>follow</quote> a copy.  To best illustrate what this
-	means, let's create an example.  We'll start with the usual
-	tiny repository that contains a single file.</para>
-
-      &interaction.daily.copy.init;
-
-      <para id="x_1be">We need to do some work in
-	parallel, so that we'll have something to merge.  So let's
-	clone our repository.</para>
-
-      &interaction.daily.copy.clone;
-
-      <para id="x_1bf">Back in our initial repository, let's use the <command
-	  role="hg-cmd">hg copy</command> command to make a copy of
-	the first file we created.</para>
-
-      &interaction.daily.copy.copy;
-
-      <para id="x_1c0">If we look at the output of the <command role="hg-cmd">hg
-	  status</command> command afterwards, the copied file looks
-	just like a normal added file.</para>
-
-      &interaction.daily.copy.status;
-
-      <para id="x_1c1">But if we pass the <option
-	  role="hg-opt-status">-C</option> option to <command
-	  role="hg-cmd">hg status</command>, it prints another line of
-	output: this is the file that our newly-added file was copied
-	<emphasis>from</emphasis>.</para>
-
-      &interaction.daily.copy.status-copy;
-
-      <para id="x_1c2">Now, back in the repository we cloned, let's make a change
-	in parallel.  We'll add a line of content to the original file
-	that we created.</para>
-
-      &interaction.daily.copy.other;
-
-      <para id="x_1c3">Now we have a modified <filename>file</filename> in this
-	repository.  When we pull the changes from the first
-	repository, and merge the two heads, Mercurial will propagate
-	the changes that we made locally to <filename>file</filename>
-	into its copy, <filename>new-file</filename>.</para>
-
-      &interaction.daily.copy.merge;
-    </sect2>
-
-    <sect2 id="sec:daily:why-copy">
-      <title>Why should changes follow copies?</title>
-
-      <para id="x_1c4">This behavior&emdash;of changes to a file
-	propagating out to copies of the file&emdash;might seem
-	esoteric, but in most cases it's highly desirable.</para>
-
-      <para id="x_1c5">First of all, remember that this propagation
-	<emphasis>only</emphasis> happens when you merge.  So if you
-	<command role="hg-cmd">hg copy</command> a file, and
-	subsequently modify the original file during the normal course
-	of your work, nothing will happen.</para>
-
-      <para id="x_1c6">The second thing to know is that modifications will only
-	propagate across a copy as long as the changeset that you're
-	merging changes from <emphasis>hasn't yet seen</emphasis> 
-	the copy.</para>
-
-      <para id="x_1c7">The reason that Mercurial does this is as follows.  Let's
-	say I make an important bug fix in a source file, and commit
-	my changes. Meanwhile, you've decided to <command
-	  role="hg-cmd">hg copy</command> the file in your repository,
-	without knowing about the bug or having seen the fix, and you
-	have started hacking on your copy of the file.</para>
-
-      <para id="x_1c8">If you pulled and merged my changes, and Mercurial
-	<emphasis>didn't</emphasis> propagate changes across copies,
-	your new source file would now contain the bug, and unless you
-	knew to propagate the bug fix by hand, the bug would
-	<emphasis>remain</emphasis> in your copy of the file.</para>
-
-      <para id="x_1c9">By automatically propagating the change that fixed the bug
-	from the original file to the copy, Mercurial prevents this
-	class of problem. To my knowledge, Mercurial is the
-	<emphasis>only</emphasis> revision control system that
-	propagates changes across copies like this.</para>
-
-      <para id="x_1ca">Once your change history has a record that the copy and
-	subsequent merge occurred, there's usually no further need to
-	propagate changes from the original file to the copied file,
-	and that's why Mercurial only propagates changes across copies
-	at the first merge, and not afterwards.</para>
-    </sect2>
-
-    <sect2>
-      <title>How to make changes <emphasis>not</emphasis> follow a
-	copy</title>
-
-      <para id="x_1cb">If, for some reason, you decide that this business of
-	automatically propagating changes across copies is not for
-	you, simply use your system's normal file copy command (on
-	Unix-like systems, that's <command>cp</command>) to make a
-	copy of a file, then <command role="hg-cmd">hg add</command>
-	the new copy by hand.  Before you do so, though, please do
-	reread <xref linkend="sec:daily:why-copy"/>, and make
-	an informed
-	decision that this behavior is not appropriate to your
-	specific case.</para>
-
-    </sect2>
-    <sect2>
-      <title>Behavior of the <command role="hg-cmd">hg copy</command>
-	command</title>
-
-      <para id="x_1cc">When you use the <command role="hg-cmd">hg copy</command>
-	command, Mercurial makes a copy of each source file as it
-	currently stands in the working directory.  This means that if
-	you make some modifications to a file, then <command
-	  role="hg-cmd">hg copy</command> it without first having
-	committed those changes, the new copy will also contain the
-	modifications you have made up until that point.  (I find this
-	behavior a little counterintuitive, which is why I mention it
-	here.)</para>
-
-      <para id="x_1cd">The <command role="hg-cmd">hg copy</command>
-	command acts similarly to the Unix <command>cp</command>
-	command (you can use the <command role="hg-cmd">hg
-	  cp</command> alias if you prefer).  We must supply two or
-	more arguments, of which the last is treated as the
-	<emphasis>destination</emphasis>, and all others are
-	<emphasis>sources</emphasis>.</para>
-
-      <para id="x_685">If you pass <command role="hg-cmd">hg copy</command> a
-	single file as the source, and the destination does not exist,
-	it creates a new file with that name.</para>
-
-      &interaction.daily.copy.simple;
-      
-      <para id="x_1ce">If the destination is a directory, Mercurial copies its
-	sources into that directory.</para>
-
-      &interaction.daily.copy.dir-dest;
-
-      <para id="x_1cf">Copying a directory is
-	recursive, and preserves the directory structure of the
-	source.</para>
-
-      &interaction.daily.copy.dir-src;
-
-      <para id="x_1d0">If the source and destination are both directories, the
-	source tree is recreated in the destination directory.</para>
-
-	&interaction.daily.copy.dir-src-dest;
-
-      <para id="x_1d1">As with the <command role="hg-cmd">hg remove</command>
-	command, if you copy a file manually and then want Mercurial
-	to know that you've copied the file, simply use the <option
-	  role="hg-opt-copy">--after</option> option to <command
-	  role="hg-cmd">hg copy</command>.</para>
-
-      &interaction.daily.copy.after;
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>Renaming files</title>
-
-    <para id="x_1d2">It's rather more common to need to rename a file than to
-      make a copy of it.  The reason I discussed the <command
-	role="hg-cmd">hg copy</command> command before talking about
-      renaming files is that Mercurial treats a rename in essentially
-      the same way as a copy.  Therefore, knowing what Mercurial does
-      when you copy a file tells you what to expect when you rename a
-      file.</para>
-
-    <para id="x_1d3">When you use the <command role="hg-cmd">hg rename</command>
-      command, Mercurial makes a copy of each source file, then
-      deletes it and marks the file as removed.</para>
-
-      &interaction.daily.rename.rename;
-
-    <para id="x_1d4">The <command role="hg-cmd">hg status</command> command shows
-      the newly copied file as added, and the copied-from file as
-      removed.</para>
-
-    &interaction.daily.rename.status;
-
-    <para id="x_1d5">As with the results of a <command role="hg-cmd">hg
-	copy</command>, we must use the <option
-	role="hg-opt-status">-C</option> option to <command
-	role="hg-cmd">hg status</command> to see that the added file
-      is really being tracked by Mercurial as a copy of the original,
-      now removed, file.</para>
-
-    &interaction.daily.rename.status-copy;
-
-    <para id="x_1d6">As with <command role="hg-cmd">hg remove</command> and
-      <command role="hg-cmd">hg copy</command>, you can tell Mercurial
-      about a rename after the fact using the <option
-	role="hg-opt-rename">--after</option> option.  In most other
-      respects, the behavior of the <command role="hg-cmd">hg
-	rename</command> command, and the options it accepts, are
-      similar to the <command role="hg-cmd">hg copy</command>
-      command.</para>
-
-    <para id="x_686">If you're familiar with the Unix command line, you'll be
-      glad to know that <command role="hg-cmd">hg rename</command>
-      command can be invoked as <command role="hg-cmd">hg
-	mv</command>.</para>
-
-    <sect2>
-      <title>Renaming files and merging changes</title>
-
-      <para id="x_1d7">Since Mercurial's rename is implemented as
-	copy-and-remove, the same propagation of changes happens when
-	you merge after a rename as after a copy.</para>
-
-      <para id="x_1d8">If I modify a file, and you rename it to a new name, and
-	then we merge our respective changes, my modifications to the
-	file under its original name will be propagated into the file
-	under its new name. (This is something you might expect to
-	<quote>simply work,</quote> but not all revision control
-	systems actually do this.)</para>
-
-      <para id="x_1d9">Whereas having changes follow a copy is a feature where
-	you can perhaps nod and say <quote>yes, that might be
-	  useful,</quote> it should be clear that having them follow a
-	rename is definitely important.  Without this facility, it
-	would simply be too easy for changes to become orphaned when
-	files are renamed.</para>
-    </sect2>
-
-    <sect2>
-      <title>Divergent renames and merging</title>
-
-      <para id="x_1da">The case of diverging names occurs when two developers
-	start with a file&emdash;let's call it
-	<filename>foo</filename>&emdash;in their respective
-	repositories.</para>
-
-      &interaction.rename.divergent.clone;
-
-      <para id="x_1db">Anne renames the file to <filename>bar</filename>.</para>
-
-      &interaction.rename.divergent.rename.anne;
-
-      <para id="x_1dc">Meanwhile, Bob renames it to
-	<filename>quux</filename>. (Remember that <command
-	  role="hg-cmd">hg mv</command> is an alias for <command
-	  role="hg-cmd">hg rename</command>.)</para>
-
-	&interaction.rename.divergent.rename.bob;
-
-      <para id="x_1dd">I like to think of this as a conflict because each
-	developer has expressed different intentions about what the
-	file ought to be named.</para>
-
-      <para id="x_1de">What do you think should happen when they merge their
-	work? Mercurial's actual behavior is that it always preserves
-	<emphasis>both</emphasis> names when it merges changesets that
-	contain divergent renames.</para>
-
-      &interaction.rename.divergent.merge;
-
-      <para id="x_1df">Notice that while Mercurial warns about the divergent
-	renames, it leaves it up to you to do something about the
-	divergence after the merge.</para>
-    </sect2>
-
-    <sect2>
-      <title>Convergent renames and merging</title>
-
-      <para id="x_1e0">Another kind of rename conflict occurs when two people
-	choose to rename different <emphasis>source</emphasis> files
-	to the same <emphasis>destination</emphasis>. In this case,
-	Mercurial runs its normal merge machinery, and lets you guide
-	it to a suitable resolution.</para>
-    </sect2>
-
-    <sect2>
-      <title>Other name-related corner cases</title>
-
-      <para id="x_1e1">Mercurial has a longstanding bug in which it fails to
-	handle a merge where one side has a file with a given name,
-	while another has a directory with the same name.  This is
-	documented as <ulink role="hg-bug"
-	  url="http://www.selenic.com/mercurial/bts/issue29">issue
-	  29</ulink>.</para>
-
-      &interaction.issue29.go;
-
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>Recovering from mistakes</title>
-
-    <para id="x_1e2">Mercurial has some useful commands that will help you to
-      recover from some common mistakes.</para>
-
-    <para id="x_1e3">The <command role="hg-cmd">hg revert</command> command lets
-      you undo changes that you have made to your working directory.
-      For example, if you <command role="hg-cmd">hg add</command> a
-      file by accident, just run <command role="hg-cmd">hg
-	revert</command> with the name of the file you added, and
-      while the file won't be touched in any way, it won't be tracked
-      for adding by Mercurial any longer, either.  You can also use
-      <command role="hg-cmd">hg revert</command> to get rid of
-      erroneous changes to a file.</para>
-
-    <para id="x_1e4">It is helpful to remember that the <command
-	role="hg-cmd">hg revert</command> command is useful for
-      changes that you have not yet committed.  Once you've committed
-      a change, if you decide it was a mistake, you can still do
-      something about it, though your options may be more
-      limited.</para>
-
-    <para id="x_1e5">For more information about the <command
-	role="hg-cmd">hg revert</command> command, and details about
-      how to deal with changes you have already committed, see <xref
-	linkend="chap:undo"/>.</para>
-  </sect1>
-
-  <sect1>
-    <title>Dealing with tricky merges</title>
-
-    <para id="x_687">In a complicated or large project, it's not unusual for a
-      merge of two changesets to result in some headaches.  Suppose
-      there's a big source file that's been extensively edited by each
-      side of a merge: this is almost inevitably going to result in
-      conflicts, some of which can take a few tries to sort
-      out.</para>
-
-    <para id="x_688">Let's develop a simple case of this and see how to deal with
-      it.  We'll start off with a repository containing one file, and
-      clone it twice.</para>
-
-    &interaction.ch04-resolve.init;
-
-    <para id="x_689">In one clone, we'll modify the file in one way.</para>
-
-    &interaction.ch04-resolve.left;
-
-    <para id="x_68a">In another, we'll modify the file differently.</para>
-
-    &interaction.ch04-resolve.right;
-
-    <para id="x_68b">Next, we'll pull each set of changes into our original
-      repo.</para>
-
-    &interaction.ch04-resolve.pull;
-
-    <para id="x_68c">We expect our repository to now contain two heads.</para>
-
-    &interaction.ch04-resolve.heads;
-
-    <para id="x_68d">Normally, if we run <command role="hg-cmd">hg
-	merge</command> at this point, it will drop us into a GUI that
-      will let us manually resolve the conflicting edits to
-      <filename>myfile.txt</filename>.  However, to simplify things
-      for presentation here, we'd like the merge to fail immediately
-      instead.  Here's one way we can do so.</para>
-
-    &interaction.ch04-resolve.export;
-
-    <para id="x_68e">We've told Mercurial's merge machinery to run the command
-      <command>false</command> (which, as we desire, fails
-      immediately) if it detects a merge that it can't sort out
-      automatically.</para>
-
-    <para id="x_68f">If we now fire up <command role="hg-cmd">hg
-	merge</command>, it should grind to a halt and report a
-	failure.</para>
-
-    &interaction.ch04-resolve.merge;
-
-    <para id="x_690">Even if we don't notice that the merge failed, Mercurial
-      will prevent us from accidentally committing the result of a
-      failed merge.</para>
-
-    &interaction.ch04-resolve.cifail;
-
-    <para id="x_691">When <command role="hg-cmd">hg commit</command> fails in
-      this case, it suggests that we use the unfamiliar <command
-	role="hg-cmd">hg resolve</command> command.  As usual,
-	<command role="hg-cmd">hg help resolve</command> will print a
-      helpful synopsis.</para>
-
-    <sect2>
-      <title>File resolution states</title>
-
-      <para id="x_692">When a merge occurs, most files will usually remain
-	unmodified.  For each file where Mercurial has to do
-	something, it tracks the state of the file.</para>
-
-      <itemizedlist>
-	<listitem>
-	  <para id="x_693">A <emphasis>resolved</emphasis> file has been
-	    successfully merged, either automatically by Mercurial or
-	    manually with human intervention.</para>
-	</listitem>
-	<listitem>
-	  <para id="x_694">An <emphasis>unresolved</emphasis> file was not merged
-	    successfully, and needs more attention.</para>
-	</listitem>
-      </itemizedlist>
-
-      <para id="x_695">If Mercurial sees <emphasis>any</emphasis> file in the
-	unresolved state after a merge, it considers the merge to have
-	failed.  Fortunately, we do not need to restart the entire
-	merge from scratch.</para>
-
-      <para id="x_696">The <option role="hg-opt-resolve">--list</option> or
-	<option role="hg-opt-resolve">-l</option> option to <command
-	  role="hg-cmd">hg resolve</command> prints out the state of
-	each merged file.</para>
-
-      &interaction.ch04-resolve.list;
-
-      <para id="x_697">In the output from <command role="hg-cmd">hg
-	  resolve</command>, a resolved file is marked with
-	<literal>R</literal>, while an unresolved file is marked with
-	<literal>U</literal>.  If any files are listed with
-	<literal>U</literal>, we know that an attempt to commit the
-	results of the merge will fail.</para>
-    </sect2>
-
-    <sect2>
-      <title>Resolving a file merge</title>
-
-      <para id="x_698">We have several options to move a file from the unresolved
-	into the resolved state.  By far the most common is to rerun
-	<command role="hg-cmd">hg resolve</command>.  If we pass the
-	names of individual files or directories, it will retry the
-	merges of any unresolved files present in those locations. We
-	can also pass the <option role="hg-opt-resolve">--all</option>
-	or <option role="hg-opt-resolve">-a</option> option, which
-	will retry the merges of <emphasis>all</emphasis> unresolved
-	files.</para>
-
-      <para id="x_699">Mercurial also lets us modify the resolution state of a
-	file directly.  We can manually mark a file as resolved using
-	the <option role="hg-opt-resolve">--mark</option> option, or
-	as unresolved using the <option
-	  role="hg-opt-resolve">--unmark</option> option.  This allows
-	us to clean up a particularly messy merge by hand, and to keep
-	track of our progress with each file as we go.</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>More useful diffs</title>
-
-    <para id="x_6c7">The default output of the <command role="hg-cmd">hg
-	diff</command> command is backwards compatible with the
-      regular <command>diff</command> command, but this has some
-      drawbacks.</para>
-
-    <para id="x_6c8">Consider the case where we use <command role="hg-cmd">hg
-	rename</command> to rename a file.</para>
-
-    &interaction.ch04-diff.rename.basic;
-
-    <para id="x_6c9">The output of <command role="hg-cmd">hg diff</command> above
-      obscures the fact that we simply renamed a file.  The <command
-	role="hg-cmd">hg diff</command> command accepts an option,
-      <option>--git</option> or <option>-g</option>, to use a newer
-      diff format that displays such information in a more readable
-      form.</para>
-
-    &interaction.ch04-diff.rename.git;
-
-    <para id="x_6ca">This option also helps with a case that can otherwise be
-      confusing: a file that appears to be modified according to
-      <command role="hg-cmd">hg status</command>, but for which
-      <command role="hg-cmd">hg diff</command> prints nothing. This
-      situation can arise if we change the file's execute
-      permissions.</para>
-
-    &interaction.ch04-diff.chmod;
-
-    <para id="x_6cb">The normal <command>diff</command> command pays no attention
-      to file permissions, which is why <command role="hg-cmd">hg
-	diff</command> prints nothing by default.  If we supply it
-      with the <option>-g</option> option, it tells us what really
-      happened.</para>
-
-    &interaction.ch04-diff.chmod.git;
-  </sect1>
-
-  <sect1>
-    <title>Which files to manage, and which to avoid</title>
-
-    <para id="x_6cc">Revision control systems are generally best at managing text
-      files that are written by humans, such as source code, where the
-      files do not change much from one revision to the next.  Some
-      centralized revision control systems can also deal tolerably
-      well with binary files, such as bitmap images.</para>
-
-    <para id="x_6cd">For instance, a game development team will typically manage
-      both its source code and all of its binary assets (e.g. geometry
-      data, textures, map layouts) in a revision control
-      system.</para>
-
-    <para id="x_6ce">Because it is usually impossible to merge two conflicting
-      modifications to a binary file, centralized systems often
-      provide a file locking mechanism that allow a user to say
-      <quote>I am the only person who can edit this
-	file</quote>.</para>
-
-    <para id="x_6cf">Compared to a centralized system, a distributed revision
-      control system changes some of the factors that guide decisions
-      over which files to manage and how.</para>
-
-    <para id="x_6d0">For instance, a distributed revision control system cannot,
-      by its nature, offer a file locking facility.  There is thus no
-      built-in mechanism to prevent two people from making conflicting
-      changes to a binary file.  If you have a team where several
-      people may be editing binary files frequently, it may not be a
-      good idea to use Mercurial&emdash;or any other distributed
-      revision control system&emdash;to manage those files.</para>
-
-    <para id="x_6d1">When storing modifications to a file, Mercurial usually
-      saves only the differences between the previous and current
-      versions of the file.  For most text files, this is extremely
-      efficient. However, some files (particularly binary files) are
-      laid out in such a way that even a small change to a file's
-      logical content results in many or most of the bytes inside the
-      file changing.  For instance, compressed files are particularly
-      susceptible to this. If the differences between each successive
-      version of a file are always large, Mercurial will not be able
-      to store the file's revision history very efficiently.  This can
-      affect both local storage needs and the amount of time it takes
-      to clone a repository.</para>
-
-    <para id="x_6d2">To get an idea of how this could affect you in practice,
-      suppose you want to use Mercurial to manage an OpenOffice
-      document.  OpenOffice stores documents on disk as compressed zip
-      files. Edit even a single letter of your document in OpenOffice,
-      and almost every byte in the entire file will change when you
-      save it. Now suppose that file is 2MB in size.  Because most of
-      the file changes every time you save, Mercurial will have to
-      store all 2MB of the file every time you commit, even though
-      from your perspective, perhaps only a few words are changing
-      each time.  A single frequently-edited file that is not friendly
-      to Mercurial's storage assumptions can easily have an outsized
-      effect on the size of the repository.</para>
-
-    <para id="x_6d3">Even worse, if both you and someone else edit the OpenOffice
-      document you're working on, there is no useful way to merge your
-      work. In fact, there isn't even a good way to tell what the
-      differences are between your respective changes.</para>
-
-    <para id="x_6d4">There are thus a few clear recommendations about specific
-      kinds of files to be very careful with.</para>
-
-    <itemizedlist>
-      <listitem>
-	<para id="x_6d5">Files that are very large and incompressible, e.g. ISO
-	  CD-ROM images, will by virtue of sheer size make clones over
-	  a network very slow.</para>
-      </listitem>
-      <listitem>
-	<para id="x_6d6">Files that change a lot from one revision to the next
-	  may be expensive to store if you edit them frequently, and
-	  conflicts due to concurrent edits may be difficult to
-	  resolve.</para>
-      </listitem>
-    </itemizedlist>
-  </sect1>
-
-  <sect1>
-    <title>Backups and mirroring</title>
-
-    <para id="x_6d7">Since Mercurial maintains a complete copy of history in each
-      clone, everyone who uses Mercurial to collaborate on a project
-      can potentially act as a source of backups in the event of a
-      catastrophe.  If a central repository becomes unavailable, you
-      can construct a replacement simply by cloning a copy of the
-      repository from one contributor, and pulling any changes they
-      may not have seen from others.</para>
-
-    <para id="x_6d8">It is simple to use Mercurial to perform off-site backups
-      and remote mirrors.  Set up a periodic job (e.g. via the
-      <command>cron</command> command) on a remote server to pull
-      changes from your master repositories every hour.  This will
-      only be tricky in the unlikely case that the number of master
-      repositories you maintain changes frequently, in which case
-      you'll need to do a little scripting to refresh the list of
-      repositories to back up.</para>
-
-    <para id="x_6d9">If you perform traditional backups of your master
-      repositories to tape or disk, and you want to back up a
-      repository named <filename>myrepo</filename>, use <command>hg
-	clone -U myrepo myrepo.bak</command> to create a
-      clone of <filename>myrepo</filename> before you start your
-      backups.  The <option>-U</option> option doesn't check out a
-      working directory after the clone completes, since that would be
-      superfluous and make the backup take longer.</para>
-
-    <para id="x_6da">If you then back up <filename>myrepo.bak</filename> instead
-      of <filename>myrepo</filename>, you will be guaranteed to have a
-      consistent snapshot of your repository that won't be pushed to
-      by an insomniac developer in mid-backup.</para>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- a/en/ch05-collab.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1565 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="cha:collab">
-  <?dbhtml filename="collaborating-with-other-people.html"?>
-  <title>Collaborating with other people</title>
-
-  <para id="x_44a">As a completely decentralised tool, Mercurial doesn't impose
-    any policy on how people ought to work with each other.  However,
-    if you're new to distributed revision control, it helps to have
-    some tools and examples in mind when you're thinking about
-    possible workflow models.</para>
-
-  <sect1>
-    <title>Mercurial's web interface</title>
-
-    <para id="x_44b">Mercurial has a powerful web interface that provides several
-      useful capabilities.</para>
-
-    <para id="x_44c">For interactive use, the web interface lets you browse a
-      single repository or a collection of repositories.  You can view
-      the history of a repository, examine each change (comments and
-      diffs), and view the contents of each directory and file.  You
-      can even get a view of history that gives a graphical view of
-      the relationships between individual changes and merges.</para>
-
-    <para id="x_44d">Also for human consumption, the web interface provides
-      Atom and RSS feeds of the changes in a repository.  This lets you
-      <quote>subscribe</quote> to a repository using your favorite
-      feed reader, and be automatically notified of activity in that
-      repository as soon as it happens.  I find this capability much
-      more convenient than the model of subscribing to a mailing list
-      to which notifications are sent, as it requires no additional
-      configuration on the part of whoever is serving the
-      repository.</para>
-
-    <para id="x_44e">The web interface also lets remote users clone a repository,
-      pull changes from it, and (when the server is configured to
-      permit it) push changes back to it.  Mercurial's HTTP tunneling
-      protocol aggressively compresses data, so that it works
-      efficiently even over low-bandwidth network connections.</para>
-
-    <para id="x_44f">The easiest way to get started with the web interface is to
-      use your web browser to visit an existing repository, such as
-      the master Mercurial repository at <ulink
-	url="http://www.selenic.com/repo/hg">http://www.selenic.com/repo/hg</ulink>.</para>
-
-    <para id="x_450">If you're interested in providing a web interface
-      to your own repositories, there are several good ways to do
-      this.</para>
-
-    <para id="x_69d">The easiest and fastest way to get started in an informal
-      environment is to use the <command role="hg-cmd">hg
-	serve</command> command, which is best suited to short-term
-      <quote>lightweight</quote> serving.  See <xref
-	linkend="sec:collab:serve"/> below for details of how to use
-      this command.</para>
-
-    <para id="x_69e">For longer-lived repositories that you'd like to
-      have permanently available, there are several public hosting
-      services available.  Some are free to open source projects,
-      while others offer paid commercial hosting.  An up-to-date list
-      is available at <ulink
-	url="http://www.selenic.com/mercurial/wiki/index.cgi/MercurialHosting">http://www.selenic.com/mercurial/wiki/index.cgi/MercurialHosting</ulink>.</para>
-
-    <para id="x_6a0">If you would prefer to host your own repositories, Mercurial
-      has built-in support for several popular hosting technologies,
-      most notably CGI (Common Gateway Interface), and WSGI (Web
-      Services Gateway Interface).  See <xref
-	linkend="sec:collab:cgi"/> for details of CGI and WSGI
-      configuration.</para>
-  </sect1>
-
-  <sect1>
-    <title>Collaboration models</title>
-
-    <para id="x_451">With a suitably flexible tool, making decisions about
-      workflow is much more of a social engineering challenge than a
-      technical one. Mercurial imposes few limitations on how you can
-      structure the flow of work in a project, so it's up to you and
-      your group to set up and live with a model that matches your own
-      particular needs.</para>
-
-    <sect2>
-      <title>Factors to keep in mind</title>
-
-      <para id="x_452">The most important aspect of any model that you must keep
-	in mind is how well it matches the needs and capabilities of
-	the people who will be using it.  This might seem
-	self-evident; even so, you still can't afford to forget it for
-	a moment.</para>
-
-      <para id="x_453">I once put together a workflow model that seemed to make
-	perfect sense to me, but that caused a considerable amount of
-	consternation and strife within my development team.  In spite
-	of my attempts to explain why we needed a complex set of
-	branches, and how changes ought to flow between them, a few
-	team members revolted.  Even though they were smart people,
-	they didn't want to pay attention to the constraints we were
-	operating under, or face the consequences of those constraints
-	in the details of the model that I was advocating.</para>
-
-      <para id="x_454">Don't sweep foreseeable social or technical problems under
-	the rug. Whatever scheme you put into effect, you should plan
-	for mistakes and problem scenarios.  Consider adding automated
-	machinery to prevent, or quickly recover from, trouble that
-	you can anticipate.  As an example, if you intend to have a
-	branch with not-for-release changes in it, you'd do well to
-	think early about the possibility that someone might
-	accidentally merge those changes into a release branch.  You
-	could avoid this particular problem by writing a hook that
-	prevents changes from being merged from an inappropriate
-	branch.</para>
-    </sect2>
-
-    <sect2>
-      <title>Informal anarchy</title>
-
-      <para id="x_455">I wouldn't suggest an <quote>anything goes</quote>
-	approach as something sustainable, but it's a model that's
-	easy to grasp, and it works perfectly well in a few unusual
-	situations.</para>
-
-      <para id="x_456">As one example, many projects have a loose-knit group of
-	collaborators who rarely physically meet each other.  Some
-	groups like to overcome the isolation of working at a distance
-	by organizing occasional <quote>sprints</quote>.  In a sprint,
-	a number of people get together in a single location (a
-	company's conference room, a hotel meeting room, that kind of
-	place) and spend several days more or less locked in there,
-	hacking intensely on a handful of projects.</para>
-
-      <para id="x_457">A sprint or a hacking session in a coffee shop are the perfect places to use the
-	<command role="hg-cmd">hg serve</command> command, since
-	<command role="hg-cmd">hg serve</command> does not require any
-	fancy server infrastructure.  You can get started with
-	<command role="hg-cmd">hg serve</command> in moments, by
-	reading <xref linkend="sec:collab:serve"/> below.  Then simply
-	tell the person next to you that you're running a server, send
-	the URL to them in an instant message, and you immediately
-	have a quick-turnaround way to work together.  They can type
-	your URL into their web browser and quickly review your
-	changes; or they can pull a bugfix from you and verify it; or
-	they can clone a branch containing a new feature and try it
-	out.</para>
-
-      <para id="x_458">The charm, and the problem, with doing things
-	in an ad hoc fashion like this is that only people who know
-	about your changes, and where they are, can see them.  Such an
-	informal approach simply doesn't scale beyond a handful
-	people, because each individual needs to know about
-	<emphasis>n</emphasis> different repositories to pull
-	from.</para>
-    </sect2>
-
-    <sect2>
-      <title>A single central repository</title>
-
-      <para id="x_459">For smaller projects migrating from a centralised revision
-	control tool, perhaps the easiest way to get started is to
-	have changes flow through a single shared central repository.
-	This is also the most common <quote>building block</quote> for
-	more ambitious workflow schemes.</para>
-
-      <para id="x_45a">Contributors start by cloning a copy of this repository.
-	They can pull changes from it whenever they need to, and some
-	(perhaps all) developers have permission to push a change back
-	when they're ready for other people to see it.</para>
-
-      <para id="x_45b">Under this model, it can still often make sense for people
-	to pull changes directly from each other, without going
-	through the central repository.  Consider a case in which I
-	have a tentative bug fix, but I am worried that if I were to
-	publish it to the central repository, it might subsequently
-	break everyone else's trees as they pull it.  To reduce the
-	potential for damage, I can ask you to clone my repository
-	into a temporary repository of your own and test it.  This
-	lets us put off publishing the potentially unsafe change until
-	it has had a little testing.</para>
-
-      <para id="x_45c">If a team is hosting its own repository in this
-	kind of scenario, people will usually use the
-	<command>ssh</command> protocol to securely push changes to
-	the central repository, as documented in <xref
-	  linkend="sec:collab:ssh"/>.  It's also usual to publish a
-	read-only copy of the repository over HTTP, as in
-	<xref linkend="sec:collab:cgi"/>. Publishing over HTTP
-	satisfies the needs of people who don't have push access, and
-	those who want to use web browsers to browse the repository's
-	history.</para>
-    </sect2>
-
-    <sect2>
-      <title>A hosted central repository</title>
-
-      <para id="x_6a1">A wonderful thing about public hosting services like
-	<ulink url="http://bitbucket.org/">Bitbucket</ulink> is that
-	not only do they handle the fiddly server configuration
-	details, such as user accounts, authentication, and secure
-	wire protocols, they provide additional infrastructure to make
-	this model work well.</para>
-
-      <para id="x_6a2">For instance, a well-engineered hosting service will let
-	people clone their own copies of a repository with a single
-	click.  This lets people work in separate spaces and share
-	their changes when they're ready.</para>
-
-      <para id="x_6a3">In addition, a good hosting service will let people
-	communicate with each other, for instance to say <quote>there
-	  are changes ready for you to review in this
-	  tree</quote>.</para>
-    </sect2>
-
-    <sect2>
-      <title>Working with multiple branches</title>
-
-      <para id="x_45d">Projects of any significant size naturally tend to make
-	progress on several fronts simultaneously.  In the case of
-	software, it's common for a project to go through periodic
-	official releases.  A release might then go into
-	<quote>maintenance mode</quote> for a while after its first
-	publication; maintenance releases tend to contain only bug
-	fixes, not new features.  In parallel with these maintenance
-	releases, one or more future releases may be under
-	development.  People normally use the word
-	<quote>branch</quote> to refer to one of these many slightly
-	different directions in which development is
-	proceeding.</para>
-
-      <para id="x_45e">Mercurial is particularly well suited to managing a number
-	of simultaneous, but not identical, branches.  Each
-	<quote>development direction</quote> can live in its own
-	central repository, and you can merge changes from one to
-	another as the need arises.  Because repositories are
-	independent of each other, unstable changes in a development
-	branch will never affect a stable branch unless someone
-	explicitly merges those changes into the stable branch.</para>
-
-      <para id="x_45f">Here's an example of how this can work in practice.  Let's
-	say you have one <quote>main branch</quote> on a central
-	server.</para>
-
-      &interaction.branching.init;
-
-      <para id="x_460">People clone it, make changes locally, test them, and push
-	them back.</para>
-
-      <para id="x_461">Once the main branch reaches a release milestone, you can
-	use the <command role="hg-cmd">hg tag</command> command to
-	give a permanent name to the milestone revision.</para>
-
-	&interaction.branching.tag;
-
-      <para id="x_462">Let's say some ongoing
-	development occurs on the main branch.</para>
-
-      &interaction.branching.main;
-
-      <para id="x_463">Using the tag that was recorded at the milestone, people
-	who clone that repository at any time in the future can use
-	<command role="hg-cmd">hg update</command> to get a copy of
-	the working directory exactly as it was when that tagged
-	revision was committed.</para>
-
-      &interaction.branching.update;
-
-      <para id="x_464">In addition, immediately after the main branch is tagged,
-	we can then clone the main branch on the server to a new
-	<quote>stable</quote> branch, also on the server.</para>
-
-      &interaction.branching.clone;
-
-      <para id="x_465">If we need to make a change to the stable
-	branch, we can then clone <emphasis>that</emphasis>
-	repository, make our changes, commit, and push our changes
-	back there.</para>
-
-      &interaction.branching.stable;
-
-      <para id="x_466">Because Mercurial repositories are independent, and
-	Mercurial doesn't move changes around automatically, the
-	stable and main branches are <emphasis>isolated</emphasis>
-	from each other.  The changes that we made on the main branch
-	don't <quote>leak</quote> to the stable branch, and vice
-	versa.</para>
-
-      <para id="x_467">We'll often want all of our bugfixes on the stable
-	branch to show up on the main branch, too.  Rather than
-	rewrite a bugfix on the main branch, we can simply pull and
-	merge changes from the stable to the main branch, and
-	Mercurial will bring those bugfixes in for us.</para>
-
-      &interaction.branching.merge;
-
-      <para id="x_468">The main branch will still contain changes that
-	are not on the stable branch, but it will also contain all of
-	the bugfixes from the stable branch.  The stable branch
-	remains unaffected by these changes, since changes are only
-	flowing from the stable to the main branch, and not the other
-	way.</para>
-    </sect2>
-
-    <sect2>
-      <title>Feature branches</title>
-
-      <para id="x_469">For larger projects, an effective way to manage change is
-	to break up a team into smaller groups.  Each group has a
-	shared branch of its own, cloned from a single
-	<quote>master</quote> branch used by the entire project.
-	People working on an individual branch are typically quite
-	isolated from developments on other branches.</para>
-
-      <figure id="fig:collab:feature-branches">
-	<title>Feature branches</title>
-	<mediaobject>
-	  <imageobject><imagedata width="100%" fileref="figs/feature-branches.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_46b">When a particular feature is deemed to be in suitable
-	shape, someone on that feature team pulls and merges from the
-	master branch into the feature branch, then pushes back up to
-	the master branch.</para>
-    </sect2>
-
-    <sect2>
-      <title>The release train</title>
-
-      <para id="x_46c">Some projects are organized on a <quote>train</quote>
-	basis: a release is scheduled to happen every few months, and
-	whatever features are ready when the <quote>train</quote> is
-	ready to leave are allowed in.</para>
-
-      <para id="x_46d">This model resembles working with feature branches.  The
-	difference is that when a feature branch misses a train,
-	someone on the feature team pulls and merges the changes that
-	went out on that train release into the feature branch, and
-	the team continues its work on top of that release so that
-	their feature can make the next release.</para>
-    </sect2>
-
-    <sect2>
-      <title>The Linux kernel model</title>
-
-      <para id="x_46e">The development of the Linux kernel has a shallow
-	hierarchical structure, surrounded by a cloud of apparent
-	chaos.  Because most Linux developers use
-	<command>git</command>, a distributed revision control tool
-	with capabilities similar to Mercurial, it's useful to
-	describe the way work flows in that environment; if you like
-	the ideas, the approach translates well across tools.</para>
-
-      <para id="x_46f">At the center of the community sits Linus Torvalds, the
-	creator of Linux.  He publishes a single source repository
-	that is considered the <quote>authoritative</quote> current
-	tree by the entire developer community. Anyone can clone
-	Linus's tree, but he is very choosy about whose trees he pulls
-	from.</para>
-
-      <para id="x_470">Linus has a number of <quote>trusted lieutenants</quote>.
-	As a general rule, he pulls whatever changes they publish, in
-	most cases without even reviewing those changes.  Some of
-	those lieutenants are generally agreed to be
-	<quote>maintainers</quote>, responsible for specific
-	subsystems within the kernel.  If a random kernel hacker wants
-	to make a change to a subsystem that they want to end up in
-	Linus's tree, they must find out who the subsystem's
-	maintainer is, and ask that maintainer to take their change.
-	If the maintainer reviews their changes and agrees to take
-	them, they'll pass them along to Linus in due course.</para>
-
-      <para id="x_471">Individual lieutenants have their own approaches to
-	reviewing, accepting, and publishing changes; and for deciding
-	when to feed them to Linus.  In addition, there are several
-	well known branches that people use for different purposes.
-	For example, a few people maintain <quote>stable</quote>
-	repositories of older versions of the kernel, to which they
-	apply critical fixes as needed.  Some maintainers publish
-	multiple trees: one for experimental changes; one for changes
-	that they are about to feed upstream; and so on.  Others just
-	publish a single tree.</para>
-
-      <para id="x_472">This model has two notable features.  The first is that
-	it's <quote>pull only</quote>.  You have to ask, convince, or
-	beg another developer to take a change from you, because there
-	are almost no trees to which more than one person can push,
-	and there's no way to push changes into a tree that someone
-	else controls.</para>
-
-      <para id="x_473">The second is that it's based on reputation and acclaim.
-	If you're an unknown, Linus will probably ignore changes from
-	you without even responding.  But a subsystem maintainer will
-	probably review them, and will likely take them if they pass
-	their criteria for suitability. The more <quote>good</quote>
-	changes you contribute to a maintainer, the more likely they
-	are to trust your judgment and accept your changes.  If you're
-	well-known and maintain a long-lived branch for something
-	Linus hasn't yet accepted, people with similar interests may
-	pull your changes regularly to keep up with your work.</para>
-
-      <para id="x_474">Reputation and acclaim don't necessarily cross subsystem
-	or <quote>people</quote> boundaries.  If you're a respected
-	but specialised storage hacker, and you try to fix a
-	networking bug, that change will receive a level of scrutiny
-	from a network maintainer comparable to a change from a
-	complete stranger.</para>
-
-      <para id="x_475">To people who come from more orderly project backgrounds,
-	the comparatively chaotic Linux kernel development process
-	often seems completely insane.  It's subject to the whims of
-	individuals; people make sweeping changes whenever they deem
-	it appropriate; and the pace of development is astounding.
-	And yet Linux is a highly successful, well-regarded piece of
-	software.</para>
-    </sect2>
-
-    <sect2>
-      <title>Pull-only versus shared-push collaboration</title>
-
-      <para id="x_476">A perpetual source of heat in the open source community is
-	whether a development model in which people only ever pull
-	changes from others is <quote>better than</quote> one in which
-	multiple people can push changes to a shared
-	repository.</para>
-
-      <para id="x_477">Typically, the backers of the shared-push model use tools
-	that actively enforce this approach.  If you're using a
-	centralised revision control tool such as Subversion, there's
-	no way to make a choice over which model you'll use: the tool
-	gives you shared-push, and if you want to do anything else,
-	you'll have to roll your own approach on top (such as applying
-	a patch by hand).</para>
-
-      <para id="x_478">A good distributed revision control tool will
-	support both models.  You and your collaborators can then
-	structure how you work together based on your own needs and
-	preferences, not on what contortions your tools force you
-	into.</para>
-    </sect2>
-    <sect2>
-      <title>Where collaboration meets branch management</title>
-
-      <para id="x_479">Once you and your team set up some shared
-	repositories and start propagating changes back and forth
-	between local and shared repos, you begin to face a related,
-	but slightly different challenge: that of managing the
-	multiple directions in which your team may be moving at once.
-	Even though this subject is intimately related to how your
-	team collaborates, it's dense enough to merit treatment of its
-	own, in <xref linkend="chap:branch"/>.</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>The technical side of sharing</title>
-
-    <para id="x_47a">The remainder of this chapter is devoted to the question of
-      sharing changes with your collaborators.</para>
-  </sect1>
-
-  <sect1 id="sec:collab:serve">
-    <title>Informal sharing with <command role="hg-cmd">hg
-	serve</command></title>
-
-    <para id="x_47b">Mercurial's <command role="hg-cmd">hg serve</command>
-      command is wonderfully suited to small, tight-knit, and
-      fast-paced group environments.  It also provides a great way to
-      get a feel for using Mercurial commands over a network.</para>
-
-    <para id="x_47c">Run <command role="hg-cmd">hg serve</command> inside a
-      repository, and in under a second it will bring up a specialised
-      HTTP server; this will accept connections from any client, and
-      serve up data for that repository until you terminate it.
-      Anyone who knows the URL of the server you just started, and can
-      talk to your computer over the network, can then use a web
-      browser or Mercurial to read data from that repository.  A URL
-      for a <command role="hg-cmd">hg serve</command> instance running
-      on a laptop is likely to look something like
-      <literal>http://my-laptop.local:8000/</literal>.</para>
-
-    <para id="x_47d">The <command role="hg-cmd">hg serve</command> command is
-      <emphasis>not</emphasis> a general-purpose web server. It can do
-      only two things:</para>
-    <itemizedlist>
-      <listitem><para id="x_47e">Allow people to browse the history of the
-	  repository it's serving, from their normal web
-	  browsers.</para>
-      </listitem>
-      <listitem><para id="x_47f">Speak Mercurial's wire protocol, so that people
-	  can <command role="hg-cmd">hg clone</command> or <command
-	    role="hg-cmd">hg pull</command> changes from that
-	  repository.</para>
-      </listitem></itemizedlist>
-    <para id="x_480">In particular, <command role="hg-cmd">hg serve</command>
-      won't allow remote users to <emphasis>modify</emphasis> your
-      repository.  It's intended for read-only use.</para>
-
-    <para id="x_481">If you're getting started with Mercurial, there's nothing to
-      prevent you from using <command role="hg-cmd">hg serve</command>
-      to serve up a repository on your own computer, then use commands
-      like <command role="hg-cmd">hg clone</command>, <command
-	role="hg-cmd">hg incoming</command>, and so on to talk to that
-      server as if the repository was hosted remotely. This can help
-      you to quickly get acquainted with using commands on
-      network-hosted repositories.</para>
-
-    <sect2>
-      <title>A few things to keep in mind</title>
-
-      <para id="x_482">Because it provides unauthenticated read access to all
-	clients, you should only use <command role="hg-cmd">hg
-	  serve</command> in an environment where you either don't
-	care, or have complete control over, who can access your
-	network and pull data from your repository.</para>
-
-      <para id="x_483">The <command role="hg-cmd">hg serve</command> command
-	knows nothing about any firewall software you might have
-	installed on your system or network.  It cannot detect or
-	control your firewall software.  If other people are unable to
-	talk to a running <command role="hg-cmd">hg serve</command>
-	instance, the second thing you should do
-	(<emphasis>after</emphasis> you make sure that they're using
-	the correct URL) is check your firewall configuration.</para>
-
-      <para id="x_484">By default, <command role="hg-cmd">hg serve</command>
-	listens for incoming connections on port 8000.  If another
-	process is already listening on the port you want to use, you
-	can specify a different port to listen on using the <option
-	  role="hg-opt-serve">-p</option> option.</para>
-
-      <para id="x_485">Normally, when <command role="hg-cmd">hg serve</command>
-	starts, it prints no output, which can be a bit unnerving.  If
-	you'd like to confirm that it is indeed running correctly, and
-	find out what URL you should send to your collaborators, start
-	it with the <option role="hg-opt-global">-v</option>
-	option.</para>
-    </sect2>
-  </sect1>
-
-  <sect1 id="sec:collab:ssh">
-    <title>Using the Secure Shell (ssh) protocol</title>
-
-    <para id="x_486">You can pull and push changes securely over a network
-      connection using the Secure Shell (<literal>ssh</literal>)
-      protocol.  To use this successfully, you may have to do a little
-      bit of configuration on the client or server sides.</para>
-
-    <para id="x_487">If you're not familiar with ssh, it's the name of
-      both a command and a network protocol that let you securely
-      communicate with another computer.  To use it with Mercurial,
-      you'll be setting up one or more user accounts on a server so
-      that remote users can log in and execute commands.</para>
-
-    <para id="x_488">(If you <emphasis>are</emphasis> familiar with ssh, you'll
-      probably find some of the material that follows to be elementary
-      in nature.)</para>
-
-    <sect2>
-      <title>How to read and write ssh URLs</title>
-
-      <para id="x_489">An ssh URL tends to look like this:</para>
-      <programlisting>ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting>
-      <orderedlist>
-	<listitem><para id="x_48a">The <quote><literal>ssh://</literal></quote>
-	    part tells Mercurial to use the ssh protocol.</para>
-	</listitem>
-	<listitem><para id="x_48b">The <quote><literal>bos@</literal></quote>
-	    component indicates what username to log into the server
-	    as.  You can leave this out if the remote username is the
-	    same as your local username.</para>
-	</listitem>
-	<listitem><para id="x_48c">The
-	    <quote><literal>hg.serpentine.com</literal></quote> gives
-	    the hostname of the server to log into.</para>
-	</listitem>
-	<listitem><para id="x_48d">The <quote>:22</quote> identifies the port
-	    number to connect to the server on.  The default port is
-	    22, so you only need to specify a colon and port number if
-	    you're <emphasis>not</emphasis> using port 22.</para>
-	</listitem>
-	<listitem><para id="x_48e">The remainder of the URL is the local path to
-	    the repository on the server.</para>
-	</listitem></orderedlist>
-
-      <para id="x_48f">There's plenty of scope for confusion with the path
-	component of ssh URLs, as there is no standard way for tools
-	to interpret it.  Some programs behave differently than others
-	when dealing with these paths. This isn't an ideal situation,
-	but it's unlikely to change.  Please read the following
-	paragraphs carefully.</para>
-
-      <para id="x_490">Mercurial treats the path to a repository on the server as
-	relative to the remote user's home directory.  For example, if
-	user <literal>foo</literal> on the server has a home directory
-	of <filename class="directory">/home/foo</filename>, then an
-	ssh URL that contains a path component of <filename
-	  class="directory">bar</filename> <emphasis>really</emphasis>
-	refers to the directory <filename
-	  class="directory">/home/foo/bar</filename>.</para>
-
-      <para id="x_491">If you want to specify a path relative to another user's
-	home directory, you can use a path that starts with a tilde
-	character followed by the user's name (let's call them
-	<literal>otheruser</literal>), like this.</para>
-      <programlisting>ssh://server/~otheruser/hg/repo</programlisting>
-
-      <para id="x_492">And if you really want to specify an
-	<emphasis>absolute</emphasis> path on the server, begin the
-	path component with two slashes, as in this example.</para>
-      <programlisting>ssh://server//absolute/path</programlisting>
-    </sect2>
-
-    <sect2>
-      <title>Finding an ssh client for your system</title>
-
-      <para id="x_493">Almost every Unix-like system comes with OpenSSH
-	preinstalled.  If you're using such a system, run
-	<literal>which ssh</literal> to find out if the
-	<command>ssh</command> command is installed (it's usually in
-	<filename class="directory">/usr/bin</filename>).  In the
-	unlikely event that it isn't present, take a look at your
-	system documentation to figure out how to install it.</para>
-
-      <para id="x_494">On Windows, the TortoiseHg package is bundled
-	with a version of Simon Tatham's excellent
-	<command>plink</command> command, and you should not need to
-	do any further configuration.</para>
-    </sect2>
-
-    <sect2>
-      <title>Generating a key pair</title>
-
-      <para id="x_499">To avoid the need to repetitively type a
-	password every time you need to use your ssh client, I
-	recommend generating a key pair.</para>
-
-      <tip>
-	<title>Key pairs are not mandatory</title>
-
-	<para id="x_6a4">Mercurial knows nothing about ssh authentication or key
-	  pairs.  You can, if you like, safely ignore this section and
-	  the one that follows until you grow tired of repeatedly
-	  typing ssh passwords.</para>
-      </tip>
-
-      <itemizedlist>
-	<listitem>
-	  <para id="x_6a5">On a Unix-like system, the
-	    <command>ssh-keygen</command> command will do the
-	    trick.</para>
-	  <para id="x_6a6">On Windows, if you're using TortoiseHg, you may need
-	    to download a command named <command>puttygen</command>
-	    from <ulink
-	      url="http://www.chiark.greenend.org.uk/~sgtatham/putty">the 
-	      PuTTY web site</ulink> to generate a key pair.  See
-	    <ulink
-	      url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter8.html#pubkey-puttygen">the 
-	      <command>puttygen</command> documentation</ulink> for
-	    details of how use the command.</para>
-	</listitem>
-      </itemizedlist>
-
-      <para id="x_49a">When you generate a key pair, it's usually
-	<emphasis>highly</emphasis> advisable to protect it with a
-	passphrase.  (The only time that you might not want to do this
-	is when you're using the ssh protocol for automated tasks on a
-	secure network.)</para>
-
-      <para id="x_49b">Simply generating a key pair isn't enough, however.
-	You'll need to add the public key to the set of authorised
-	keys for whatever user you're logging in remotely as.  For
-	servers using OpenSSH (the vast majority), this will mean
-	adding the public key to a list in a file called <filename
-	  role="special">authorized_keys</filename> in their <filename
-	  role="special" class="directory">.ssh</filename>
-	directory.</para>
-
-      <para id="x_49c">On a Unix-like system, your public key will have a
-	<filename>.pub</filename> extension.  If you're using
-	<command>puttygen</command> on Windows, you can save the
-	public key to a file of your choosing, or paste it from the
-	window it's displayed in straight into the <filename
-	  role="special">authorized_keys</filename> file.</para>
-    </sect2>
-    <sect2>
-      <title>Using an authentication agent</title>
-
-      <para id="x_49d">An authentication agent is a daemon that stores
-	passphrases in memory (so it will forget passphrases if you
-	log out and log back in again). An ssh client will notice if
-	it's running, and query it for a passphrase.  If there's no
-	authentication agent running, or the agent doesn't store the
-	necessary passphrase, you'll have to type your passphrase
-	every time Mercurial tries to communicate with a server on
-	your behalf (e.g. whenever you pull or push changes).</para>
-
-      <para id="x_49e">The downside of storing passphrases in an agent is that
-	it's possible for a well-prepared attacker to recover the
-	plain text of your passphrases, in some cases even if your
-	system has been power-cycled. You should make your own
-	judgment as to whether this is an acceptable risk.  It
-	certainly saves a lot of repeated typing.</para>
-
-      <itemizedlist>
-	<listitem>
-	  <para id="x_49f">On Unix-like systems, the agent is called
-	    <command>ssh-agent</command>, and it's often run
-	    automatically for you when you log in.  You'll need to use
-	    the <command>ssh-add</command> command to add passphrases
-	    to the agent's store.</para>
-	</listitem>
-	<listitem>
-	  <para id="x_6a7">On Windows, if you're using TortoiseHg, the
-	    <command>pageant</command> command acts as the agent.  As
-	    with <command>puttygen</command>, you'll need to <ulink
-	      url="http://www.chiark.greenend.org.uk/%7Esgtatham/putty/download.html">download 
-	      <command>pageant</command></ulink> from the PuTTY web
-	    site and read <ulink
-	      url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter9.html#pageant">its 
-	      documentation</ulink>.  The <command>pageant</command>
-	    command adds an icon to your system tray that will let you
-	    manage stored passphrases.</para>
-	</listitem>
-      </itemizedlist>
-    </sect2>
-
-    <sect2>
-      <title>Configuring the server side properly</title>
-
-      <para id="x_4a0">Because ssh can be fiddly to set up if you're new to it,
-	a variety of things can go wrong.  Add Mercurial
-	on top, and there's plenty more scope for head-scratching.
-	Most of these potential problems occur on the server side, not
-	the client side.  The good news is that once you've gotten a
-	configuration working, it will usually continue to work
-	indefinitely.</para>
-
-      <para id="x_4a1">Before you try using Mercurial to talk to an ssh server,
-	it's best to make sure that you can use the normal
-	<command>ssh</command> or <command>putty</command> command to
-	talk to the server first.  If you run into problems with using
-	these commands directly, Mercurial surely won't work.  Worse,
-	it will obscure the underlying problem.  Any time you want to
-	debug ssh-related Mercurial problems, you should drop back to
-	making sure that plain ssh client commands work first,
-	<emphasis>before</emphasis> you worry about whether there's a
-	problem with Mercurial.</para>
-
-      <para id="x_4a2">The first thing to be sure of on the server side is that
-	you can actually log in from another machine at all.  If you
-	can't use <command>ssh</command> or <command>putty</command>
-	to log in, the error message you get may give you a few hints
-	as to what's wrong.  The most common problems are as
-	follows.</para>
-      <itemizedlist>
-	<listitem><para id="x_4a3">If you get a <quote>connection refused</quote>
-	    error, either there isn't an SSH daemon running on the
-	    server at all, or it's inaccessible due to firewall
-	    configuration.</para>
-	</listitem>
-	<listitem><para id="x_4a4">If you get a <quote>no route to host</quote>
-	    error, you either have an incorrect address for the server
-	    or a seriously locked down firewall that won't admit its
-	    existence at all.</para>
-	</listitem>
-	<listitem><para id="x_4a5">If you get a <quote>permission denied</quote>
-	    error, you may have mistyped the username on the server,
-	    or you could have mistyped your key's passphrase or the
-	    remote user's password.</para>
-	</listitem></itemizedlist>
-      <para id="x_4a6">In summary, if you're having trouble talking to the
-	server's ssh daemon, first make sure that one is running at
-	all.  On many systems it will be installed, but disabled, by
-	default.  Once you're done with this step, you should then
-	check that the server's firewall is configured to allow
-	incoming connections on the port the ssh daemon is listening
-	on (usually 22).  Don't worry about more exotic possibilities
-	for misconfiguration until you've checked these two
-	first.</para>
-
-      <para id="x_4a7">If you're using an authentication agent on the client side
-	to store passphrases for your keys, you ought to be able to
-	log into the server without being prompted for a passphrase or
-	a password.  If you're prompted for a passphrase, there are a
-	few possible culprits.</para>
-      <itemizedlist>
-	<listitem><para id="x_4a8">You might have forgotten to use
-	    <command>ssh-add</command> or <command>pageant</command>
-	    to store the passphrase.</para>
-	</listitem>
-	<listitem><para id="x_4a9">You might have stored the passphrase for the
-	    wrong key.</para>
-	</listitem></itemizedlist>
-      <para id="x_4aa">If you're being prompted for the remote user's password,
-	there are another few possible problems to check.</para>
-      <itemizedlist>
-	<listitem><para id="x_4ab">Either the user's home directory or their
-	    <filename role="special" class="directory">.ssh</filename>
-	    directory might have excessively liberal permissions.  As
-	    a result, the ssh daemon will not trust or read their
-	    <filename role="special">authorized_keys</filename> file.
-	    For example, a group-writable home or <filename
-	      role="special" class="directory">.ssh</filename>
-	    directory will often cause this symptom.</para>
-	</listitem>
-	<listitem><para id="x_4ac">The user's <filename
-	      role="special">authorized_keys</filename> file may have
-	    a problem. If anyone other than the user owns or can write
-	    to that file, the ssh daemon will not trust or read
-	    it.</para>
-	</listitem></itemizedlist>
-
-      <para id="x_4ad">In the ideal world, you should be able to run the
-	following command successfully, and it should print exactly
-	one line of output, the current date and time.</para>
-      <programlisting>ssh myserver date</programlisting>
-
-      <para id="x_4ae">If, on your server, you have login scripts that print
-	banners or other junk even when running non-interactive
-	commands like this, you should fix them before you continue,
-	so that they only print output if they're run interactively.
-	Otherwise these banners will at least clutter up Mercurial's
-	output.  Worse, they could potentially cause problems with
-	running Mercurial commands remotely.  Mercurial tries to
-	detect and ignore banners in non-interactive
-	<command>ssh</command> sessions, but it is not foolproof.  (If
-	you're editing your login scripts on your server, the usual
-	way to see if a login script is running in an interactive
-	shell is to check the return code from the command
-	<literal>tty -s</literal>.)</para>
-
-      <para id="x_4af">Once you've verified that plain old ssh is working with
-	your server, the next step is to ensure that Mercurial runs on
-	the server.  The following command should run
-	successfully:</para>
-
-      <programlisting>ssh myserver hg version</programlisting>
-
-      <para id="x_4b0">If you see an error message instead of normal <command
-	  role="hg-cmd">hg version</command> output, this is usually
-	because you haven't installed Mercurial to <filename
-	  class="directory">/usr/bin</filename>.  Don't worry if this
-	is the case; you don't need to do that.  But you should check
-	for a few possible problems.</para>
-      <itemizedlist>
-	<listitem><para id="x_4b1">Is Mercurial really installed on the server at
-	    all?  I know this sounds trivial, but it's worth
-	    checking!</para>
-	</listitem>
-	<listitem><para id="x_4b2">Maybe your shell's search path (usually set
-	    via the <envar>PATH</envar> environment variable) is
-	    simply misconfigured.</para>
-	</listitem>
-	<listitem><para id="x_4b3">Perhaps your <envar>PATH</envar> environment
-	    variable is only being set to point to the location of the
-	    <command>hg</command> executable if the login session is
-	    interactive.  This can happen if you're setting the path
-	    in the wrong shell login script.  See your shell's
-	    documentation for details.</para>
-	</listitem>
-	<listitem><para id="x_4b4">The <envar>PYTHONPATH</envar> environment
-	    variable may need to contain the path to the Mercurial
-	    Python modules.  It might not be set at all; it could be
-	    incorrect; or it may be set only if the login is
-	    interactive.</para>
-	</listitem></itemizedlist>
-
-      <para id="x_4b5">If you can run <command role="hg-cmd">hg version</command>
-	over an ssh connection, well done! You've got the server and
-	client sorted out.  You should now be able to use Mercurial to
-	access repositories hosted by that username on that server.
-	If you run into problems with Mercurial and ssh at this point,
-	try using the <option role="hg-opt-global">--debug</option>
-	option to get a clearer picture of what's going on.</para>
-    </sect2>
-    <sect2>
-      <title>Using compression with ssh</title>
-
-      <para id="x_4b6">Mercurial does not compress data when it uses the ssh
-	protocol, because the ssh protocol can transparently compress
-	data.  However, the default behavior of ssh clients is
-	<emphasis>not</emphasis> to request compression.</para>
-
-      <para id="x_4b7">Over any network other than a fast LAN (even a wireless
-	network), using compression is likely to significantly speed
-	up Mercurial's network operations.  For example, over a WAN,
-	someone measured compression as reducing the amount of time
-	required to clone a particularly large repository from 51
-	minutes to 17 minutes.</para>
-
-      <para id="x_4b8">Both <command>ssh</command> and <command>plink</command>
-	accept a <option role="cmd-opt-ssh">-C</option> option which
-	turns on compression.  You can easily edit your <filename
-	  role="special">~/.hgrc</filename> to enable compression for
-	all of Mercurial's uses of the ssh protocol.  Here is how to
-	do so for regular <command>ssh</command> on Unix-like systems,
-	for example.</para>
-      <programlisting>[ui]
-ssh = ssh -C</programlisting>
-
-      <para id="x_4b9">If you use <command>ssh</command> on a
-	Unix-like system, you can configure it to always use
-	compression when talking to your server.  To do this, edit
-	your <filename role="special">.ssh/config</filename> file
-	(which may not yet exist), as follows.</para>
-
-      <programlisting>Host hg
-  Compression yes
-  HostName hg.example.com</programlisting>
-
-      <para id="x_4ba">This defines a hostname alias,
-	<literal>hg</literal>.  When you use that hostname on the
-	<command>ssh</command> command line or in a Mercurial
-	<literal>ssh</literal>-protocol URL, it will cause
-	<command>ssh</command> to connect to
-	<literal>hg.example.com</literal> and use compression.  This
-	gives you both a shorter name to type and compression, each of
-	which is a good thing in its own right.</para>
-    </sect2>
-  </sect1>
-
-  <sect1 id="sec:collab:cgi">
-    <title>Serving over HTTP using CGI</title>
-
-    <para id="x_6a8">The simplest way to host one or more repositories in a
-      permanent way is to use a web server and Mercurial's CGI
-      support.</para>
-
-    <para id="x_4bb">Depending on how ambitious you are, configuring Mercurial's
-      CGI interface can take anything from a few moments to several
-      hours.</para>
-
-    <para id="x_4bc">We'll begin with the simplest of examples, and work our way
-      towards a more complex configuration.  Even for the most basic
-      case, you're almost certainly going to need to read and modify
-      your web server's configuration.</para>
-
-    <note>
-      <title>High pain tolerance required</title>
-
-      <para id="x_4bd">Configuring a web server is a complex, fiddly,
-	and highly system-dependent activity.  I can't possibly give
-	you instructions that will cover anything like all of the
-	cases you will encounter. Please use your discretion and
-	judgment in following the sections below.  Be prepared to make
-	plenty of mistakes, and to spend a lot of time reading your
-	server's error logs.</para>
-
-      <para id="x_6a9">If you don't have a strong stomach for tweaking
-	configurations over and over, or a compelling need to host
-	your own services, you might want to try one of the public
-	hosting services that I mentioned earlier.</para>
-    </note>
-
-    <sect2>
-      <title>Web server configuration checklist</title>
-
-      <para id="x_4be">Before you continue, do take a few moments to check a few
-	aspects of your system's setup.</para>
-
-      <orderedlist>
-	<listitem><para id="x_4bf">Do you have a web server installed
-	    at all? Mac OS X and some Linux distributions ship with
-	    Apache, but many other systems may not have a web server
-	    installed.</para>
-	</listitem>
-	<listitem><para id="x_4c0">If you have a web server installed, is it
-	    actually running?  On most systems, even if one is
-	    present, it will be disabled by default.</para>
-	</listitem>
-	<listitem><para id="x_4c1">Is your server configured to allow you to run
-	    CGI programs in the directory where you plan to do so?
-	    Most servers default to explicitly disabling the ability
-	    to run CGI programs.</para>
-	</listitem></orderedlist>
-
-      <para id="x_4c2">If you don't have a web server installed, and don't have
-	substantial experience configuring Apache, you should consider
-	using the <literal>lighttpd</literal> web server instead of
-	Apache.  Apache has a well-deserved reputation for baroque and
-	confusing configuration. While <literal>lighttpd</literal> is
-	less capable in some ways than Apache, most of these
-	capabilities are not relevant to serving Mercurial
-	repositories.  And <literal>lighttpd</literal> is undeniably
-	<emphasis>much</emphasis> easier to get started with than
-	Apache.</para>
-    </sect2>
-
-    <sect2>
-      <title>Basic CGI configuration</title>
-
-      <para id="x_4c3">On Unix-like systems, it's common for users to have a
-	subdirectory named something like <filename
-	  class="directory">public_html</filename> in their home
-	directory, from which they can serve up web pages.  A file
-	named <filename>foo</filename> in this directory will be
-	accessible at a URL of the form
-	<literal>http://www.example.com/username/foo</literal>.</para>
-
-      <para id="x_4c4">To get started, find the <filename
-	  role="special">hgweb.cgi</filename> script that should be
-	present in your Mercurial installation.  If you can't quickly
-	find a local copy on your system, simply download one from the
-	master Mercurial repository at <ulink
-	  url="http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi</ulink>.</para>
-
-      <para id="x_4c5">You'll need to copy this script into your <filename
-	  class="directory">public_html</filename> directory, and
-	ensure that it's executable.</para>
-      <programlisting>cp .../hgweb.cgi ~/public_html
-chmod 755 ~/public_html/hgweb.cgi</programlisting>
-      <para id="x_4c6">The <literal>755</literal> argument to
-	<command>chmod</command> is a little more general than just
-	making the script executable: it ensures that the script is
-	executable by anyone, and that <quote>group</quote> and
-	<quote>other</quote> write permissions are
-	<emphasis>not</emphasis> set.  If you were to leave those
-	write permissions enabled, Apache's <literal>suexec</literal>
-	subsystem would likely refuse to execute the script.  In fact,
-	<literal>suexec</literal> also insists that the
-	<emphasis>directory</emphasis> in which the script resides
-	must not be writable by others.</para>
-      <programlisting>chmod 755 ~/public_html</programlisting>
-
-      <sect3 id="sec:collab:wtf">
-	<title>What could <emphasis>possibly</emphasis> go
-	  wrong?</title>
-
-	<para id="x_4c7">Once you've copied the CGI script into place,
-	  go into a web browser, and try to open the URL
-	  <literal>http://myhostname/~myuser/hgweb.cgi</literal>,
-	  <emphasis>but</emphasis> brace yourself for instant failure.
-	  There's a high probability that trying to visit this URL
-	  will fail, and there are many possible reasons for this.  In
-	  fact, you're likely to stumble over almost every one of the
-	  possible errors below, so please read carefully.  The
-	  following are all of the problems I ran into on a system
-	  running Fedora 7, with a fresh installation of Apache, and a
-	  user account that I created specially to perform this
-	  exercise.</para>
-
-	<para id="x_4c8">Your web server may have per-user directories disabled.
-	  If you're using Apache, search your config file for a
-	  <literal>UserDir</literal> directive.  If there's none
-	  present, per-user directories will be disabled.  If one
-	  exists, but its value is <literal>disabled</literal>, then
-	  per-user directories will be disabled.  Otherwise, the
-	  string after <literal>UserDir</literal> gives the name of
-	  the subdirectory that Apache will look in under your home
-	  directory, for example <filename
-	    class="directory">public_html</filename>.</para>
-
-	<para id="x_4c9">Your file access permissions may be too restrictive.
-	  The web server must be able to traverse your home directory
-	  and directories under your <filename
-	    class="directory">public_html</filename> directory, and
-	  read files under the latter too.  Here's a quick recipe to
-	  help you to make your permissions more appropriate.</para>
-	<programlisting>chmod 755 ~
-find ~/public_html -type d -print0 | xargs -0r chmod 755
-find ~/public_html -type f -print0 | xargs -0r chmod 644</programlisting>
-
-	<para id="x_4ca">The other possibility with permissions is that you might
-	  get a completely empty window when you try to load the
-	  script.  In this case, it's likely that your access
-	  permissions are <emphasis>too permissive</emphasis>.  Apache's
-	  <literal>suexec</literal> subsystem won't execute a script
-	  that's group- or world-writable, for example.</para>
-
-	<para id="x_4cb">Your web server may be configured to disallow execution
-	  of CGI programs in your per-user web directory.  Here's
-	  Apache's default per-user configuration from my Fedora
-	  system.</para>
-
-	&ch06-apache-config.lst;
-
-	<para id="x_4cc">If you find a similar-looking
-	  <literal>Directory</literal> group in your Apache
-	  configuration, the directive to look at inside it is
-	  <literal>Options</literal>. Add <literal>ExecCGI</literal>
-	  to the end of this list if it's missing, and restart the web
-	  server.</para>
-
-	<para id="x_4cd">If you find that Apache serves you the text of the CGI
-	  script instead of executing it, you may need to either
-	  uncomment (if already present) or add a directive like
-	  this.</para>
-	<programlisting>AddHandler cgi-script .cgi</programlisting>
-
-	<para id="x_4ce">The next possibility is that you might be served with a
-	  colourful Python backtrace claiming that it can't import a
-	  <literal>mercurial</literal>-related module.  This is
-	  actually progress!  The server is now capable of executing
-	  your CGI script.  This error is only likely to occur if
-	  you're running a private installation of Mercurial, instead
-	  of a system-wide version.  Remember that the web server runs
-	  the CGI program without any of the environment variables
-	  that you take for granted in an interactive session.  If
-	  this error happens to you, edit your copy of <filename
-	    role="special">hgweb.cgi</filename> and follow the
-	  directions inside it to correctly set your
-	  <envar>PYTHONPATH</envar> environment variable.</para>
-
-	<para id="x_4cf">Finally, you are <emphasis>certain</emphasis> to be
-	  served with another colourful Python backtrace: this one
-	  will complain that it can't find <filename
-	    class="directory">/path/to/repository</filename>.  Edit
-	  your <filename role="special">hgweb.cgi</filename> script
-	  and replace the <filename
-	    class="directory">/path/to/repository</filename> string
-	  with the complete path to the repository you want to serve
-	  up.</para>
-
-	<para id="x_4d0">At this point, when you try to reload the page, you
-	  should be presented with a nice HTML view of your
-	  repository's history.  Whew!</para>
-      </sect3>
-
-      <sect3>
-	<title>Configuring lighttpd</title>
-
-	<para id="x_4d1">To be exhaustive in my experiments, I tried configuring
-	  the increasingly popular <literal>lighttpd</literal> web
-	  server to serve the same repository as I described with
-	  Apache above.  I had already overcome all of the problems I
-	  outlined with Apache, many of which are not server-specific.
-	  As a result, I was fairly sure that my file and directory
-	  permissions were good, and that my <filename
-	    role="special">hgweb.cgi</filename> script was properly
-	  edited.</para>
-
-	<para id="x_4d2">Once I had Apache running, getting
-	  <literal>lighttpd</literal> to serve the repository was a
-	  snap (in other words, even if you're trying to use
-	  <literal>lighttpd</literal>, you should read the Apache
-	  section).  I first had to edit the
-	  <literal>mod_access</literal> section of its config file to
-	  enable <literal>mod_cgi</literal> and
-	  <literal>mod_userdir</literal>, both of which were disabled
-	  by default on my system.  I then added a few lines to the
-	  end of the config file, to configure these modules.</para>
-	<programlisting>userdir.path = "public_html"
-cgi.assign = (".cgi" =&gt; "" )</programlisting>
-	<para id="x_4d3">With this done, <literal>lighttpd</literal> ran
-	  immediately for me.  If I had configured
-	  <literal>lighttpd</literal> before Apache, I'd almost
-	  certainly have run into many of the same system-level
-	  configuration problems as I did with Apache.  However, I
-	  found <literal>lighttpd</literal> to be noticeably easier to
-	  configure than Apache, even though I've used Apache for over
-	  a decade, and this was my first exposure to
-	  <literal>lighttpd</literal>.</para>
-      </sect3>
-    </sect2>
-
-    <sect2>
-      <title>Sharing multiple repositories with one CGI script</title>
-
-      <para id="x_4d4">The <filename role="special">hgweb.cgi</filename> script
-	only lets you publish a single repository, which is an
-	annoying restriction.  If you want to publish more than one
-	without wracking yourself with multiple copies of the same
-	script, each with different names, a better choice is to use
-	the <filename role="special">hgwebdir.cgi</filename>
-	script.</para>
-
-      <para id="x_4d5">The procedure to configure <filename
-	  role="special">hgwebdir.cgi</filename> is only a little more
-	involved than for <filename
-	  role="special">hgweb.cgi</filename>.  First, you must obtain
-	a copy of the script.  If you don't have one handy, you can
-	download a copy from the master Mercurial repository at <ulink
-	  url="http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi</ulink>.</para>
-
-      <para id="x_4d6">You'll need to copy this script into your <filename
-	  class="directory">public_html</filename> directory, and
-	ensure that it's executable.</para>
-
-      <programlisting>cp .../hgwebdir.cgi ~/public_html
-chmod 755 ~/public_html ~/public_html/hgwebdir.cgi</programlisting>
-
-      <para id="x_4d7">With basic configuration out of the way, try to
-	visit <literal>http://myhostname/~myuser/hgwebdir.cgi</literal>
-	in your	browser.  It should
-	display an empty list of repositories.  If you get a blank
-	window or error message, try walking through the list of
-	potential problems in <xref
-	  linkend="sec:collab:wtf"/>.</para>
-
-      <para id="x_4d8">The <filename role="special">hgwebdir.cgi</filename>
-	script relies on an external configuration file.  By default,
-	it searches for a file named <filename
-	  role="special">hgweb.config</filename> in the same directory
-	as itself.  You'll need to create this file, and make it
-	world-readable.  The format of the file is similar to a
-	Windows <quote>ini</quote> file, as understood by Python's
-	<literal>ConfigParser</literal>
-	<citation>web:configparser</citation> module.</para>
-
-      <para id="x_4d9">The easiest way to configure <filename
-	  role="special">hgwebdir.cgi</filename> is with a section
-	named <literal>collections</literal>.  This will automatically
-	publish <emphasis>every</emphasis> repository under the
-	directories you name.  The section should look like
-	this:</para>
-      <programlisting>[collections]
-/my/root = /my/root</programlisting>
-      <para id="x_4da">Mercurial interprets this by looking at the directory name
-	on the <emphasis>right</emphasis> hand side of the
-	<quote><literal>=</literal></quote> sign; finding repositories
-	in that directory hierarchy; and using the text on the
-	<emphasis>left</emphasis> to strip off matching text from the
-	names it will actually list in the web interface.  The
-	remaining component of a path after this stripping has
-	occurred is called a <quote>virtual path</quote>.</para>
-
-      <para id="x_4db">Given the example above, if we have a
-	repository whose local path is <filename
-	  class="directory">/my/root/this/repo</filename>, the CGI
-	script will strip the leading <filename
-	  class="directory">/my/root</filename> from the name, and
-	publish the repository with a virtual path of <filename
-	  class="directory">this/repo</filename>.  If the base URL for
-	our CGI script is
-	<literal>http://myhostname/~myuser/hgwebdir.cgi</literal>, the
-	complete URL for that repository will be
-	<literal>http://myhostname/~myuser/hgwebdir.cgi/this/repo</literal>.</para>
-
-      <para id="x_4dc">If we replace <filename
-	  class="directory">/my/root</filename> on the left hand side
-	of this example with <filename
-	  class="directory">/my</filename>, then <filename
-	  role="special">hgwebdir.cgi</filename> will only strip off
-	<filename class="directory">/my</filename> from the repository
-	name, and will give us a virtual path of <filename
-	  class="directory">root/this/repo</filename> instead of
-	<filename class="directory">this/repo</filename>.</para>
-
-      <para id="x_4dd">The <filename role="special">hgwebdir.cgi</filename>
-	script will recursively search each directory listed in the
-	<literal>collections</literal> section of its configuration
-	file, but it will <literal>not</literal> recurse into the
-	repositories it finds.</para>
-
-      <para id="x_4de">The <literal>collections</literal> mechanism makes it easy
-	to publish many repositories in a <quote>fire and
-	  forget</quote> manner.  You only need to set up the CGI
-	script and configuration file one time.  Afterwards, you can
-	publish or unpublish a repository at any time by simply moving
-	it into, or out of, the directory hierarchy in which you've
-	configured <filename role="special">hgwebdir.cgi</filename> to
-	look.</para>
-
-      <sect3>
-	<title>Explicitly specifying which repositories to
-	  publish</title>
-
-	<para id="x_4df">In addition to the <literal>collections</literal>
-	  mechanism, the <filename
-	    role="special">hgwebdir.cgi</filename> script allows you
-	  to publish a specific list of repositories.  To do so,
-	  create a <literal>paths</literal> section, with contents of
-	  the following form.</para>
-	<programlisting>[paths]
-repo1 = /my/path/to/some/repo
-repo2 = /some/path/to/another</programlisting>
-	<para id="x_4e0">In this case, the virtual path (the component that will
-	  appear in a URL) is on the left hand side of each
-	  definition, while the path to the repository is on the
-	  right.  Notice that there does not need to be any
-	  relationship between the virtual path you choose and the
-	  location of a repository in your filesystem.</para>
-
-	<para id="x_4e1">If you wish, you can use both the
-	  <literal>collections</literal> and <literal>paths</literal>
-	  mechanisms simultaneously in a single configuration
-	  file.</para>
-
-	<note>
-	  <title>Beware duplicate virtual paths</title>
-
-	  <para id="x_4e2">  If several repositories have the same
-	    virtual path, <filename
-	      role="special">hgwebdir.cgi</filename> will not report
-	    an error.  Instead, it will behave unpredictably.</para>
-	</note>
-      </sect3>
-    </sect2>
-
-    <sect2>
-      <title>Downloading source archives</title>
-
-      <para id="x_4e3">Mercurial's web interface lets users download an archive
-	of any revision.  This archive will contain a snapshot of the
-	working directory as of that revision, but it will not contain
-	a copy of the repository data.</para>
-
-      <para id="x_4e4">By default, this feature is not enabled.  To enable it,
-	you'll need to add an <envar
-	  role="rc-item-web">allow_archive</envar> item to the
-	<literal role="rc-web">web</literal> section of your <filename
-	  role="special">~/.hgrc</filename>; see below for details.</para>
-    </sect2>
-    <sect2>
-      <title>Web configuration options</title>
-
-      <para id="x_4e5">Mercurial's web interfaces (the <command role="hg-cmd">hg
-	  serve</command> command, and the <filename
-	  role="special">hgweb.cgi</filename> and <filename
-	  role="special">hgwebdir.cgi</filename> scripts) have a
-	number of configuration options that you can set.  These
-	belong in a section named <literal
-	  role="rc-web">web</literal>.</para>
-      <itemizedlist>
-	<listitem><para id="x_4e6"><envar
-	      role="rc-item-web">allow_archive</envar>: Determines
-	    which (if any) archive download mechanisms Mercurial
-	    supports.  If you enable this feature, users of the web
-	    interface will be able to download an archive of whatever
-	    revision of a repository they are viewing. To enable the
-	    archive feature, this item must take the form of a
-	    sequence of words drawn from the list below.</para>
-	  <itemizedlist>
-	    <listitem><para id="x_4e7"><literal>bz2</literal>: A
-		<command>tar</command> archive, compressed using
-		<literal>bzip2</literal> compression.  This has the
-		best compression ratio, but uses the most CPU time on
-		the server.</para>
-	    </listitem>
-	    <listitem><para id="x_4e8"><literal>gz</literal>: A
-		<command>tar</command> archive, compressed using
-		<literal>gzip</literal> compression.</para>
-	    </listitem>
-	    <listitem><para id="x_4e9"><literal>zip</literal>: A
-		<command>zip</command> archive, compressed using LZW
-		compression.  This format has the worst compression
-		ratio, but is widely used in the Windows world.</para>
-	    </listitem>
-	  </itemizedlist>
-	  <para id="x_4ea">  If you provide an empty list, or don't have an
-	    <envar role="rc-item-web">allow_archive</envar> entry at
-	    all, this feature will be disabled.  Here is an example of
-	    how to enable all three supported formats.</para>
-	  <programlisting>[web]
-allow_archive = bz2 gz zip</programlisting>
-	</listitem>
-	<listitem><para id="x_4eb"><envar role="rc-item-web">allowpull</envar>:
-	    Boolean.  Determines whether the web interface allows
-	    remote users to <command role="hg-cmd">hg pull</command>
-	    and <command role="hg-cmd">hg clone</command> this
-	    repository over HTTP.  If set to <literal>no</literal> or
-	    <literal>false</literal>, only the
-	    <quote>human-oriented</quote> portion of the web interface
-	    is available.</para>
-	</listitem>
-	<listitem><para id="x_4ec"><envar role="rc-item-web">contact</envar>:
-	    String.  A free-form (but preferably brief) string
-	    identifying the person or group in charge of the
-	    repository.  This often contains the name and email
-	    address of a person or mailing list.  It often makes sense
-	    to place this entry in a repository's own <filename
-	      role="special">.hg/hgrc</filename> file, but it can make
-	    sense to use in a global <filename
-	      role="special">~/.hgrc</filename> if every repository
-	    has a single maintainer.</para>
-	</listitem>
-	<listitem><para id="x_4ed"><envar role="rc-item-web">maxchanges</envar>:
-	    Integer.  The default maximum number of changesets to
-	    display in a single page of output.</para>
-	</listitem>
-	<listitem><para id="x_4ee"><envar role="rc-item-web">maxfiles</envar>:
-	    Integer.  The default maximum number of modified files to
-	    display in a single page of output.</para>
-	</listitem>
-	<listitem><para id="x_4ef"><envar role="rc-item-web">stripes</envar>:
-	    Integer.  If the web interface displays alternating
-	    <quote>stripes</quote> to make it easier to visually align
-	    rows when you are looking at a table, this number controls
-	    the number of rows in each stripe.</para>
-	</listitem>
-	<listitem><para id="x_4f0"><envar
-	      role="rc-item-web">style</envar>: Controls the template
-	    Mercurial uses to display the web interface.  Mercurial
-	    ships with several web templates.</para>
-	  <itemizedlist>
-	    <listitem>
-	      <para id="x_6aa"><literal>coal</literal> is monochromatic.</para>
-	    </listitem>
-	    <listitem>
-	      <para id="x_6ab"><literal>gitweb</literal> emulates the visual
-		style of git's web interface.</para>
-	    </listitem>
-	    <listitem>
-	      <para id="x_6ac"><literal>monoblue</literal> uses solid blues and
-		greys.</para>
-	    </listitem>
-	    <listitem>
-	      <para id="x_6ad"><literal>paper</literal> is the default.</para>
-	    </listitem>
-	    <listitem>
-	      <para id="x_6ae"><literal>spartan</literal> was the default for a
-		long time.</para>
-	    </listitem>
-	  </itemizedlist>
-	  <para id="x_6af">You can
-	    also specify a custom template of your own; see 
-	    <xref linkend="chap:template"/> for details. Here, you can
-	    see how to enable the <literal>gitweb</literal>
-	    style.</para>
-	  <programlisting>[web]
-style = gitweb</programlisting>
-	</listitem>
-	<listitem><para id="x_4f1"><envar role="rc-item-web">templates</envar>:
-	    Path.  The directory in which to search for template
-	    files.  By default, Mercurial searches in the directory in
-	    which it was installed.</para>
-	</listitem></itemizedlist>
-      <para id="x_4f2">If you are using <filename
-	  role="special">hgwebdir.cgi</filename>, you can place a few
-	configuration items in a <literal role="rc-web">web</literal>
-	section of the <filename
-	  role="special">hgweb.config</filename> file instead of a
-	<filename role="special">~/.hgrc</filename> file, for
-	convenience.  These items are <envar
-	  role="rc-item-web">motd</envar> and <envar
-	  role="rc-item-web">style</envar>.</para>
-
-      <sect3>
-	<title>Options specific to an individual repository</title>
-
-	<para id="x_4f3">A few <literal role="rc-web">web</literal> configuration
-	  items ought to be placed in a repository's local <filename
-	    role="special">.hg/hgrc</filename>, rather than a user's
-	  or global <filename role="special">~/.hgrc</filename>.</para>
-	<itemizedlist>
-	  <listitem><para id="x_4f4"><envar
-		role="rc-item-web">description</envar>: String.  A
-	      free-form (but preferably brief) string that describes
-	      the contents or purpose of the repository.</para>
-	  </listitem>
-	  <listitem><para id="x_4f5"><envar role="rc-item-web">name</envar>:
-	      String.  The name to use for the repository in the web
-	      interface.  This overrides the default name, which is
-	      the last component of the repository's path.</para>
-	  </listitem></itemizedlist>
-      </sect3>
-
-      <sect3>
-	<title>Options specific to the <command role="hg-cmd">hg
-	    serve</command> command</title>
-
-	<para id="x_4f6">Some of the items in the <literal
-	    role="rc-web">web</literal> section of a <filename
-	    role="special">~/.hgrc</filename> file are only for use
-	  with the <command role="hg-cmd">hg serve</command>
-	  command.</para>
-	<itemizedlist>
-	  <listitem><para id="x_4f7"><envar role="rc-item-web">accesslog</envar>:
-	      Path.  The name of a file into which to write an access
-	      log.  By default, the <command role="hg-cmd">hg
-		serve</command> command writes this information to
-	      standard output, not to a file.  Log entries are written
-	      in the standard <quote>combined</quote> file format used
-	      by almost all web servers.</para>
-	  </listitem>
-	  <listitem><para id="x_4f8"><envar role="rc-item-web">address</envar>:
-	      String.  The local address on which the server should
-	      listen for incoming connections.  By default, the server
-	      listens on all addresses.</para>
-	  </listitem>
-	  <listitem><para id="x_4f9"><envar role="rc-item-web">errorlog</envar>:
-	      Path.  The name of a file into which to write an error
-	      log.  By default, the <command role="hg-cmd">hg
-		serve</command> command writes this information to
-	      standard error, not to a file.</para>
-	  </listitem>
-	  <listitem><para id="x_4fa"><envar role="rc-item-web">ipv6</envar>:
-	      Boolean.  Whether to use the IPv6 protocol. By default,
-	      IPv6 is not used.</para>
-	  </listitem>
-	  <listitem><para id="x_4fb"><envar role="rc-item-web">port</envar>:
-	      Integer.  The TCP port number on which the server should
-	      listen.  The default port number used is 8000.</para>
-	  </listitem></itemizedlist>
-      </sect3>
-
-      <sect3>
-	<title>Choosing the right <filename
-	    role="special">~/.hgrc</filename> file to add <literal
-	    role="rc-web">web</literal> items to</title>
-
-	<para id="x_4fc">It is important to remember that a web server like
-	  Apache or <literal>lighttpd</literal> will run under a user
-	  ID that is different to yours. CGI scripts run by your
-	  server, such as <filename
-	    role="special">hgweb.cgi</filename>, will usually also run
-	  under that user ID.</para>
-
-	<para id="x_4fd">If you add <literal role="rc-web">web</literal> items to
-	  your own personal <filename role="special">~/.hgrc</filename> file, CGI scripts won't read that
-	  <filename role="special">~/.hgrc</filename> file.  Those
-	  settings will thus only affect the behavior of the <command
-	    role="hg-cmd">hg serve</command> command when you run it.
-	  To cause CGI scripts to see your settings, either create a
-	  <filename role="special">~/.hgrc</filename> file in the
-	  home directory of the user ID that runs your web server, or
-	  add those settings to a system-wide <filename
-	    role="special">hgrc</filename> file.</para>
-      </sect3>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>System-wide configuration</title>
-
-    <para id="x_6b0">On Unix-like systems shared by multiple users (such as a
-      server to which people publish changes), it often makes sense to
-      set up some global default behaviors, such as what theme to use
-      in web interfaces.</para>
-
-    <para id="x_6b1">If a file named <filename>/etc/mercurial/hgrc</filename>
-      exists, Mercurial will read it at startup time and apply any
-      configuration settings it finds in that file.  It will also look
-      for files ending in a <literal>.rc</literal> extension in a
-      directory named <filename>/etc/mercurial/hgrc.d</filename>, and
-      apply any configuration settings it finds in each of those
-      files.</para>
-
-    <sect2>
-      <title>Making Mercurial more trusting</title>
-
-      <para id="x_6b2">One situation in which a global <filename>hgrc</filename>
-	can be useful is if users are pulling changes owned by other
-	users.  By default, Mercurial will not trust most of the
-	configuration items in a <filename>.hg/hgrc</filename> file
-	inside a repository that is owned by a different user. If we
-	clone or pull changes from such a repository, Mercurial will
-	print a warning stating that it does not trust their
-	<filename>.hg/hgrc</filename>.</para>
-
-      <para id="x_6b3">If everyone in a particular Unix group is on the same team
-	and <emphasis>should</emphasis> trust each other's
-	configuration settings, or we want to trust particular users,
-	we can override Mercurial's skeptical defaults by creating a
-	system-wide <filename>hgrc</filename> file such as the
-	following:</para>
-
-    <programlisting># Save this as e.g. /etc/mercurial/hgrc.d/trust.rc
-[trusted]
-# Trust all entries in any hgrc file owned by the "editors" or
-# "www-data" groups.
-groups = editors, www-data
-
-# Trust entries in hgrc files owned by the following users.
-users = apache, bobo
-</programlisting>
-    </sect2>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch05-daily.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,840 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:daily">
+  <?dbhtml filename="mercurial-in-daily-use.html"?>
+  <title>Mercurial in daily use</title>
+
+  <sect1>
+    <title>Telling Mercurial which files to track</title>
+
+    <para id="x_1a3">Mercurial does not work with files in your repository unless
+      you tell it to manage them.  The <command role="hg-cmd">hg
+	status</command> command will tell you which files Mercurial
+      doesn't know about; it uses a
+      <quote><literal>?</literal></quote> to display such
+      files.</para>
+
+    <para id="x_1a4">To tell Mercurial to track a file, use the <command
+	role="hg-cmd">hg add</command> command.  Once you have added a
+      file, the entry in the output of <command role="hg-cmd">hg
+	status</command> for that file changes from
+      <quote><literal>?</literal></quote> to
+      <quote><literal>A</literal></quote>.</para>
+
+      &interaction.daily.files.add;
+
+    <para id="x_1a5">After you run a <command role="hg-cmd">hg commit</command>,
+      the files that you added before the commit will no longer be
+      listed in the output of <command role="hg-cmd">hg
+	status</command>.  The reason for this is that by default, <command
+	role="hg-cmd">hg status</command> only tells you about
+      <quote>interesting</quote> files&emdash;those that you have (for
+      example) modified, removed, or renamed.  If you have a repository
+      that contains thousands of files, you will rarely want to know
+      about files that Mercurial is tracking, but that have not
+      changed.  (You can still get this information; we'll return to
+      this later.)</para>
+
+    <para id="x_1a6">Once you add a file, Mercurial doesn't do anything with it
+      immediately.  Instead, it will take a snapshot of the file's
+      state the next time you perform a commit.  It will then continue
+      to track the changes you make to the file every time you commit,
+      until you remove the file.</para>
+
+    <sect2>
+      <title>Explicit versus implicit file naming</title>
+
+      <para id="x_1a7">A useful behavior that Mercurial has is that if you pass
+	the name of a directory to a command, every Mercurial command
+	will treat this as <quote>I want to operate on every file in
+	  this directory and its subdirectories</quote>.</para>
+
+      &interaction.daily.files.add-dir;
+
+      <para id="x_1a8">Notice in this example that Mercurial printed
+	the names of the files it added, whereas it didn't do so when
+	we added the file named <filename>myfile.txt</filename> in the
+	earlier example.</para>
+
+      <para id="x_1a9">What's going on is that in the former case, we explicitly
+	named the file to add on the command line.  The assumption
+	that Mercurial makes in such cases is that we know what we
+	are doing, and it doesn't print any output.</para>
+
+      <para id="x_1aa">However, when we <emphasis>imply</emphasis> the names of
+	files by giving the name of a directory, Mercurial takes the
+	extra step of printing the name of each file that it does
+	something with.  This makes it more clear what is happening,
+	and reduces the likelihood of a silent and nasty surprise.
+	This behavior is common to most Mercurial commands.</para>
+    </sect2>
+
+    <sect2>
+      <title>Mercurial tracks files, not directories</title>
+
+      <para id="x_1ab">Mercurial does not track directory information.  Instead,
+	it tracks the path to a file.  Before creating a file, it
+	first creates any missing directory components of the path.
+	After it deletes a file, it then deletes any empty directories
+	that were in the deleted file's path.  This sounds like a
+	trivial distinction, but it has one minor practical
+	consequence: it is not possible to represent a completely
+	empty directory in Mercurial.</para>
+
+      <para id="x_1ac">Empty directories are rarely useful, and there are
+	unintrusive workarounds that you can use to achieve an
+	appropriate effect.  The developers of Mercurial thus felt
+	that the complexity that would be required to manage empty
+	directories was not worth the limited benefit this feature
+	would bring.</para>
+
+      <para id="x_1ad">If you need an empty directory in your repository, there
+	are a few ways to achieve this. One is to create a directory,
+	then <command role="hg-cmd">hg add</command> a
+	<quote>hidden</quote> file to that directory.  On Unix-like
+	systems, any file name that begins with a period
+	(<quote><literal>.</literal></quote>) is treated as hidden by
+	most commands and GUI tools.  This approach is illustrated
+	below.</para>
+
+&interaction.daily.files.hidden;
+
+      <para id="x_1ae">Another way to tackle a need for an empty directory is to
+	simply create one in your automated build scripts before they
+	will need it.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>How to stop tracking a file</title>
+
+    <para id="x_1af">Once you decide that a file no longer belongs in
+      your repository, use the <command role="hg-cmd">hg
+	remove</command> command. This deletes the file, and tells
+      Mercurial to stop tracking it (which will occur at the next
+      commit).  A removed file is represented in the output of
+      <command role="hg-cmd">hg status</command> with a
+      <quote><literal>R</literal></quote>.</para>
+
+    &interaction.daily.files.remove;
+
+    <para id="x_1b0">After you <command role="hg-cmd">hg remove</command> a file,
+      Mercurial will no longer track changes to that file, even if you
+      recreate a file with the same name in your working directory.
+      If you do recreate a file with the same name and want Mercurial
+      to track the new file, simply <command role="hg-cmd">hg
+	add</command> it. Mercurial will know that the newly added
+      file is not related to the old file of the same name.</para>
+
+    <sect2>
+      <title>Removing a file does not affect its history</title>
+
+      <para id="x_1b1">It is important to understand that removing a file has
+	only two effects.</para>
+      <itemizedlist>
+	<listitem><para id="x_1b2">It removes the current version of the file
+	    from the working directory.</para>
+	</listitem>
+	<listitem><para id="x_1b3">It stops Mercurial from tracking changes to
+	    the file, from the time of the next commit.</para>
+	</listitem></itemizedlist>
+      <para id="x_1b4">Removing a file <emphasis>does not</emphasis> in any way
+	alter the <emphasis>history</emphasis> of the file.</para>
+
+      <para id="x_1b5">If you update the working directory to a
+	changeset that was committed when it was still tracking a file
+	that you later removed, the file will reappear in the working
+	directory, with the contents it had when you committed that
+	changeset.  If you then update the working directory to a
+	later changeset, in which the file had been removed, Mercurial
+	will once again remove the file from the working
+	directory.</para>
+    </sect2>
+
+    <sect2>
+      <title>Missing files</title>
+
+      <para id="x_1b6">Mercurial considers a file that you have deleted, but not
+	used <command role="hg-cmd">hg remove</command> to delete, to
+	be <emphasis>missing</emphasis>.  A missing file is
+	represented with <quote><literal>!</literal></quote> in the
+	output of <command role="hg-cmd">hg status</command>.
+	Mercurial commands will not generally do anything with missing
+	files.</para>
+
+      &interaction.daily.files.missing;
+
+      <para id="x_1b7">If your repository contains a file that <command
+	  role="hg-cmd">hg status</command> reports as missing, and
+	you want the file to stay gone, you can run <command
+	  role="hg-cmd">hg remove <option
+	    role="hg-opt-remove">--after</option></command> at any
+	time later on, to tell Mercurial that you really did mean to
+	remove the file.</para>
+
+      &interaction.daily.files.remove-after;
+
+      <para id="x_1b8">On the other hand, if you deleted the missing file by
+	accident, give <command role="hg-cmd">hg revert</command> the
+	name of the file to recover.  It will reappear, in unmodified
+	form.</para>
+
+      &interaction.daily.files.recover-missing;
+    </sect2>
+
+    <sect2>
+      <title>Aside: why tell Mercurial explicitly to remove a
+	file?</title>
+
+      <para id="x_1b9">You might wonder why Mercurial requires you to explicitly
+	tell it that you are deleting a file.  Early during the
+	development of Mercurial, it let you delete a file however you
+	pleased; Mercurial would notice the absence of the file
+	automatically when you next ran a <command role="hg-cmd">hg
+	  commit</command>, and stop tracking the file.  In practice,
+	this made it too easy to accidentally remove a file without
+	noticing.</para>
+    </sect2>
+
+    <sect2>
+      <title>Useful shorthand&emdash;adding and removing files in one
+	step</title>
+
+      <para id="x_1ba">Mercurial offers a combination command, <command
+	  role="hg-cmd">hg addremove</command>, that adds untracked
+	files and marks missing files as removed.</para>
+
+      &interaction.daily.files.addremove;
+
+      <para id="x_1bb">The <command role="hg-cmd">hg commit</command> command
+	also provides a <option role="hg-opt-commit">-A</option>
+	option that performs this same add-and-remove, immediately
+	followed by a commit.</para>
+
+      &interaction.daily.files.commit-addremove;
+    </sect2>
+  </sect1>
+
+  <sect1 id="chap:daily.copy">
+    <title>Copying files</title>
+
+    <para id="x_1bc">Mercurial provides a <command role="hg-cmd">hg
+	copy</command> command that lets you make a new copy of a
+      file.  When you copy a file using this command, Mercurial makes
+      a record of the fact that the new file is a copy of the original
+      file.  It treats these copied files specially when you merge
+      your work with someone else's.</para>
+
+    <sect2>
+      <title>The results of copying during a merge</title>
+
+      <para id="x_1bd">What happens during a merge is that changes
+	<quote>follow</quote> a copy.  To best illustrate what this
+	means, let's create an example.  We'll start with the usual
+	tiny repository that contains a single file.</para>
+
+      &interaction.daily.copy.init;
+
+      <para id="x_1be">We need to do some work in
+	parallel, so that we'll have something to merge.  So let's
+	clone our repository.</para>
+
+      &interaction.daily.copy.clone;
+
+      <para id="x_1bf">Back in our initial repository, let's use the <command
+	  role="hg-cmd">hg copy</command> command to make a copy of
+	the first file we created.</para>
+
+      &interaction.daily.copy.copy;
+
+      <para id="x_1c0">If we look at the output of the <command role="hg-cmd">hg
+	  status</command> command afterwards, the copied file looks
+	just like a normal added file.</para>
+
+      &interaction.daily.copy.status;
+
+      <para id="x_1c1">But if we pass the <option
+	  role="hg-opt-status">-C</option> option to <command
+	  role="hg-cmd">hg status</command>, it prints another line of
+	output: this is the file that our newly-added file was copied
+	<emphasis>from</emphasis>.</para>
+
+      &interaction.daily.copy.status-copy;
+
+      <para id="x_1c2">Now, back in the repository we cloned, let's make a change
+	in parallel.  We'll add a line of content to the original file
+	that we created.</para>
+
+      &interaction.daily.copy.other;
+
+      <para id="x_1c3">Now we have a modified <filename>file</filename> in this
+	repository.  When we pull the changes from the first
+	repository, and merge the two heads, Mercurial will propagate
+	the changes that we made locally to <filename>file</filename>
+	into its copy, <filename>new-file</filename>.</para>
+
+      &interaction.daily.copy.merge;
+    </sect2>
+
+    <sect2 id="sec:daily:why-copy">
+      <title>Why should changes follow copies?</title>
+
+      <para id="x_1c4">This behavior&emdash;of changes to a file
+	propagating out to copies of the file&emdash;might seem
+	esoteric, but in most cases it's highly desirable.</para>
+
+      <para id="x_1c5">First of all, remember that this propagation
+	<emphasis>only</emphasis> happens when you merge.  So if you
+	<command role="hg-cmd">hg copy</command> a file, and
+	subsequently modify the original file during the normal course
+	of your work, nothing will happen.</para>
+
+      <para id="x_1c6">The second thing to know is that modifications will only
+	propagate across a copy as long as the changeset that you're
+	merging changes from <emphasis>hasn't yet seen</emphasis> 
+	the copy.</para>
+
+      <para id="x_1c7">The reason that Mercurial does this is as follows.  Let's
+	say I make an important bug fix in a source file, and commit
+	my changes. Meanwhile, you've decided to <command
+	  role="hg-cmd">hg copy</command> the file in your repository,
+	without knowing about the bug or having seen the fix, and you
+	have started hacking on your copy of the file.</para>
+
+      <para id="x_1c8">If you pulled and merged my changes, and Mercurial
+	<emphasis>didn't</emphasis> propagate changes across copies,
+	your new source file would now contain the bug, and unless you
+	knew to propagate the bug fix by hand, the bug would
+	<emphasis>remain</emphasis> in your copy of the file.</para>
+
+      <para id="x_1c9">By automatically propagating the change that fixed the bug
+	from the original file to the copy, Mercurial prevents this
+	class of problem. To my knowledge, Mercurial is the
+	<emphasis>only</emphasis> revision control system that
+	propagates changes across copies like this.</para>
+
+      <para id="x_1ca">Once your change history has a record that the copy and
+	subsequent merge occurred, there's usually no further need to
+	propagate changes from the original file to the copied file,
+	and that's why Mercurial only propagates changes across copies
+	at the first merge, and not afterwards.</para>
+    </sect2>
+
+    <sect2>
+      <title>How to make changes <emphasis>not</emphasis> follow a
+	copy</title>
+
+      <para id="x_1cb">If, for some reason, you decide that this business of
+	automatically propagating changes across copies is not for
+	you, simply use your system's normal file copy command (on
+	Unix-like systems, that's <command>cp</command>) to make a
+	copy of a file, then <command role="hg-cmd">hg add</command>
+	the new copy by hand.  Before you do so, though, please do
+	reread <xref linkend="sec:daily:why-copy"/>, and make
+	an informed
+	decision that this behavior is not appropriate to your
+	specific case.</para>
+
+    </sect2>
+    <sect2>
+      <title>Behavior of the <command role="hg-cmd">hg copy</command>
+	command</title>
+
+      <para id="x_1cc">When you use the <command role="hg-cmd">hg copy</command>
+	command, Mercurial makes a copy of each source file as it
+	currently stands in the working directory.  This means that if
+	you make some modifications to a file, then <command
+	  role="hg-cmd">hg copy</command> it without first having
+	committed those changes, the new copy will also contain the
+	modifications you have made up until that point.  (I find this
+	behavior a little counterintuitive, which is why I mention it
+	here.)</para>
+
+      <para id="x_1cd">The <command role="hg-cmd">hg copy</command>
+	command acts similarly to the Unix <command>cp</command>
+	command (you can use the <command role="hg-cmd">hg
+	  cp</command> alias if you prefer).  We must supply two or
+	more arguments, of which the last is treated as the
+	<emphasis>destination</emphasis>, and all others are
+	<emphasis>sources</emphasis>.</para>
+
+      <para id="x_685">If you pass <command role="hg-cmd">hg copy</command> a
+	single file as the source, and the destination does not exist,
+	it creates a new file with that name.</para>
+
+      &interaction.daily.copy.simple;
+      
+      <para id="x_1ce">If the destination is a directory, Mercurial copies its
+	sources into that directory.</para>
+
+      &interaction.daily.copy.dir-dest;
+
+      <para id="x_1cf">Copying a directory is
+	recursive, and preserves the directory structure of the
+	source.</para>
+
+      &interaction.daily.copy.dir-src;
+
+      <para id="x_1d0">If the source and destination are both directories, the
+	source tree is recreated in the destination directory.</para>
+
+	&interaction.daily.copy.dir-src-dest;
+
+      <para id="x_1d1">As with the <command role="hg-cmd">hg remove</command>
+	command, if you copy a file manually and then want Mercurial
+	to know that you've copied the file, simply use the <option
+	  role="hg-opt-copy">--after</option> option to <command
+	  role="hg-cmd">hg copy</command>.</para>
+
+      &interaction.daily.copy.after;
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Renaming files</title>
+
+    <para id="x_1d2">It's rather more common to need to rename a file than to
+      make a copy of it.  The reason I discussed the <command
+	role="hg-cmd">hg copy</command> command before talking about
+      renaming files is that Mercurial treats a rename in essentially
+      the same way as a copy.  Therefore, knowing what Mercurial does
+      when you copy a file tells you what to expect when you rename a
+      file.</para>
+
+    <para id="x_1d3">When you use the <command role="hg-cmd">hg rename</command>
+      command, Mercurial makes a copy of each source file, then
+      deletes it and marks the file as removed.</para>
+
+      &interaction.daily.rename.rename;
+
+    <para id="x_1d4">The <command role="hg-cmd">hg status</command> command shows
+      the newly copied file as added, and the copied-from file as
+      removed.</para>
+
+    &interaction.daily.rename.status;
+
+    <para id="x_1d5">As with the results of a <command role="hg-cmd">hg
+	copy</command>, we must use the <option
+	role="hg-opt-status">-C</option> option to <command
+	role="hg-cmd">hg status</command> to see that the added file
+      is really being tracked by Mercurial as a copy of the original,
+      now removed, file.</para>
+
+    &interaction.daily.rename.status-copy;
+
+    <para id="x_1d6">As with <command role="hg-cmd">hg remove</command> and
+      <command role="hg-cmd">hg copy</command>, you can tell Mercurial
+      about a rename after the fact using the <option
+	role="hg-opt-rename">--after</option> option.  In most other
+      respects, the behavior of the <command role="hg-cmd">hg
+	rename</command> command, and the options it accepts, are
+      similar to the <command role="hg-cmd">hg copy</command>
+      command.</para>
+
+    <para id="x_686">If you're familiar with the Unix command line, you'll be
+      glad to know that <command role="hg-cmd">hg rename</command>
+      command can be invoked as <command role="hg-cmd">hg
+	mv</command>.</para>
+
+    <sect2>
+      <title>Renaming files and merging changes</title>
+
+      <para id="x_1d7">Since Mercurial's rename is implemented as
+	copy-and-remove, the same propagation of changes happens when
+	you merge after a rename as after a copy.</para>
+
+      <para id="x_1d8">If I modify a file, and you rename it to a new name, and
+	then we merge our respective changes, my modifications to the
+	file under its original name will be propagated into the file
+	under its new name. (This is something you might expect to
+	<quote>simply work,</quote> but not all revision control
+	systems actually do this.)</para>
+
+      <para id="x_1d9">Whereas having changes follow a copy is a feature where
+	you can perhaps nod and say <quote>yes, that might be
+	  useful,</quote> it should be clear that having them follow a
+	rename is definitely important.  Without this facility, it
+	would simply be too easy for changes to become orphaned when
+	files are renamed.</para>
+    </sect2>
+
+    <sect2>
+      <title>Divergent renames and merging</title>
+
+      <para id="x_1da">The case of diverging names occurs when two developers
+	start with a file&emdash;let's call it
+	<filename>foo</filename>&emdash;in their respective
+	repositories.</para>
+
+      &interaction.rename.divergent.clone;
+
+      <para id="x_1db">Anne renames the file to <filename>bar</filename>.</para>
+
+      &interaction.rename.divergent.rename.anne;
+
+      <para id="x_1dc">Meanwhile, Bob renames it to
+	<filename>quux</filename>. (Remember that <command
+	  role="hg-cmd">hg mv</command> is an alias for <command
+	  role="hg-cmd">hg rename</command>.)</para>
+
+	&interaction.rename.divergent.rename.bob;
+
+      <para id="x_1dd">I like to think of this as a conflict because each
+	developer has expressed different intentions about what the
+	file ought to be named.</para>
+
+      <para id="x_1de">What do you think should happen when they merge their
+	work? Mercurial's actual behavior is that it always preserves
+	<emphasis>both</emphasis> names when it merges changesets that
+	contain divergent renames.</para>
+
+      &interaction.rename.divergent.merge;
+
+      <para id="x_1df">Notice that while Mercurial warns about the divergent
+	renames, it leaves it up to you to do something about the
+	divergence after the merge.</para>
+    </sect2>
+
+    <sect2>
+      <title>Convergent renames and merging</title>
+
+      <para id="x_1e0">Another kind of rename conflict occurs when two people
+	choose to rename different <emphasis>source</emphasis> files
+	to the same <emphasis>destination</emphasis>. In this case,
+	Mercurial runs its normal merge machinery, and lets you guide
+	it to a suitable resolution.</para>
+    </sect2>
+
+    <sect2>
+      <title>Other name-related corner cases</title>
+
+      <para id="x_1e1">Mercurial has a longstanding bug in which it fails to
+	handle a merge where one side has a file with a given name,
+	while another has a directory with the same name.  This is
+	documented as <ulink role="hg-bug"
+	  url="http://www.selenic.com/mercurial/bts/issue29">issue
+	  29</ulink>.</para>
+
+      &interaction.issue29.go;
+
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Recovering from mistakes</title>
+
+    <para id="x_1e2">Mercurial has some useful commands that will help you to
+      recover from some common mistakes.</para>
+
+    <para id="x_1e3">The <command role="hg-cmd">hg revert</command> command lets
+      you undo changes that you have made to your working directory.
+      For example, if you <command role="hg-cmd">hg add</command> a
+      file by accident, just run <command role="hg-cmd">hg
+	revert</command> with the name of the file you added, and
+      while the file won't be touched in any way, it won't be tracked
+      for adding by Mercurial any longer, either.  You can also use
+      <command role="hg-cmd">hg revert</command> to get rid of
+      erroneous changes to a file.</para>
+
+    <para id="x_1e4">It is helpful to remember that the <command
+	role="hg-cmd">hg revert</command> command is useful for
+      changes that you have not yet committed.  Once you've committed
+      a change, if you decide it was a mistake, you can still do
+      something about it, though your options may be more
+      limited.</para>
+
+    <para id="x_1e5">For more information about the <command
+	role="hg-cmd">hg revert</command> command, and details about
+      how to deal with changes you have already committed, see <xref
+	linkend="chap:undo"/>.</para>
+  </sect1>
+
+  <sect1>
+    <title>Dealing with tricky merges</title>
+
+    <para id="x_687">In a complicated or large project, it's not unusual for a
+      merge of two changesets to result in some headaches.  Suppose
+      there's a big source file that's been extensively edited by each
+      side of a merge: this is almost inevitably going to result in
+      conflicts, some of which can take a few tries to sort
+      out.</para>
+
+    <para id="x_688">Let's develop a simple case of this and see how to deal with
+      it.  We'll start off with a repository containing one file, and
+      clone it twice.</para>
+
+    &interaction.ch04-resolve.init;
+
+    <para id="x_689">In one clone, we'll modify the file in one way.</para>
+
+    &interaction.ch04-resolve.left;
+
+    <para id="x_68a">In another, we'll modify the file differently.</para>
+
+    &interaction.ch04-resolve.right;
+
+    <para id="x_68b">Next, we'll pull each set of changes into our original
+      repo.</para>
+
+    &interaction.ch04-resolve.pull;
+
+    <para id="x_68c">We expect our repository to now contain two heads.</para>
+
+    &interaction.ch04-resolve.heads;
+
+    <para id="x_68d">Normally, if we run <command role="hg-cmd">hg
+	merge</command> at this point, it will drop us into a GUI that
+      will let us manually resolve the conflicting edits to
+      <filename>myfile.txt</filename>.  However, to simplify things
+      for presentation here, we'd like the merge to fail immediately
+      instead.  Here's one way we can do so.</para>
+
+    &interaction.ch04-resolve.export;
+
+    <para id="x_68e">We've told Mercurial's merge machinery to run the command
+      <command>false</command> (which, as we desire, fails
+      immediately) if it detects a merge that it can't sort out
+      automatically.</para>
+
+    <para id="x_68f">If we now fire up <command role="hg-cmd">hg
+	merge</command>, it should grind to a halt and report a
+	failure.</para>
+
+    &interaction.ch04-resolve.merge;
+
+    <para id="x_690">Even if we don't notice that the merge failed, Mercurial
+      will prevent us from accidentally committing the result of a
+      failed merge.</para>
+
+    &interaction.ch04-resolve.cifail;
+
+    <para id="x_691">When <command role="hg-cmd">hg commit</command> fails in
+      this case, it suggests that we use the unfamiliar <command
+	role="hg-cmd">hg resolve</command> command.  As usual,
+	<command role="hg-cmd">hg help resolve</command> will print a
+      helpful synopsis.</para>
+
+    <sect2>
+      <title>File resolution states</title>
+
+      <para id="x_692">When a merge occurs, most files will usually remain
+	unmodified.  For each file where Mercurial has to do
+	something, it tracks the state of the file.</para>
+
+      <itemizedlist>
+	<listitem>
+	  <para id="x_693">A <emphasis>resolved</emphasis> file has been
+	    successfully merged, either automatically by Mercurial or
+	    manually with human intervention.</para>
+	</listitem>
+	<listitem>
+	  <para id="x_694">An <emphasis>unresolved</emphasis> file was not merged
+	    successfully, and needs more attention.</para>
+	</listitem>
+      </itemizedlist>
+
+      <para id="x_695">If Mercurial sees <emphasis>any</emphasis> file in the
+	unresolved state after a merge, it considers the merge to have
+	failed.  Fortunately, we do not need to restart the entire
+	merge from scratch.</para>
+
+      <para id="x_696">The <option role="hg-opt-resolve">--list</option> or
+	<option role="hg-opt-resolve">-l</option> option to <command
+	  role="hg-cmd">hg resolve</command> prints out the state of
+	each merged file.</para>
+
+      &interaction.ch04-resolve.list;
+
+      <para id="x_697">In the output from <command role="hg-cmd">hg
+	  resolve</command>, a resolved file is marked with
+	<literal>R</literal>, while an unresolved file is marked with
+	<literal>U</literal>.  If any files are listed with
+	<literal>U</literal>, we know that an attempt to commit the
+	results of the merge will fail.</para>
+    </sect2>
+
+    <sect2>
+      <title>Resolving a file merge</title>
+
+      <para id="x_698">We have several options to move a file from the unresolved
+	into the resolved state.  By far the most common is to rerun
+	<command role="hg-cmd">hg resolve</command>.  If we pass the
+	names of individual files or directories, it will retry the
+	merges of any unresolved files present in those locations. We
+	can also pass the <option role="hg-opt-resolve">--all</option>
+	or <option role="hg-opt-resolve">-a</option> option, which
+	will retry the merges of <emphasis>all</emphasis> unresolved
+	files.</para>
+
+      <para id="x_699">Mercurial also lets us modify the resolution state of a
+	file directly.  We can manually mark a file as resolved using
+	the <option role="hg-opt-resolve">--mark</option> option, or
+	as unresolved using the <option
+	  role="hg-opt-resolve">--unmark</option> option.  This allows
+	us to clean up a particularly messy merge by hand, and to keep
+	track of our progress with each file as we go.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>More useful diffs</title>
+
+    <para id="x_6c7">The default output of the <command role="hg-cmd">hg
+	diff</command> command is backwards compatible with the
+      regular <command>diff</command> command, but this has some
+      drawbacks.</para>
+
+    <para id="x_6c8">Consider the case where we use <command role="hg-cmd">hg
+	rename</command> to rename a file.</para>
+
+    &interaction.ch04-diff.rename.basic;
+
+    <para id="x_6c9">The output of <command role="hg-cmd">hg diff</command> above
+      obscures the fact that we simply renamed a file.  The <command
+	role="hg-cmd">hg diff</command> command accepts an option,
+      <option>--git</option> or <option>-g</option>, to use a newer
+      diff format that displays such information in a more readable
+      form.</para>
+
+    &interaction.ch04-diff.rename.git;
+
+    <para id="x_6ca">This option also helps with a case that can otherwise be
+      confusing: a file that appears to be modified according to
+      <command role="hg-cmd">hg status</command>, but for which
+      <command role="hg-cmd">hg diff</command> prints nothing. This
+      situation can arise if we change the file's execute
+      permissions.</para>
+
+    &interaction.ch04-diff.chmod;
+
+    <para id="x_6cb">The normal <command>diff</command> command pays no attention
+      to file permissions, which is why <command role="hg-cmd">hg
+	diff</command> prints nothing by default.  If we supply it
+      with the <option>-g</option> option, it tells us what really
+      happened.</para>
+
+    &interaction.ch04-diff.chmod.git;
+  </sect1>
+
+  <sect1>
+    <title>Which files to manage, and which to avoid</title>
+
+    <para id="x_6cc">Revision control systems are generally best at managing text
+      files that are written by humans, such as source code, where the
+      files do not change much from one revision to the next.  Some
+      centralized revision control systems can also deal tolerably
+      well with binary files, such as bitmap images.</para>
+
+    <para id="x_6cd">For instance, a game development team will typically manage
+      both its source code and all of its binary assets (e.g. geometry
+      data, textures, map layouts) in a revision control
+      system.</para>
+
+    <para id="x_6ce">Because it is usually impossible to merge two conflicting
+      modifications to a binary file, centralized systems often
+      provide a file locking mechanism that allow a user to say
+      <quote>I am the only person who can edit this
+	file</quote>.</para>
+
+    <para id="x_6cf">Compared to a centralized system, a distributed revision
+      control system changes some of the factors that guide decisions
+      over which files to manage and how.</para>
+
+    <para id="x_6d0">For instance, a distributed revision control system cannot,
+      by its nature, offer a file locking facility.  There is thus no
+      built-in mechanism to prevent two people from making conflicting
+      changes to a binary file.  If you have a team where several
+      people may be editing binary files frequently, it may not be a
+      good idea to use Mercurial&emdash;or any other distributed
+      revision control system&emdash;to manage those files.</para>
+
+    <para id="x_6d1">When storing modifications to a file, Mercurial usually
+      saves only the differences between the previous and current
+      versions of the file.  For most text files, this is extremely
+      efficient. However, some files (particularly binary files) are
+      laid out in such a way that even a small change to a file's
+      logical content results in many or most of the bytes inside the
+      file changing.  For instance, compressed files are particularly
+      susceptible to this. If the differences between each successive
+      version of a file are always large, Mercurial will not be able
+      to store the file's revision history very efficiently.  This can
+      affect both local storage needs and the amount of time it takes
+      to clone a repository.</para>
+
+    <para id="x_6d2">To get an idea of how this could affect you in practice,
+      suppose you want to use Mercurial to manage an OpenOffice
+      document.  OpenOffice stores documents on disk as compressed zip
+      files. Edit even a single letter of your document in OpenOffice,
+      and almost every byte in the entire file will change when you
+      save it. Now suppose that file is 2MB in size.  Because most of
+      the file changes every time you save, Mercurial will have to
+      store all 2MB of the file every time you commit, even though
+      from your perspective, perhaps only a few words are changing
+      each time.  A single frequently-edited file that is not friendly
+      to Mercurial's storage assumptions can easily have an outsized
+      effect on the size of the repository.</para>
+
+    <para id="x_6d3">Even worse, if both you and someone else edit the OpenOffice
+      document you're working on, there is no useful way to merge your
+      work. In fact, there isn't even a good way to tell what the
+      differences are between your respective changes.</para>
+
+    <para id="x_6d4">There are thus a few clear recommendations about specific
+      kinds of files to be very careful with.</para>
+
+    <itemizedlist>
+      <listitem>
+	<para id="x_6d5">Files that are very large and incompressible, e.g. ISO
+	  CD-ROM images, will by virtue of sheer size make clones over
+	  a network very slow.</para>
+      </listitem>
+      <listitem>
+	<para id="x_6d6">Files that change a lot from one revision to the next
+	  may be expensive to store if you edit them frequently, and
+	  conflicts due to concurrent edits may be difficult to
+	  resolve.</para>
+      </listitem>
+    </itemizedlist>
+  </sect1>
+
+  <sect1>
+    <title>Backups and mirroring</title>
+
+    <para id="x_6d7">Since Mercurial maintains a complete copy of history in each
+      clone, everyone who uses Mercurial to collaborate on a project
+      can potentially act as a source of backups in the event of a
+      catastrophe.  If a central repository becomes unavailable, you
+      can construct a replacement simply by cloning a copy of the
+      repository from one contributor, and pulling any changes they
+      may not have seen from others.</para>
+
+    <para id="x_6d8">It is simple to use Mercurial to perform off-site backups
+      and remote mirrors.  Set up a periodic job (e.g. via the
+      <command>cron</command> command) on a remote server to pull
+      changes from your master repositories every hour.  This will
+      only be tricky in the unlikely case that the number of master
+      repositories you maintain changes frequently, in which case
+      you'll need to do a little scripting to refresh the list of
+      repositories to back up.</para>
+
+    <para id="x_6d9">If you perform traditional backups of your master
+      repositories to tape or disk, and you want to back up a
+      repository named <filename>myrepo</filename>, use <command>hg
+	clone -U myrepo myrepo.bak</command> to create a
+      clone of <filename>myrepo</filename> before you start your
+      backups.  The <option>-U</option> option doesn't check out a
+      working directory after the clone completes, since that would be
+      superfluous and make the backup take longer.</para>
+
+    <para id="x_6da">If you then back up <filename>myrepo.bak</filename> instead
+      of <filename>myrepo</filename>, you will be guaranteed to have a
+      consistent snapshot of your repository that won't be pushed to
+      by an insomniac developer in mid-backup.</para>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch06-collab.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,1565 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="cha:collab">
+  <?dbhtml filename="collaborating-with-other-people.html"?>
+  <title>Collaborating with other people</title>
+
+  <para id="x_44a">As a completely decentralised tool, Mercurial doesn't impose
+    any policy on how people ought to work with each other.  However,
+    if you're new to distributed revision control, it helps to have
+    some tools and examples in mind when you're thinking about
+    possible workflow models.</para>
+
+  <sect1>
+    <title>Mercurial's web interface</title>
+
+    <para id="x_44b">Mercurial has a powerful web interface that provides several
+      useful capabilities.</para>
+
+    <para id="x_44c">For interactive use, the web interface lets you browse a
+      single repository or a collection of repositories.  You can view
+      the history of a repository, examine each change (comments and
+      diffs), and view the contents of each directory and file.  You
+      can even get a view of history that gives a graphical view of
+      the relationships between individual changes and merges.</para>
+
+    <para id="x_44d">Also for human consumption, the web interface provides
+      Atom and RSS feeds of the changes in a repository.  This lets you
+      <quote>subscribe</quote> to a repository using your favorite
+      feed reader, and be automatically notified of activity in that
+      repository as soon as it happens.  I find this capability much
+      more convenient than the model of subscribing to a mailing list
+      to which notifications are sent, as it requires no additional
+      configuration on the part of whoever is serving the
+      repository.</para>
+
+    <para id="x_44e">The web interface also lets remote users clone a repository,
+      pull changes from it, and (when the server is configured to
+      permit it) push changes back to it.  Mercurial's HTTP tunneling
+      protocol aggressively compresses data, so that it works
+      efficiently even over low-bandwidth network connections.</para>
+
+    <para id="x_44f">The easiest way to get started with the web interface is to
+      use your web browser to visit an existing repository, such as
+      the master Mercurial repository at <ulink
+	url="http://www.selenic.com/repo/hg">http://www.selenic.com/repo/hg</ulink>.</para>
+
+    <para id="x_450">If you're interested in providing a web interface
+      to your own repositories, there are several good ways to do
+      this.</para>
+
+    <para id="x_69d">The easiest and fastest way to get started in an informal
+      environment is to use the <command role="hg-cmd">hg
+	serve</command> command, which is best suited to short-term
+      <quote>lightweight</quote> serving.  See <xref
+	linkend="sec:collab:serve"/> below for details of how to use
+      this command.</para>
+
+    <para id="x_69e">For longer-lived repositories that you'd like to
+      have permanently available, there are several public hosting
+      services available.  Some are free to open source projects,
+      while others offer paid commercial hosting.  An up-to-date list
+      is available at <ulink
+	url="http://www.selenic.com/mercurial/wiki/index.cgi/MercurialHosting">http://www.selenic.com/mercurial/wiki/index.cgi/MercurialHosting</ulink>.</para>
+
+    <para id="x_6a0">If you would prefer to host your own repositories, Mercurial
+      has built-in support for several popular hosting technologies,
+      most notably CGI (Common Gateway Interface), and WSGI (Web
+      Services Gateway Interface).  See <xref
+	linkend="sec:collab:cgi"/> for details of CGI and WSGI
+      configuration.</para>
+  </sect1>
+
+  <sect1>
+    <title>Collaboration models</title>
+
+    <para id="x_451">With a suitably flexible tool, making decisions about
+      workflow is much more of a social engineering challenge than a
+      technical one. Mercurial imposes few limitations on how you can
+      structure the flow of work in a project, so it's up to you and
+      your group to set up and live with a model that matches your own
+      particular needs.</para>
+
+    <sect2>
+      <title>Factors to keep in mind</title>
+
+      <para id="x_452">The most important aspect of any model that you must keep
+	in mind is how well it matches the needs and capabilities of
+	the people who will be using it.  This might seem
+	self-evident; even so, you still can't afford to forget it for
+	a moment.</para>
+
+      <para id="x_453">I once put together a workflow model that seemed to make
+	perfect sense to me, but that caused a considerable amount of
+	consternation and strife within my development team.  In spite
+	of my attempts to explain why we needed a complex set of
+	branches, and how changes ought to flow between them, a few
+	team members revolted.  Even though they were smart people,
+	they didn't want to pay attention to the constraints we were
+	operating under, or face the consequences of those constraints
+	in the details of the model that I was advocating.</para>
+
+      <para id="x_454">Don't sweep foreseeable social or technical problems under
+	the rug. Whatever scheme you put into effect, you should plan
+	for mistakes and problem scenarios.  Consider adding automated
+	machinery to prevent, or quickly recover from, trouble that
+	you can anticipate.  As an example, if you intend to have a
+	branch with not-for-release changes in it, you'd do well to
+	think early about the possibility that someone might
+	accidentally merge those changes into a release branch.  You
+	could avoid this particular problem by writing a hook that
+	prevents changes from being merged from an inappropriate
+	branch.</para>
+    </sect2>
+
+    <sect2>
+      <title>Informal anarchy</title>
+
+      <para id="x_455">I wouldn't suggest an <quote>anything goes</quote>
+	approach as something sustainable, but it's a model that's
+	easy to grasp, and it works perfectly well in a few unusual
+	situations.</para>
+
+      <para id="x_456">As one example, many projects have a loose-knit group of
+	collaborators who rarely physically meet each other.  Some
+	groups like to overcome the isolation of working at a distance
+	by organizing occasional <quote>sprints</quote>.  In a sprint,
+	a number of people get together in a single location (a
+	company's conference room, a hotel meeting room, that kind of
+	place) and spend several days more or less locked in there,
+	hacking intensely on a handful of projects.</para>
+
+      <para id="x_457">A sprint or a hacking session in a coffee shop are the perfect places to use the
+	<command role="hg-cmd">hg serve</command> command, since
+	<command role="hg-cmd">hg serve</command> does not require any
+	fancy server infrastructure.  You can get started with
+	<command role="hg-cmd">hg serve</command> in moments, by
+	reading <xref linkend="sec:collab:serve"/> below.  Then simply
+	tell the person next to you that you're running a server, send
+	the URL to them in an instant message, and you immediately
+	have a quick-turnaround way to work together.  They can type
+	your URL into their web browser and quickly review your
+	changes; or they can pull a bugfix from you and verify it; or
+	they can clone a branch containing a new feature and try it
+	out.</para>
+
+      <para id="x_458">The charm, and the problem, with doing things
+	in an ad hoc fashion like this is that only people who know
+	about your changes, and where they are, can see them.  Such an
+	informal approach simply doesn't scale beyond a handful
+	people, because each individual needs to know about
+	<emphasis>n</emphasis> different repositories to pull
+	from.</para>
+    </sect2>
+
+    <sect2>
+      <title>A single central repository</title>
+
+      <para id="x_459">For smaller projects migrating from a centralised revision
+	control tool, perhaps the easiest way to get started is to
+	have changes flow through a single shared central repository.
+	This is also the most common <quote>building block</quote> for
+	more ambitious workflow schemes.</para>
+
+      <para id="x_45a">Contributors start by cloning a copy of this repository.
+	They can pull changes from it whenever they need to, and some
+	(perhaps all) developers have permission to push a change back
+	when they're ready for other people to see it.</para>
+
+      <para id="x_45b">Under this model, it can still often make sense for people
+	to pull changes directly from each other, without going
+	through the central repository.  Consider a case in which I
+	have a tentative bug fix, but I am worried that if I were to
+	publish it to the central repository, it might subsequently
+	break everyone else's trees as they pull it.  To reduce the
+	potential for damage, I can ask you to clone my repository
+	into a temporary repository of your own and test it.  This
+	lets us put off publishing the potentially unsafe change until
+	it has had a little testing.</para>
+
+      <para id="x_45c">If a team is hosting its own repository in this
+	kind of scenario, people will usually use the
+	<command>ssh</command> protocol to securely push changes to
+	the central repository, as documented in <xref
+	  linkend="sec:collab:ssh"/>.  It's also usual to publish a
+	read-only copy of the repository over HTTP, as in
+	<xref linkend="sec:collab:cgi"/>. Publishing over HTTP
+	satisfies the needs of people who don't have push access, and
+	those who want to use web browsers to browse the repository's
+	history.</para>
+    </sect2>
+
+    <sect2>
+      <title>A hosted central repository</title>
+
+      <para id="x_6a1">A wonderful thing about public hosting services like
+	<ulink url="http://bitbucket.org/">Bitbucket</ulink> is that
+	not only do they handle the fiddly server configuration
+	details, such as user accounts, authentication, and secure
+	wire protocols, they provide additional infrastructure to make
+	this model work well.</para>
+
+      <para id="x_6a2">For instance, a well-engineered hosting service will let
+	people clone their own copies of a repository with a single
+	click.  This lets people work in separate spaces and share
+	their changes when they're ready.</para>
+
+      <para id="x_6a3">In addition, a good hosting service will let people
+	communicate with each other, for instance to say <quote>there
+	  are changes ready for you to review in this
+	  tree</quote>.</para>
+    </sect2>
+
+    <sect2>
+      <title>Working with multiple branches</title>
+
+      <para id="x_45d">Projects of any significant size naturally tend to make
+	progress on several fronts simultaneously.  In the case of
+	software, it's common for a project to go through periodic
+	official releases.  A release might then go into
+	<quote>maintenance mode</quote> for a while after its first
+	publication; maintenance releases tend to contain only bug
+	fixes, not new features.  In parallel with these maintenance
+	releases, one or more future releases may be under
+	development.  People normally use the word
+	<quote>branch</quote> to refer to one of these many slightly
+	different directions in which development is
+	proceeding.</para>
+
+      <para id="x_45e">Mercurial is particularly well suited to managing a number
+	of simultaneous, but not identical, branches.  Each
+	<quote>development direction</quote> can live in its own
+	central repository, and you can merge changes from one to
+	another as the need arises.  Because repositories are
+	independent of each other, unstable changes in a development
+	branch will never affect a stable branch unless someone
+	explicitly merges those changes into the stable branch.</para>
+
+      <para id="x_45f">Here's an example of how this can work in practice.  Let's
+	say you have one <quote>main branch</quote> on a central
+	server.</para>
+
+      &interaction.branching.init;
+
+      <para id="x_460">People clone it, make changes locally, test them, and push
+	them back.</para>
+
+      <para id="x_461">Once the main branch reaches a release milestone, you can
+	use the <command role="hg-cmd">hg tag</command> command to
+	give a permanent name to the milestone revision.</para>
+
+	&interaction.branching.tag;
+
+      <para id="x_462">Let's say some ongoing
+	development occurs on the main branch.</para>
+
+      &interaction.branching.main;
+
+      <para id="x_463">Using the tag that was recorded at the milestone, people
+	who clone that repository at any time in the future can use
+	<command role="hg-cmd">hg update</command> to get a copy of
+	the working directory exactly as it was when that tagged
+	revision was committed.</para>
+
+      &interaction.branching.update;
+
+      <para id="x_464">In addition, immediately after the main branch is tagged,
+	we can then clone the main branch on the server to a new
+	<quote>stable</quote> branch, also on the server.</para>
+
+      &interaction.branching.clone;
+
+      <para id="x_465">If we need to make a change to the stable
+	branch, we can then clone <emphasis>that</emphasis>
+	repository, make our changes, commit, and push our changes
+	back there.</para>
+
+      &interaction.branching.stable;
+
+      <para id="x_466">Because Mercurial repositories are independent, and
+	Mercurial doesn't move changes around automatically, the
+	stable and main branches are <emphasis>isolated</emphasis>
+	from each other.  The changes that we made on the main branch
+	don't <quote>leak</quote> to the stable branch, and vice
+	versa.</para>
+
+      <para id="x_467">We'll often want all of our bugfixes on the stable
+	branch to show up on the main branch, too.  Rather than
+	rewrite a bugfix on the main branch, we can simply pull and
+	merge changes from the stable to the main branch, and
+	Mercurial will bring those bugfixes in for us.</para>
+
+      &interaction.branching.merge;
+
+      <para id="x_468">The main branch will still contain changes that
+	are not on the stable branch, but it will also contain all of
+	the bugfixes from the stable branch.  The stable branch
+	remains unaffected by these changes, since changes are only
+	flowing from the stable to the main branch, and not the other
+	way.</para>
+    </sect2>
+
+    <sect2>
+      <title>Feature branches</title>
+
+      <para id="x_469">For larger projects, an effective way to manage change is
+	to break up a team into smaller groups.  Each group has a
+	shared branch of its own, cloned from a single
+	<quote>master</quote> branch used by the entire project.
+	People working on an individual branch are typically quite
+	isolated from developments on other branches.</para>
+
+      <figure id="fig:collab:feature-branches">
+	<title>Feature branches</title>
+	<mediaobject>
+	  <imageobject><imagedata width="100%" fileref="figs/feature-branches.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_46b">When a particular feature is deemed to be in suitable
+	shape, someone on that feature team pulls and merges from the
+	master branch into the feature branch, then pushes back up to
+	the master branch.</para>
+    </sect2>
+
+    <sect2>
+      <title>The release train</title>
+
+      <para id="x_46c">Some projects are organized on a <quote>train</quote>
+	basis: a release is scheduled to happen every few months, and
+	whatever features are ready when the <quote>train</quote> is
+	ready to leave are allowed in.</para>
+
+      <para id="x_46d">This model resembles working with feature branches.  The
+	difference is that when a feature branch misses a train,
+	someone on the feature team pulls and merges the changes that
+	went out on that train release into the feature branch, and
+	the team continues its work on top of that release so that
+	their feature can make the next release.</para>
+    </sect2>
+
+    <sect2>
+      <title>The Linux kernel model</title>
+
+      <para id="x_46e">The development of the Linux kernel has a shallow
+	hierarchical structure, surrounded by a cloud of apparent
+	chaos.  Because most Linux developers use
+	<command>git</command>, a distributed revision control tool
+	with capabilities similar to Mercurial, it's useful to
+	describe the way work flows in that environment; if you like
+	the ideas, the approach translates well across tools.</para>
+
+      <para id="x_46f">At the center of the community sits Linus Torvalds, the
+	creator of Linux.  He publishes a single source repository
+	that is considered the <quote>authoritative</quote> current
+	tree by the entire developer community. Anyone can clone
+	Linus's tree, but he is very choosy about whose trees he pulls
+	from.</para>
+
+      <para id="x_470">Linus has a number of <quote>trusted lieutenants</quote>.
+	As a general rule, he pulls whatever changes they publish, in
+	most cases without even reviewing those changes.  Some of
+	those lieutenants are generally agreed to be
+	<quote>maintainers</quote>, responsible for specific
+	subsystems within the kernel.  If a random kernel hacker wants
+	to make a change to a subsystem that they want to end up in
+	Linus's tree, they must find out who the subsystem's
+	maintainer is, and ask that maintainer to take their change.
+	If the maintainer reviews their changes and agrees to take
+	them, they'll pass them along to Linus in due course.</para>
+
+      <para id="x_471">Individual lieutenants have their own approaches to
+	reviewing, accepting, and publishing changes; and for deciding
+	when to feed them to Linus.  In addition, there are several
+	well known branches that people use for different purposes.
+	For example, a few people maintain <quote>stable</quote>
+	repositories of older versions of the kernel, to which they
+	apply critical fixes as needed.  Some maintainers publish
+	multiple trees: one for experimental changes; one for changes
+	that they are about to feed upstream; and so on.  Others just
+	publish a single tree.</para>
+
+      <para id="x_472">This model has two notable features.  The first is that
+	it's <quote>pull only</quote>.  You have to ask, convince, or
+	beg another developer to take a change from you, because there
+	are almost no trees to which more than one person can push,
+	and there's no way to push changes into a tree that someone
+	else controls.</para>
+
+      <para id="x_473">The second is that it's based on reputation and acclaim.
+	If you're an unknown, Linus will probably ignore changes from
+	you without even responding.  But a subsystem maintainer will
+	probably review them, and will likely take them if they pass
+	their criteria for suitability. The more <quote>good</quote>
+	changes you contribute to a maintainer, the more likely they
+	are to trust your judgment and accept your changes.  If you're
+	well-known and maintain a long-lived branch for something
+	Linus hasn't yet accepted, people with similar interests may
+	pull your changes regularly to keep up with your work.</para>
+
+      <para id="x_474">Reputation and acclaim don't necessarily cross subsystem
+	or <quote>people</quote> boundaries.  If you're a respected
+	but specialised storage hacker, and you try to fix a
+	networking bug, that change will receive a level of scrutiny
+	from a network maintainer comparable to a change from a
+	complete stranger.</para>
+
+      <para id="x_475">To people who come from more orderly project backgrounds,
+	the comparatively chaotic Linux kernel development process
+	often seems completely insane.  It's subject to the whims of
+	individuals; people make sweeping changes whenever they deem
+	it appropriate; and the pace of development is astounding.
+	And yet Linux is a highly successful, well-regarded piece of
+	software.</para>
+    </sect2>
+
+    <sect2>
+      <title>Pull-only versus shared-push collaboration</title>
+
+      <para id="x_476">A perpetual source of heat in the open source community is
+	whether a development model in which people only ever pull
+	changes from others is <quote>better than</quote> one in which
+	multiple people can push changes to a shared
+	repository.</para>
+
+      <para id="x_477">Typically, the backers of the shared-push model use tools
+	that actively enforce this approach.  If you're using a
+	centralised revision control tool such as Subversion, there's
+	no way to make a choice over which model you'll use: the tool
+	gives you shared-push, and if you want to do anything else,
+	you'll have to roll your own approach on top (such as applying
+	a patch by hand).</para>
+
+      <para id="x_478">A good distributed revision control tool will
+	support both models.  You and your collaborators can then
+	structure how you work together based on your own needs and
+	preferences, not on what contortions your tools force you
+	into.</para>
+    </sect2>
+    <sect2>
+      <title>Where collaboration meets branch management</title>
+
+      <para id="x_479">Once you and your team set up some shared
+	repositories and start propagating changes back and forth
+	between local and shared repos, you begin to face a related,
+	but slightly different challenge: that of managing the
+	multiple directions in which your team may be moving at once.
+	Even though this subject is intimately related to how your
+	team collaborates, it's dense enough to merit treatment of its
+	own, in <xref linkend="chap:branch"/>.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>The technical side of sharing</title>
+
+    <para id="x_47a">The remainder of this chapter is devoted to the question of
+      sharing changes with your collaborators.</para>
+  </sect1>
+
+  <sect1 id="sec:collab:serve">
+    <title>Informal sharing with <command role="hg-cmd">hg
+	serve</command></title>
+
+    <para id="x_47b">Mercurial's <command role="hg-cmd">hg serve</command>
+      command is wonderfully suited to small, tight-knit, and
+      fast-paced group environments.  It also provides a great way to
+      get a feel for using Mercurial commands over a network.</para>
+
+    <para id="x_47c">Run <command role="hg-cmd">hg serve</command> inside a
+      repository, and in under a second it will bring up a specialised
+      HTTP server; this will accept connections from any client, and
+      serve up data for that repository until you terminate it.
+      Anyone who knows the URL of the server you just started, and can
+      talk to your computer over the network, can then use a web
+      browser or Mercurial to read data from that repository.  A URL
+      for a <command role="hg-cmd">hg serve</command> instance running
+      on a laptop is likely to look something like
+      <literal>http://my-laptop.local:8000/</literal>.</para>
+
+    <para id="x_47d">The <command role="hg-cmd">hg serve</command> command is
+      <emphasis>not</emphasis> a general-purpose web server. It can do
+      only two things:</para>
+    <itemizedlist>
+      <listitem><para id="x_47e">Allow people to browse the history of the
+	  repository it's serving, from their normal web
+	  browsers.</para>
+      </listitem>
+      <listitem><para id="x_47f">Speak Mercurial's wire protocol, so that people
+	  can <command role="hg-cmd">hg clone</command> or <command
+	    role="hg-cmd">hg pull</command> changes from that
+	  repository.</para>
+      </listitem></itemizedlist>
+    <para id="x_480">In particular, <command role="hg-cmd">hg serve</command>
+      won't allow remote users to <emphasis>modify</emphasis> your
+      repository.  It's intended for read-only use.</para>
+
+    <para id="x_481">If you're getting started with Mercurial, there's nothing to
+      prevent you from using <command role="hg-cmd">hg serve</command>
+      to serve up a repository on your own computer, then use commands
+      like <command role="hg-cmd">hg clone</command>, <command
+	role="hg-cmd">hg incoming</command>, and so on to talk to that
+      server as if the repository was hosted remotely. This can help
+      you to quickly get acquainted with using commands on
+      network-hosted repositories.</para>
+
+    <sect2>
+      <title>A few things to keep in mind</title>
+
+      <para id="x_482">Because it provides unauthenticated read access to all
+	clients, you should only use <command role="hg-cmd">hg
+	  serve</command> in an environment where you either don't
+	care, or have complete control over, who can access your
+	network and pull data from your repository.</para>
+
+      <para id="x_483">The <command role="hg-cmd">hg serve</command> command
+	knows nothing about any firewall software you might have
+	installed on your system or network.  It cannot detect or
+	control your firewall software.  If other people are unable to
+	talk to a running <command role="hg-cmd">hg serve</command>
+	instance, the second thing you should do
+	(<emphasis>after</emphasis> you make sure that they're using
+	the correct URL) is check your firewall configuration.</para>
+
+      <para id="x_484">By default, <command role="hg-cmd">hg serve</command>
+	listens for incoming connections on port 8000.  If another
+	process is already listening on the port you want to use, you
+	can specify a different port to listen on using the <option
+	  role="hg-opt-serve">-p</option> option.</para>
+
+      <para id="x_485">Normally, when <command role="hg-cmd">hg serve</command>
+	starts, it prints no output, which can be a bit unnerving.  If
+	you'd like to confirm that it is indeed running correctly, and
+	find out what URL you should send to your collaborators, start
+	it with the <option role="hg-opt-global">-v</option>
+	option.</para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="sec:collab:ssh">
+    <title>Using the Secure Shell (ssh) protocol</title>
+
+    <para id="x_486">You can pull and push changes securely over a network
+      connection using the Secure Shell (<literal>ssh</literal>)
+      protocol.  To use this successfully, you may have to do a little
+      bit of configuration on the client or server sides.</para>
+
+    <para id="x_487">If you're not familiar with ssh, it's the name of
+      both a command and a network protocol that let you securely
+      communicate with another computer.  To use it with Mercurial,
+      you'll be setting up one or more user accounts on a server so
+      that remote users can log in and execute commands.</para>
+
+    <para id="x_488">(If you <emphasis>are</emphasis> familiar with ssh, you'll
+      probably find some of the material that follows to be elementary
+      in nature.)</para>
+
+    <sect2>
+      <title>How to read and write ssh URLs</title>
+
+      <para id="x_489">An ssh URL tends to look like this:</para>
+      <programlisting>ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting>
+      <orderedlist>
+	<listitem><para id="x_48a">The <quote><literal>ssh://</literal></quote>
+	    part tells Mercurial to use the ssh protocol.</para>
+	</listitem>
+	<listitem><para id="x_48b">The <quote><literal>bos@</literal></quote>
+	    component indicates what username to log into the server
+	    as.  You can leave this out if the remote username is the
+	    same as your local username.</para>
+	</listitem>
+	<listitem><para id="x_48c">The
+	    <quote><literal>hg.serpentine.com</literal></quote> gives
+	    the hostname of the server to log into.</para>
+	</listitem>
+	<listitem><para id="x_48d">The <quote>:22</quote> identifies the port
+	    number to connect to the server on.  The default port is
+	    22, so you only need to specify a colon and port number if
+	    you're <emphasis>not</emphasis> using port 22.</para>
+	</listitem>
+	<listitem><para id="x_48e">The remainder of the URL is the local path to
+	    the repository on the server.</para>
+	</listitem></orderedlist>
+
+      <para id="x_48f">There's plenty of scope for confusion with the path
+	component of ssh URLs, as there is no standard way for tools
+	to interpret it.  Some programs behave differently than others
+	when dealing with these paths. This isn't an ideal situation,
+	but it's unlikely to change.  Please read the following
+	paragraphs carefully.</para>
+
+      <para id="x_490">Mercurial treats the path to a repository on the server as
+	relative to the remote user's home directory.  For example, if
+	user <literal>foo</literal> on the server has a home directory
+	of <filename class="directory">/home/foo</filename>, then an
+	ssh URL that contains a path component of <filename
+	  class="directory">bar</filename> <emphasis>really</emphasis>
+	refers to the directory <filename
+	  class="directory">/home/foo/bar</filename>.</para>
+
+      <para id="x_491">If you want to specify a path relative to another user's
+	home directory, you can use a path that starts with a tilde
+	character followed by the user's name (let's call them
+	<literal>otheruser</literal>), like this.</para>
+      <programlisting>ssh://server/~otheruser/hg/repo</programlisting>
+
+      <para id="x_492">And if you really want to specify an
+	<emphasis>absolute</emphasis> path on the server, begin the
+	path component with two slashes, as in this example.</para>
+      <programlisting>ssh://server//absolute/path</programlisting>
+    </sect2>
+
+    <sect2>
+      <title>Finding an ssh client for your system</title>
+
+      <para id="x_493">Almost every Unix-like system comes with OpenSSH
+	preinstalled.  If you're using such a system, run
+	<literal>which ssh</literal> to find out if the
+	<command>ssh</command> command is installed (it's usually in
+	<filename class="directory">/usr/bin</filename>).  In the
+	unlikely event that it isn't present, take a look at your
+	system documentation to figure out how to install it.</para>
+
+      <para id="x_494">On Windows, the TortoiseHg package is bundled
+	with a version of Simon Tatham's excellent
+	<command>plink</command> command, and you should not need to
+	do any further configuration.</para>
+    </sect2>
+
+    <sect2>
+      <title>Generating a key pair</title>
+
+      <para id="x_499">To avoid the need to repetitively type a
+	password every time you need to use your ssh client, I
+	recommend generating a key pair.</para>
+
+      <tip>
+	<title>Key pairs are not mandatory</title>
+
+	<para id="x_6a4">Mercurial knows nothing about ssh authentication or key
+	  pairs.  You can, if you like, safely ignore this section and
+	  the one that follows until you grow tired of repeatedly
+	  typing ssh passwords.</para>
+      </tip>
+
+      <itemizedlist>
+	<listitem>
+	  <para id="x_6a5">On a Unix-like system, the
+	    <command>ssh-keygen</command> command will do the
+	    trick.</para>
+	  <para id="x_6a6">On Windows, if you're using TortoiseHg, you may need
+	    to download a command named <command>puttygen</command>
+	    from <ulink
+	      url="http://www.chiark.greenend.org.uk/~sgtatham/putty">the 
+	      PuTTY web site</ulink> to generate a key pair.  See
+	    <ulink
+	      url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter8.html#pubkey-puttygen">the 
+	      <command>puttygen</command> documentation</ulink> for
+	    details of how use the command.</para>
+	</listitem>
+      </itemizedlist>
+
+      <para id="x_49a">When you generate a key pair, it's usually
+	<emphasis>highly</emphasis> advisable to protect it with a
+	passphrase.  (The only time that you might not want to do this
+	is when you're using the ssh protocol for automated tasks on a
+	secure network.)</para>
+
+      <para id="x_49b">Simply generating a key pair isn't enough, however.
+	You'll need to add the public key to the set of authorised
+	keys for whatever user you're logging in remotely as.  For
+	servers using OpenSSH (the vast majority), this will mean
+	adding the public key to a list in a file called <filename
+	  role="special">authorized_keys</filename> in their <filename
+	  role="special" class="directory">.ssh</filename>
+	directory.</para>
+
+      <para id="x_49c">On a Unix-like system, your public key will have a
+	<filename>.pub</filename> extension.  If you're using
+	<command>puttygen</command> on Windows, you can save the
+	public key to a file of your choosing, or paste it from the
+	window it's displayed in straight into the <filename
+	  role="special">authorized_keys</filename> file.</para>
+    </sect2>
+    <sect2>
+      <title>Using an authentication agent</title>
+
+      <para id="x_49d">An authentication agent is a daemon that stores
+	passphrases in memory (so it will forget passphrases if you
+	log out and log back in again). An ssh client will notice if
+	it's running, and query it for a passphrase.  If there's no
+	authentication agent running, or the agent doesn't store the
+	necessary passphrase, you'll have to type your passphrase
+	every time Mercurial tries to communicate with a server on
+	your behalf (e.g. whenever you pull or push changes).</para>
+
+      <para id="x_49e">The downside of storing passphrases in an agent is that
+	it's possible for a well-prepared attacker to recover the
+	plain text of your passphrases, in some cases even if your
+	system has been power-cycled. You should make your own
+	judgment as to whether this is an acceptable risk.  It
+	certainly saves a lot of repeated typing.</para>
+
+      <itemizedlist>
+	<listitem>
+	  <para id="x_49f">On Unix-like systems, the agent is called
+	    <command>ssh-agent</command>, and it's often run
+	    automatically for you when you log in.  You'll need to use
+	    the <command>ssh-add</command> command to add passphrases
+	    to the agent's store.</para>
+	</listitem>
+	<listitem>
+	  <para id="x_6a7">On Windows, if you're using TortoiseHg, the
+	    <command>pageant</command> command acts as the agent.  As
+	    with <command>puttygen</command>, you'll need to <ulink
+	      url="http://www.chiark.greenend.org.uk/%7Esgtatham/putty/download.html">download 
+	      <command>pageant</command></ulink> from the PuTTY web
+	    site and read <ulink
+	      url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter9.html#pageant">its 
+	      documentation</ulink>.  The <command>pageant</command>
+	    command adds an icon to your system tray that will let you
+	    manage stored passphrases.</para>
+	</listitem>
+      </itemizedlist>
+    </sect2>
+
+    <sect2>
+      <title>Configuring the server side properly</title>
+
+      <para id="x_4a0">Because ssh can be fiddly to set up if you're new to it,
+	a variety of things can go wrong.  Add Mercurial
+	on top, and there's plenty more scope for head-scratching.
+	Most of these potential problems occur on the server side, not
+	the client side.  The good news is that once you've gotten a
+	configuration working, it will usually continue to work
+	indefinitely.</para>
+
+      <para id="x_4a1">Before you try using Mercurial to talk to an ssh server,
+	it's best to make sure that you can use the normal
+	<command>ssh</command> or <command>putty</command> command to
+	talk to the server first.  If you run into problems with using
+	these commands directly, Mercurial surely won't work.  Worse,
+	it will obscure the underlying problem.  Any time you want to
+	debug ssh-related Mercurial problems, you should drop back to
+	making sure that plain ssh client commands work first,
+	<emphasis>before</emphasis> you worry about whether there's a
+	problem with Mercurial.</para>
+
+      <para id="x_4a2">The first thing to be sure of on the server side is that
+	you can actually log in from another machine at all.  If you
+	can't use <command>ssh</command> or <command>putty</command>
+	to log in, the error message you get may give you a few hints
+	as to what's wrong.  The most common problems are as
+	follows.</para>
+      <itemizedlist>
+	<listitem><para id="x_4a3">If you get a <quote>connection refused</quote>
+	    error, either there isn't an SSH daemon running on the
+	    server at all, or it's inaccessible due to firewall
+	    configuration.</para>
+	</listitem>
+	<listitem><para id="x_4a4">If you get a <quote>no route to host</quote>
+	    error, you either have an incorrect address for the server
+	    or a seriously locked down firewall that won't admit its
+	    existence at all.</para>
+	</listitem>
+	<listitem><para id="x_4a5">If you get a <quote>permission denied</quote>
+	    error, you may have mistyped the username on the server,
+	    or you could have mistyped your key's passphrase or the
+	    remote user's password.</para>
+	</listitem></itemizedlist>
+      <para id="x_4a6">In summary, if you're having trouble talking to the
+	server's ssh daemon, first make sure that one is running at
+	all.  On many systems it will be installed, but disabled, by
+	default.  Once you're done with this step, you should then
+	check that the server's firewall is configured to allow
+	incoming connections on the port the ssh daemon is listening
+	on (usually 22).  Don't worry about more exotic possibilities
+	for misconfiguration until you've checked these two
+	first.</para>
+
+      <para id="x_4a7">If you're using an authentication agent on the client side
+	to store passphrases for your keys, you ought to be able to
+	log into the server without being prompted for a passphrase or
+	a password.  If you're prompted for a passphrase, there are a
+	few possible culprits.</para>
+      <itemizedlist>
+	<listitem><para id="x_4a8">You might have forgotten to use
+	    <command>ssh-add</command> or <command>pageant</command>
+	    to store the passphrase.</para>
+	</listitem>
+	<listitem><para id="x_4a9">You might have stored the passphrase for the
+	    wrong key.</para>
+	</listitem></itemizedlist>
+      <para id="x_4aa">If you're being prompted for the remote user's password,
+	there are another few possible problems to check.</para>
+      <itemizedlist>
+	<listitem><para id="x_4ab">Either the user's home directory or their
+	    <filename role="special" class="directory">.ssh</filename>
+	    directory might have excessively liberal permissions.  As
+	    a result, the ssh daemon will not trust or read their
+	    <filename role="special">authorized_keys</filename> file.
+	    For example, a group-writable home or <filename
+	      role="special" class="directory">.ssh</filename>
+	    directory will often cause this symptom.</para>
+	</listitem>
+	<listitem><para id="x_4ac">The user's <filename
+	      role="special">authorized_keys</filename> file may have
+	    a problem. If anyone other than the user owns or can write
+	    to that file, the ssh daemon will not trust or read
+	    it.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_4ad">In the ideal world, you should be able to run the
+	following command successfully, and it should print exactly
+	one line of output, the current date and time.</para>
+      <programlisting>ssh myserver date</programlisting>
+
+      <para id="x_4ae">If, on your server, you have login scripts that print
+	banners or other junk even when running non-interactive
+	commands like this, you should fix them before you continue,
+	so that they only print output if they're run interactively.
+	Otherwise these banners will at least clutter up Mercurial's
+	output.  Worse, they could potentially cause problems with
+	running Mercurial commands remotely.  Mercurial tries to
+	detect and ignore banners in non-interactive
+	<command>ssh</command> sessions, but it is not foolproof.  (If
+	you're editing your login scripts on your server, the usual
+	way to see if a login script is running in an interactive
+	shell is to check the return code from the command
+	<literal>tty -s</literal>.)</para>
+
+      <para id="x_4af">Once you've verified that plain old ssh is working with
+	your server, the next step is to ensure that Mercurial runs on
+	the server.  The following command should run
+	successfully:</para>
+
+      <programlisting>ssh myserver hg version</programlisting>
+
+      <para id="x_4b0">If you see an error message instead of normal <command
+	  role="hg-cmd">hg version</command> output, this is usually
+	because you haven't installed Mercurial to <filename
+	  class="directory">/usr/bin</filename>.  Don't worry if this
+	is the case; you don't need to do that.  But you should check
+	for a few possible problems.</para>
+      <itemizedlist>
+	<listitem><para id="x_4b1">Is Mercurial really installed on the server at
+	    all?  I know this sounds trivial, but it's worth
+	    checking!</para>
+	</listitem>
+	<listitem><para id="x_4b2">Maybe your shell's search path (usually set
+	    via the <envar>PATH</envar> environment variable) is
+	    simply misconfigured.</para>
+	</listitem>
+	<listitem><para id="x_4b3">Perhaps your <envar>PATH</envar> environment
+	    variable is only being set to point to the location of the
+	    <command>hg</command> executable if the login session is
+	    interactive.  This can happen if you're setting the path
+	    in the wrong shell login script.  See your shell's
+	    documentation for details.</para>
+	</listitem>
+	<listitem><para id="x_4b4">The <envar>PYTHONPATH</envar> environment
+	    variable may need to contain the path to the Mercurial
+	    Python modules.  It might not be set at all; it could be
+	    incorrect; or it may be set only if the login is
+	    interactive.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_4b5">If you can run <command role="hg-cmd">hg version</command>
+	over an ssh connection, well done! You've got the server and
+	client sorted out.  You should now be able to use Mercurial to
+	access repositories hosted by that username on that server.
+	If you run into problems with Mercurial and ssh at this point,
+	try using the <option role="hg-opt-global">--debug</option>
+	option to get a clearer picture of what's going on.</para>
+    </sect2>
+    <sect2>
+      <title>Using compression with ssh</title>
+
+      <para id="x_4b6">Mercurial does not compress data when it uses the ssh
+	protocol, because the ssh protocol can transparently compress
+	data.  However, the default behavior of ssh clients is
+	<emphasis>not</emphasis> to request compression.</para>
+
+      <para id="x_4b7">Over any network other than a fast LAN (even a wireless
+	network), using compression is likely to significantly speed
+	up Mercurial's network operations.  For example, over a WAN,
+	someone measured compression as reducing the amount of time
+	required to clone a particularly large repository from 51
+	minutes to 17 minutes.</para>
+
+      <para id="x_4b8">Both <command>ssh</command> and <command>plink</command>
+	accept a <option role="cmd-opt-ssh">-C</option> option which
+	turns on compression.  You can easily edit your <filename
+	  role="special">~/.hgrc</filename> to enable compression for
+	all of Mercurial's uses of the ssh protocol.  Here is how to
+	do so for regular <command>ssh</command> on Unix-like systems,
+	for example.</para>
+      <programlisting>[ui]
+ssh = ssh -C</programlisting>
+
+      <para id="x_4b9">If you use <command>ssh</command> on a
+	Unix-like system, you can configure it to always use
+	compression when talking to your server.  To do this, edit
+	your <filename role="special">.ssh/config</filename> file
+	(which may not yet exist), as follows.</para>
+
+      <programlisting>Host hg
+  Compression yes
+  HostName hg.example.com</programlisting>
+
+      <para id="x_4ba">This defines a hostname alias,
+	<literal>hg</literal>.  When you use that hostname on the
+	<command>ssh</command> command line or in a Mercurial
+	<literal>ssh</literal>-protocol URL, it will cause
+	<command>ssh</command> to connect to
+	<literal>hg.example.com</literal> and use compression.  This
+	gives you both a shorter name to type and compression, each of
+	which is a good thing in its own right.</para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="sec:collab:cgi">
+    <title>Serving over HTTP using CGI</title>
+
+    <para id="x_6a8">The simplest way to host one or more repositories in a
+      permanent way is to use a web server and Mercurial's CGI
+      support.</para>
+
+    <para id="x_4bb">Depending on how ambitious you are, configuring Mercurial's
+      CGI interface can take anything from a few moments to several
+      hours.</para>
+
+    <para id="x_4bc">We'll begin with the simplest of examples, and work our way
+      towards a more complex configuration.  Even for the most basic
+      case, you're almost certainly going to need to read and modify
+      your web server's configuration.</para>
+
+    <note>
+      <title>High pain tolerance required</title>
+
+      <para id="x_4bd">Configuring a web server is a complex, fiddly,
+	and highly system-dependent activity.  I can't possibly give
+	you instructions that will cover anything like all of the
+	cases you will encounter. Please use your discretion and
+	judgment in following the sections below.  Be prepared to make
+	plenty of mistakes, and to spend a lot of time reading your
+	server's error logs.</para>
+
+      <para id="x_6a9">If you don't have a strong stomach for tweaking
+	configurations over and over, or a compelling need to host
+	your own services, you might want to try one of the public
+	hosting services that I mentioned earlier.</para>
+    </note>
+
+    <sect2>
+      <title>Web server configuration checklist</title>
+
+      <para id="x_4be">Before you continue, do take a few moments to check a few
+	aspects of your system's setup.</para>
+
+      <orderedlist>
+	<listitem><para id="x_4bf">Do you have a web server installed
+	    at all? Mac OS X and some Linux distributions ship with
+	    Apache, but many other systems may not have a web server
+	    installed.</para>
+	</listitem>
+	<listitem><para id="x_4c0">If you have a web server installed, is it
+	    actually running?  On most systems, even if one is
+	    present, it will be disabled by default.</para>
+	</listitem>
+	<listitem><para id="x_4c1">Is your server configured to allow you to run
+	    CGI programs in the directory where you plan to do so?
+	    Most servers default to explicitly disabling the ability
+	    to run CGI programs.</para>
+	</listitem></orderedlist>
+
+      <para id="x_4c2">If you don't have a web server installed, and don't have
+	substantial experience configuring Apache, you should consider
+	using the <literal>lighttpd</literal> web server instead of
+	Apache.  Apache has a well-deserved reputation for baroque and
+	confusing configuration. While <literal>lighttpd</literal> is
+	less capable in some ways than Apache, most of these
+	capabilities are not relevant to serving Mercurial
+	repositories.  And <literal>lighttpd</literal> is undeniably
+	<emphasis>much</emphasis> easier to get started with than
+	Apache.</para>
+    </sect2>
+
+    <sect2>
+      <title>Basic CGI configuration</title>
+
+      <para id="x_4c3">On Unix-like systems, it's common for users to have a
+	subdirectory named something like <filename
+	  class="directory">public_html</filename> in their home
+	directory, from which they can serve up web pages.  A file
+	named <filename>foo</filename> in this directory will be
+	accessible at a URL of the form
+	<literal>http://www.example.com/username/foo</literal>.</para>
+
+      <para id="x_4c4">To get started, find the <filename
+	  role="special">hgweb.cgi</filename> script that should be
+	present in your Mercurial installation.  If you can't quickly
+	find a local copy on your system, simply download one from the
+	master Mercurial repository at <ulink
+	  url="http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi</ulink>.</para>
+
+      <para id="x_4c5">You'll need to copy this script into your <filename
+	  class="directory">public_html</filename> directory, and
+	ensure that it's executable.</para>
+      <programlisting>cp .../hgweb.cgi ~/public_html
+chmod 755 ~/public_html/hgweb.cgi</programlisting>
+      <para id="x_4c6">The <literal>755</literal> argument to
+	<command>chmod</command> is a little more general than just
+	making the script executable: it ensures that the script is
+	executable by anyone, and that <quote>group</quote> and
+	<quote>other</quote> write permissions are
+	<emphasis>not</emphasis> set.  If you were to leave those
+	write permissions enabled, Apache's <literal>suexec</literal>
+	subsystem would likely refuse to execute the script.  In fact,
+	<literal>suexec</literal> also insists that the
+	<emphasis>directory</emphasis> in which the script resides
+	must not be writable by others.</para>
+      <programlisting>chmod 755 ~/public_html</programlisting>
+
+      <sect3 id="sec:collab:wtf">
+	<title>What could <emphasis>possibly</emphasis> go
+	  wrong?</title>
+
+	<para id="x_4c7">Once you've copied the CGI script into place,
+	  go into a web browser, and try to open the URL
+	  <literal>http://myhostname/~myuser/hgweb.cgi</literal>,
+	  <emphasis>but</emphasis> brace yourself for instant failure.
+	  There's a high probability that trying to visit this URL
+	  will fail, and there are many possible reasons for this.  In
+	  fact, you're likely to stumble over almost every one of the
+	  possible errors below, so please read carefully.  The
+	  following are all of the problems I ran into on a system
+	  running Fedora 7, with a fresh installation of Apache, and a
+	  user account that I created specially to perform this
+	  exercise.</para>
+
+	<para id="x_4c8">Your web server may have per-user directories disabled.
+	  If you're using Apache, search your config file for a
+	  <literal>UserDir</literal> directive.  If there's none
+	  present, per-user directories will be disabled.  If one
+	  exists, but its value is <literal>disabled</literal>, then
+	  per-user directories will be disabled.  Otherwise, the
+	  string after <literal>UserDir</literal> gives the name of
+	  the subdirectory that Apache will look in under your home
+	  directory, for example <filename
+	    class="directory">public_html</filename>.</para>
+
+	<para id="x_4c9">Your file access permissions may be too restrictive.
+	  The web server must be able to traverse your home directory
+	  and directories under your <filename
+	    class="directory">public_html</filename> directory, and
+	  read files under the latter too.  Here's a quick recipe to
+	  help you to make your permissions more appropriate.</para>
+	<programlisting>chmod 755 ~
+find ~/public_html -type d -print0 | xargs -0r chmod 755
+find ~/public_html -type f -print0 | xargs -0r chmod 644</programlisting>
+
+	<para id="x_4ca">The other possibility with permissions is that you might
+	  get a completely empty window when you try to load the
+	  script.  In this case, it's likely that your access
+	  permissions are <emphasis>too permissive</emphasis>.  Apache's
+	  <literal>suexec</literal> subsystem won't execute a script
+	  that's group- or world-writable, for example.</para>
+
+	<para id="x_4cb">Your web server may be configured to disallow execution
+	  of CGI programs in your per-user web directory.  Here's
+	  Apache's default per-user configuration from my Fedora
+	  system.</para>
+
+	&ch06-apache-config.lst;
+
+	<para id="x_4cc">If you find a similar-looking
+	  <literal>Directory</literal> group in your Apache
+	  configuration, the directive to look at inside it is
+	  <literal>Options</literal>. Add <literal>ExecCGI</literal>
+	  to the end of this list if it's missing, and restart the web
+	  server.</para>
+
+	<para id="x_4cd">If you find that Apache serves you the text of the CGI
+	  script instead of executing it, you may need to either
+	  uncomment (if already present) or add a directive like
+	  this.</para>
+	<programlisting>AddHandler cgi-script .cgi</programlisting>
+
+	<para id="x_4ce">The next possibility is that you might be served with a
+	  colourful Python backtrace claiming that it can't import a
+	  <literal>mercurial</literal>-related module.  This is
+	  actually progress!  The server is now capable of executing
+	  your CGI script.  This error is only likely to occur if
+	  you're running a private installation of Mercurial, instead
+	  of a system-wide version.  Remember that the web server runs
+	  the CGI program without any of the environment variables
+	  that you take for granted in an interactive session.  If
+	  this error happens to you, edit your copy of <filename
+	    role="special">hgweb.cgi</filename> and follow the
+	  directions inside it to correctly set your
+	  <envar>PYTHONPATH</envar> environment variable.</para>
+
+	<para id="x_4cf">Finally, you are <emphasis>certain</emphasis> to be
+	  served with another colourful Python backtrace: this one
+	  will complain that it can't find <filename
+	    class="directory">/path/to/repository</filename>.  Edit
+	  your <filename role="special">hgweb.cgi</filename> script
+	  and replace the <filename
+	    class="directory">/path/to/repository</filename> string
+	  with the complete path to the repository you want to serve
+	  up.</para>
+
+	<para id="x_4d0">At this point, when you try to reload the page, you
+	  should be presented with a nice HTML view of your
+	  repository's history.  Whew!</para>
+      </sect3>
+
+      <sect3>
+	<title>Configuring lighttpd</title>
+
+	<para id="x_4d1">To be exhaustive in my experiments, I tried configuring
+	  the increasingly popular <literal>lighttpd</literal> web
+	  server to serve the same repository as I described with
+	  Apache above.  I had already overcome all of the problems I
+	  outlined with Apache, many of which are not server-specific.
+	  As a result, I was fairly sure that my file and directory
+	  permissions were good, and that my <filename
+	    role="special">hgweb.cgi</filename> script was properly
+	  edited.</para>
+
+	<para id="x_4d2">Once I had Apache running, getting
+	  <literal>lighttpd</literal> to serve the repository was a
+	  snap (in other words, even if you're trying to use
+	  <literal>lighttpd</literal>, you should read the Apache
+	  section).  I first had to edit the
+	  <literal>mod_access</literal> section of its config file to
+	  enable <literal>mod_cgi</literal> and
+	  <literal>mod_userdir</literal>, both of which were disabled
+	  by default on my system.  I then added a few lines to the
+	  end of the config file, to configure these modules.</para>
+	<programlisting>userdir.path = "public_html"
+cgi.assign = (".cgi" =&gt; "" )</programlisting>
+	<para id="x_4d3">With this done, <literal>lighttpd</literal> ran
+	  immediately for me.  If I had configured
+	  <literal>lighttpd</literal> before Apache, I'd almost
+	  certainly have run into many of the same system-level
+	  configuration problems as I did with Apache.  However, I
+	  found <literal>lighttpd</literal> to be noticeably easier to
+	  configure than Apache, even though I've used Apache for over
+	  a decade, and this was my first exposure to
+	  <literal>lighttpd</literal>.</para>
+      </sect3>
+    </sect2>
+
+    <sect2>
+      <title>Sharing multiple repositories with one CGI script</title>
+
+      <para id="x_4d4">The <filename role="special">hgweb.cgi</filename> script
+	only lets you publish a single repository, which is an
+	annoying restriction.  If you want to publish more than one
+	without wracking yourself with multiple copies of the same
+	script, each with different names, a better choice is to use
+	the <filename role="special">hgwebdir.cgi</filename>
+	script.</para>
+
+      <para id="x_4d5">The procedure to configure <filename
+	  role="special">hgwebdir.cgi</filename> is only a little more
+	involved than for <filename
+	  role="special">hgweb.cgi</filename>.  First, you must obtain
+	a copy of the script.  If you don't have one handy, you can
+	download a copy from the master Mercurial repository at <ulink
+	  url="http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi</ulink>.</para>
+
+      <para id="x_4d6">You'll need to copy this script into your <filename
+	  class="directory">public_html</filename> directory, and
+	ensure that it's executable.</para>
+
+      <programlisting>cp .../hgwebdir.cgi ~/public_html
+chmod 755 ~/public_html ~/public_html/hgwebdir.cgi</programlisting>
+
+      <para id="x_4d7">With basic configuration out of the way, try to
+	visit <literal>http://myhostname/~myuser/hgwebdir.cgi</literal>
+	in your	browser.  It should
+	display an empty list of repositories.  If you get a blank
+	window or error message, try walking through the list of
+	potential problems in <xref
+	  linkend="sec:collab:wtf"/>.</para>
+
+      <para id="x_4d8">The <filename role="special">hgwebdir.cgi</filename>
+	script relies on an external configuration file.  By default,
+	it searches for a file named <filename
+	  role="special">hgweb.config</filename> in the same directory
+	as itself.  You'll need to create this file, and make it
+	world-readable.  The format of the file is similar to a
+	Windows <quote>ini</quote> file, as understood by Python's
+	<literal>ConfigParser</literal>
+	<citation>web:configparser</citation> module.</para>
+
+      <para id="x_4d9">The easiest way to configure <filename
+	  role="special">hgwebdir.cgi</filename> is with a section
+	named <literal>collections</literal>.  This will automatically
+	publish <emphasis>every</emphasis> repository under the
+	directories you name.  The section should look like
+	this:</para>
+      <programlisting>[collections]
+/my/root = /my/root</programlisting>
+      <para id="x_4da">Mercurial interprets this by looking at the directory name
+	on the <emphasis>right</emphasis> hand side of the
+	<quote><literal>=</literal></quote> sign; finding repositories
+	in that directory hierarchy; and using the text on the
+	<emphasis>left</emphasis> to strip off matching text from the
+	names it will actually list in the web interface.  The
+	remaining component of a path after this stripping has
+	occurred is called a <quote>virtual path</quote>.</para>
+
+      <para id="x_4db">Given the example above, if we have a
+	repository whose local path is <filename
+	  class="directory">/my/root/this/repo</filename>, the CGI
+	script will strip the leading <filename
+	  class="directory">/my/root</filename> from the name, and
+	publish the repository with a virtual path of <filename
+	  class="directory">this/repo</filename>.  If the base URL for
+	our CGI script is
+	<literal>http://myhostname/~myuser/hgwebdir.cgi</literal>, the
+	complete URL for that repository will be
+	<literal>http://myhostname/~myuser/hgwebdir.cgi/this/repo</literal>.</para>
+
+      <para id="x_4dc">If we replace <filename
+	  class="directory">/my/root</filename> on the left hand side
+	of this example with <filename
+	  class="directory">/my</filename>, then <filename
+	  role="special">hgwebdir.cgi</filename> will only strip off
+	<filename class="directory">/my</filename> from the repository
+	name, and will give us a virtual path of <filename
+	  class="directory">root/this/repo</filename> instead of
+	<filename class="directory">this/repo</filename>.</para>
+
+      <para id="x_4dd">The <filename role="special">hgwebdir.cgi</filename>
+	script will recursively search each directory listed in the
+	<literal>collections</literal> section of its configuration
+	file, but it will <literal>not</literal> recurse into the
+	repositories it finds.</para>
+
+      <para id="x_4de">The <literal>collections</literal> mechanism makes it easy
+	to publish many repositories in a <quote>fire and
+	  forget</quote> manner.  You only need to set up the CGI
+	script and configuration file one time.  Afterwards, you can
+	publish or unpublish a repository at any time by simply moving
+	it into, or out of, the directory hierarchy in which you've
+	configured <filename role="special">hgwebdir.cgi</filename> to
+	look.</para>
+
+      <sect3>
+	<title>Explicitly specifying which repositories to
+	  publish</title>
+
+	<para id="x_4df">In addition to the <literal>collections</literal>
+	  mechanism, the <filename
+	    role="special">hgwebdir.cgi</filename> script allows you
+	  to publish a specific list of repositories.  To do so,
+	  create a <literal>paths</literal> section, with contents of
+	  the following form.</para>
+	<programlisting>[paths]
+repo1 = /my/path/to/some/repo
+repo2 = /some/path/to/another</programlisting>
+	<para id="x_4e0">In this case, the virtual path (the component that will
+	  appear in a URL) is on the left hand side of each
+	  definition, while the path to the repository is on the
+	  right.  Notice that there does not need to be any
+	  relationship between the virtual path you choose and the
+	  location of a repository in your filesystem.</para>
+
+	<para id="x_4e1">If you wish, you can use both the
+	  <literal>collections</literal> and <literal>paths</literal>
+	  mechanisms simultaneously in a single configuration
+	  file.</para>
+
+	<note>
+	  <title>Beware duplicate virtual paths</title>
+
+	  <para id="x_4e2">  If several repositories have the same
+	    virtual path, <filename
+	      role="special">hgwebdir.cgi</filename> will not report
+	    an error.  Instead, it will behave unpredictably.</para>
+	</note>
+      </sect3>
+    </sect2>
+
+    <sect2>
+      <title>Downloading source archives</title>
+
+      <para id="x_4e3">Mercurial's web interface lets users download an archive
+	of any revision.  This archive will contain a snapshot of the
+	working directory as of that revision, but it will not contain
+	a copy of the repository data.</para>
+
+      <para id="x_4e4">By default, this feature is not enabled.  To enable it,
+	you'll need to add an <envar
+	  role="rc-item-web">allow_archive</envar> item to the
+	<literal role="rc-web">web</literal> section of your <filename
+	  role="special">~/.hgrc</filename>; see below for details.</para>
+    </sect2>
+    <sect2>
+      <title>Web configuration options</title>
+
+      <para id="x_4e5">Mercurial's web interfaces (the <command role="hg-cmd">hg
+	  serve</command> command, and the <filename
+	  role="special">hgweb.cgi</filename> and <filename
+	  role="special">hgwebdir.cgi</filename> scripts) have a
+	number of configuration options that you can set.  These
+	belong in a section named <literal
+	  role="rc-web">web</literal>.</para>
+      <itemizedlist>
+	<listitem><para id="x_4e6"><envar
+	      role="rc-item-web">allow_archive</envar>: Determines
+	    which (if any) archive download mechanisms Mercurial
+	    supports.  If you enable this feature, users of the web
+	    interface will be able to download an archive of whatever
+	    revision of a repository they are viewing. To enable the
+	    archive feature, this item must take the form of a
+	    sequence of words drawn from the list below.</para>
+	  <itemizedlist>
+	    <listitem><para id="x_4e7"><literal>bz2</literal>: A
+		<command>tar</command> archive, compressed using
+		<literal>bzip2</literal> compression.  This has the
+		best compression ratio, but uses the most CPU time on
+		the server.</para>
+	    </listitem>
+	    <listitem><para id="x_4e8"><literal>gz</literal>: A
+		<command>tar</command> archive, compressed using
+		<literal>gzip</literal> compression.</para>
+	    </listitem>
+	    <listitem><para id="x_4e9"><literal>zip</literal>: A
+		<command>zip</command> archive, compressed using LZW
+		compression.  This format has the worst compression
+		ratio, but is widely used in the Windows world.</para>
+	    </listitem>
+	  </itemizedlist>
+	  <para id="x_4ea">  If you provide an empty list, or don't have an
+	    <envar role="rc-item-web">allow_archive</envar> entry at
+	    all, this feature will be disabled.  Here is an example of
+	    how to enable all three supported formats.</para>
+	  <programlisting>[web]
+allow_archive = bz2 gz zip</programlisting>
+	</listitem>
+	<listitem><para id="x_4eb"><envar role="rc-item-web">allowpull</envar>:
+	    Boolean.  Determines whether the web interface allows
+	    remote users to <command role="hg-cmd">hg pull</command>
+	    and <command role="hg-cmd">hg clone</command> this
+	    repository over HTTP.  If set to <literal>no</literal> or
+	    <literal>false</literal>, only the
+	    <quote>human-oriented</quote> portion of the web interface
+	    is available.</para>
+	</listitem>
+	<listitem><para id="x_4ec"><envar role="rc-item-web">contact</envar>:
+	    String.  A free-form (but preferably brief) string
+	    identifying the person or group in charge of the
+	    repository.  This often contains the name and email
+	    address of a person or mailing list.  It often makes sense
+	    to place this entry in a repository's own <filename
+	      role="special">.hg/hgrc</filename> file, but it can make
+	    sense to use in a global <filename
+	      role="special">~/.hgrc</filename> if every repository
+	    has a single maintainer.</para>
+	</listitem>
+	<listitem><para id="x_4ed"><envar role="rc-item-web">maxchanges</envar>:
+	    Integer.  The default maximum number of changesets to
+	    display in a single page of output.</para>
+	</listitem>
+	<listitem><para id="x_4ee"><envar role="rc-item-web">maxfiles</envar>:
+	    Integer.  The default maximum number of modified files to
+	    display in a single page of output.</para>
+	</listitem>
+	<listitem><para id="x_4ef"><envar role="rc-item-web">stripes</envar>:
+	    Integer.  If the web interface displays alternating
+	    <quote>stripes</quote> to make it easier to visually align
+	    rows when you are looking at a table, this number controls
+	    the number of rows in each stripe.</para>
+	</listitem>
+	<listitem><para id="x_4f0"><envar
+	      role="rc-item-web">style</envar>: Controls the template
+	    Mercurial uses to display the web interface.  Mercurial
+	    ships with several web templates.</para>
+	  <itemizedlist>
+	    <listitem>
+	      <para id="x_6aa"><literal>coal</literal> is monochromatic.</para>
+	    </listitem>
+	    <listitem>
+	      <para id="x_6ab"><literal>gitweb</literal> emulates the visual
+		style of git's web interface.</para>
+	    </listitem>
+	    <listitem>
+	      <para id="x_6ac"><literal>monoblue</literal> uses solid blues and
+		greys.</para>
+	    </listitem>
+	    <listitem>
+	      <para id="x_6ad"><literal>paper</literal> is the default.</para>
+	    </listitem>
+	    <listitem>
+	      <para id="x_6ae"><literal>spartan</literal> was the default for a
+		long time.</para>
+	    </listitem>
+	  </itemizedlist>
+	  <para id="x_6af">You can
+	    also specify a custom template of your own; see 
+	    <xref linkend="chap:template"/> for details. Here, you can
+	    see how to enable the <literal>gitweb</literal>
+	    style.</para>
+	  <programlisting>[web]
+style = gitweb</programlisting>
+	</listitem>
+	<listitem><para id="x_4f1"><envar role="rc-item-web">templates</envar>:
+	    Path.  The directory in which to search for template
+	    files.  By default, Mercurial searches in the directory in
+	    which it was installed.</para>
+	</listitem></itemizedlist>
+      <para id="x_4f2">If you are using <filename
+	  role="special">hgwebdir.cgi</filename>, you can place a few
+	configuration items in a <literal role="rc-web">web</literal>
+	section of the <filename
+	  role="special">hgweb.config</filename> file instead of a
+	<filename role="special">~/.hgrc</filename> file, for
+	convenience.  These items are <envar
+	  role="rc-item-web">motd</envar> and <envar
+	  role="rc-item-web">style</envar>.</para>
+
+      <sect3>
+	<title>Options specific to an individual repository</title>
+
+	<para id="x_4f3">A few <literal role="rc-web">web</literal> configuration
+	  items ought to be placed in a repository's local <filename
+	    role="special">.hg/hgrc</filename>, rather than a user's
+	  or global <filename role="special">~/.hgrc</filename>.</para>
+	<itemizedlist>
+	  <listitem><para id="x_4f4"><envar
+		role="rc-item-web">description</envar>: String.  A
+	      free-form (but preferably brief) string that describes
+	      the contents or purpose of the repository.</para>
+	  </listitem>
+	  <listitem><para id="x_4f5"><envar role="rc-item-web">name</envar>:
+	      String.  The name to use for the repository in the web
+	      interface.  This overrides the default name, which is
+	      the last component of the repository's path.</para>
+	  </listitem></itemizedlist>
+      </sect3>
+
+      <sect3>
+	<title>Options specific to the <command role="hg-cmd">hg
+	    serve</command> command</title>
+
+	<para id="x_4f6">Some of the items in the <literal
+	    role="rc-web">web</literal> section of a <filename
+	    role="special">~/.hgrc</filename> file are only for use
+	  with the <command role="hg-cmd">hg serve</command>
+	  command.</para>
+	<itemizedlist>
+	  <listitem><para id="x_4f7"><envar role="rc-item-web">accesslog</envar>:
+	      Path.  The name of a file into which to write an access
+	      log.  By default, the <command role="hg-cmd">hg
+		serve</command> command writes this information to
+	      standard output, not to a file.  Log entries are written
+	      in the standard <quote>combined</quote> file format used
+	      by almost all web servers.</para>
+	  </listitem>
+	  <listitem><para id="x_4f8"><envar role="rc-item-web">address</envar>:
+	      String.  The local address on which the server should
+	      listen for incoming connections.  By default, the server
+	      listens on all addresses.</para>
+	  </listitem>
+	  <listitem><para id="x_4f9"><envar role="rc-item-web">errorlog</envar>:
+	      Path.  The name of a file into which to write an error
+	      log.  By default, the <command role="hg-cmd">hg
+		serve</command> command writes this information to
+	      standard error, not to a file.</para>
+	  </listitem>
+	  <listitem><para id="x_4fa"><envar role="rc-item-web">ipv6</envar>:
+	      Boolean.  Whether to use the IPv6 protocol. By default,
+	      IPv6 is not used.</para>
+	  </listitem>
+	  <listitem><para id="x_4fb"><envar role="rc-item-web">port</envar>:
+	      Integer.  The TCP port number on which the server should
+	      listen.  The default port number used is 8000.</para>
+	  </listitem></itemizedlist>
+      </sect3>
+
+      <sect3>
+	<title>Choosing the right <filename
+	    role="special">~/.hgrc</filename> file to add <literal
+	    role="rc-web">web</literal> items to</title>
+
+	<para id="x_4fc">It is important to remember that a web server like
+	  Apache or <literal>lighttpd</literal> will run under a user
+	  ID that is different to yours. CGI scripts run by your
+	  server, such as <filename
+	    role="special">hgweb.cgi</filename>, will usually also run
+	  under that user ID.</para>
+
+	<para id="x_4fd">If you add <literal role="rc-web">web</literal> items to
+	  your own personal <filename role="special">~/.hgrc</filename> file, CGI scripts won't read that
+	  <filename role="special">~/.hgrc</filename> file.  Those
+	  settings will thus only affect the behavior of the <command
+	    role="hg-cmd">hg serve</command> command when you run it.
+	  To cause CGI scripts to see your settings, either create a
+	  <filename role="special">~/.hgrc</filename> file in the
+	  home directory of the user ID that runs your web server, or
+	  add those settings to a system-wide <filename
+	    role="special">hgrc</filename> file.</para>
+      </sect3>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>System-wide configuration</title>
+
+    <para id="x_6b0">On Unix-like systems shared by multiple users (such as a
+      server to which people publish changes), it often makes sense to
+      set up some global default behaviors, such as what theme to use
+      in web interfaces.</para>
+
+    <para id="x_6b1">If a file named <filename>/etc/mercurial/hgrc</filename>
+      exists, Mercurial will read it at startup time and apply any
+      configuration settings it finds in that file.  It will also look
+      for files ending in a <literal>.rc</literal> extension in a
+      directory named <filename>/etc/mercurial/hgrc.d</filename>, and
+      apply any configuration settings it finds in each of those
+      files.</para>
+
+    <sect2>
+      <title>Making Mercurial more trusting</title>
+
+      <para id="x_6b2">One situation in which a global <filename>hgrc</filename>
+	can be useful is if users are pulling changes owned by other
+	users.  By default, Mercurial will not trust most of the
+	configuration items in a <filename>.hg/hgrc</filename> file
+	inside a repository that is owned by a different user. If we
+	clone or pull changes from such a repository, Mercurial will
+	print a warning stating that it does not trust their
+	<filename>.hg/hgrc</filename>.</para>
+
+      <para id="x_6b3">If everyone in a particular Unix group is on the same team
+	and <emphasis>should</emphasis> trust each other's
+	configuration settings, or we want to trust particular users,
+	we can override Mercurial's skeptical defaults by creating a
+	system-wide <filename>hgrc</filename> file such as the
+	following:</para>
+
+    <programlisting># Save this as e.g. /etc/mercurial/hgrc.d/trust.rc
+[trusted]
+# Trust all entries in any hgrc file owned by the "editors" or
+# "www-data" groups.
+groups = editors, www-data
+
+# Trust entries in hgrc files owned by the following users.
+users = apache, bobo
+</programlisting>
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- a/en/ch06-filenames.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,451 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:names">
-  <?dbhtml filename="file-names-and-pattern-matching.html"?>
-  <title>File names and pattern matching</title>
-
-  <para id="x_543">Mercurial provides mechanisms that let you work with file
-    names in a consistent and expressive way.</para>
-
-  <sect1>
-    <title>Simple file naming</title>
-
-    <para id="x_544">Mercurial uses a unified piece of machinery <quote>under the
-	hood</quote> to handle file names.  Every command behaves
-      uniformly with respect to file names.  The way in which commands
-      work with file names is as follows.</para>
-
-    <para id="x_545">If you explicitly name real files on the command line,
-      Mercurial works with exactly those files, as you would expect.
-      &interaction.filenames.files;</para>
-
-    <para id="x_546">When you provide a directory name, Mercurial will interpret
-      this as <quote>operate on every file in this directory and its
-	subdirectories</quote>. Mercurial traverses the files and
-      subdirectories in a directory in alphabetical order.  When it
-      encounters a subdirectory, it will traverse that subdirectory
-      before continuing with the current directory.</para>
-
-      &interaction.filenames.dirs;
-  </sect1>
-
-  <sect1>
-    <title>Running commands without any file names</title>
-
-    <para id="x_547">Mercurial's commands that work with file names have useful
-      default behaviors when you invoke them without providing any
-      file names or patterns.  What kind of behavior you should
-      expect depends on what the command does.  Here are a few rules
-      of thumb you can use to predict what a command is likely to do
-      if you don't give it any names to work with.</para>
-    <itemizedlist>
-      <listitem><para id="x_548">Most commands will operate on the entire working
-	  directory. This is what the <command role="hg-cmd">hg
-	    add</command> command does, for example.</para>
-      </listitem>
-      <listitem><para id="x_549">If the command has effects that are difficult or
-	  impossible to reverse, it will force you to explicitly
-	  provide at least one name or pattern (see below).  This
-	  protects you from accidentally deleting files by running
-	  <command role="hg-cmd">hg remove</command> with no
-	  arguments, for example.</para>
-      </listitem></itemizedlist>
-
-    <para id="x_54a">It's easy to work around these default behaviors if they
-      don't suit you.  If a command normally operates on the whole
-      working directory, you can invoke it on just the current
-      directory and its subdirectories by giving it the name
-      <quote><filename class="directory">.</filename></quote>.</para>
-
-    &interaction.filenames.wdir-subdir;
-
-    <para id="x_54b">Along the same lines, some commands normally print file
-      names relative to the root of the repository, even if you're
-      invoking them from a subdirectory.  Such a command will print
-      file names relative to your subdirectory if you give it explicit
-      names.  Here, we're going to run <command role="hg-cmd">hg
-	status</command> from a subdirectory, and get it to operate on
-      the entire working directory while printing file names relative
-      to our subdirectory, by passing it the output of the <command
-	role="hg-cmd">hg root</command> command.</para>
-
-      &interaction.filenames.wdir-relname;
-  </sect1>
-
-  <sect1>
-    <title>Telling you what's going on</title>
-
-    <para id="x_54c">The <command role="hg-cmd">hg add</command> example in the
-      preceding section illustrates something else that's helpful
-      about Mercurial commands.  If a command operates on a file that
-      you didn't name explicitly on the command line, it will usually
-      print the name of the file, so that you will not be surprised
-      what's going on.</para>
-
-    <para id="x_54d">The principle here is of <emphasis>least
-	surprise</emphasis>.  If you've exactly named a file on the
-      command line, there's no point in repeating it back at you.  If
-      Mercurial is acting on a file <emphasis>implicitly</emphasis>, e.g.
-      because you provided no names, or a directory, or a pattern (see
-      below), it is safest to tell you what files it's operating on.</para>
-
-    <para id="x_54e">For commands that behave this way, you can silence them
-      using the <option role="hg-opt-global">-q</option> option.  You
-      can also get them to print the name of every file, even those
-      you've named explicitly, using the <option
-	role="hg-opt-global">-v</option> option.</para>
-  </sect1>
-
-  <sect1>
-    <title>Using patterns to identify files</title>
-
-    <para id="x_54f">In addition to working with file and directory names,
-      Mercurial lets you use <emphasis>patterns</emphasis> to identify
-      files.  Mercurial's pattern handling is expressive.</para>
-
-    <para id="x_550">On Unix-like systems (Linux, MacOS, etc.), the job of
-      matching file names to patterns normally falls to the shell.  On
-      these systems, you must explicitly tell Mercurial that a name is
-      a pattern.  On Windows, the shell does not expand patterns, so
-      Mercurial will automatically identify names that are patterns,
-      and expand them for you.</para>
-
-    <para id="x_551">To provide a pattern in place of a regular name on the
-      command line, the mechanism is simple:</para>
-    <programlisting>syntax:patternbody</programlisting>
-    <para id="x_552">That is, a pattern is identified by a short text string that
-      says what kind of pattern this is, followed by a colon, followed
-      by the actual pattern.</para>
-
-    <para id="x_553">Mercurial supports two kinds of pattern syntax.  The most
-      frequently used is called <literal>glob</literal>; this is the
-      same kind of pattern matching used by the Unix shell, and should
-      be familiar to Windows command prompt users, too.</para>
-
-    <para id="x_554">When Mercurial does automatic pattern matching on Windows,
-      it uses <literal>glob</literal> syntax.  You can thus omit the
-      <quote><literal>glob:</literal></quote> prefix on Windows, but
-      it's safe to use it, too.</para>
-
-    <para id="x_555">The <literal>re</literal> syntax is more powerful; it lets
-      you specify patterns using regular expressions, also known as
-      regexps.</para>
-
-    <para id="x_556">By the way, in the examples that follow, notice that I'm
-      careful to wrap all of my patterns in quote characters, so that
-      they won't get expanded by the shell before Mercurial sees
-      them.</para>
-
-    <sect2>
-      <title>Shell-style <literal>glob</literal> patterns</title>
-
-      <para id="x_557">This is an overview of the kinds of patterns you can use
-	when you're matching on glob patterns.</para>
-
-      <para id="x_558">The <quote><literal>*</literal></quote> character matches
-	any string, within a single directory.</para>
-
-      &interaction.filenames.glob.star;
-
-      <para id="x_559">The <quote><literal>**</literal></quote> pattern matches
-	any string, and crosses directory boundaries.  It's not a
-	standard Unix glob token, but it's accepted by several popular
-	Unix shells, and is very useful.</para>
-
-      &interaction.filenames.glob.starstar;
-
-      <para id="x_55a">The <quote><literal>?</literal></quote> pattern matches
-	any single character.</para>
-
-      &interaction.filenames.glob.question;
-
-      <para id="x_55b">The <quote><literal>[</literal></quote> character begins a
-	<emphasis>character class</emphasis>.  This matches any single
-	character within the class.  The class ends with a
-	<quote><literal>]</literal></quote> character.  A class may
-	contain multiple <emphasis>range</emphasis>s of the form
-	<quote><literal>a-f</literal></quote>, which is shorthand for
-	<quote><literal>abcdef</literal></quote>.</para>
-
-	&interaction.filenames.glob.range;
-
-      <para id="x_55c">If the first character after the
-	<quote><literal>[</literal></quote> in a character class is a
-	<quote><literal>!</literal></quote>, it
-	<emphasis>negates</emphasis> the class, making it match any
-	single character not in the class.</para>
-
-      <para id="x_55d">A <quote><literal>{</literal></quote> begins a group of
-	subpatterns, where the whole group matches if any subpattern
-	in the group matches.  The <quote><literal>,</literal></quote>
-	character separates subpatterns, and
-	<quote><literal>}</literal></quote> ends the group.</para>
-
-      &interaction.filenames.glob.group;
-
-      <sect3>
-	<title>Watch out!</title>
-
-	<para id="x_55e">Don't forget that if you want to match a pattern in any
-	  directory, you should not be using the
-	  <quote><literal>*</literal></quote> match-any token, as this
-	  will only match within one directory.  Instead, use the
-	  <quote><literal>**</literal></quote> token.  This small
-	  example illustrates the difference between the two.</para>
-
-	  &interaction.filenames.glob.star-starstar;
-      </sect3>
-    </sect2>
-
-    <sect2>
-      <title>Regular expression matching with <literal>re</literal>
-	patterns</title>
-
-      <para id="x_55f">Mercurial accepts the same regular expression syntax as
-	the Python programming language (it uses Python's regexp
-	engine internally). This is based on the Perl language's
-	regexp syntax, which is the most popular dialect in use (it's
-	also used in Java, for example).</para>
-
-      <para id="x_560">I won't discuss Mercurial's regexp dialect in any detail
-	here, as regexps are not often used.  Perl-style regexps are
-	in any case already exhaustively documented on a multitude of
-	web sites, and in many books.  Instead, I will focus here on a
-	few things you should know if you find yourself needing to use
-	regexps with Mercurial.</para>
-
-      <para id="x_561">A regexp is matched against an entire file name, relative
-	to the root of the repository.  In other words, even if you're
-	already in subbdirectory <filename
-	  class="directory">foo</filename>, if you want to match files
-	under this directory, your pattern must start with
-	<quote><literal>foo/</literal></quote>.</para>
-
-      <para id="x_562">One thing to note, if you're familiar with Perl-style
-	regexps, is that Mercurial's are <emphasis>rooted</emphasis>.
-	That is, a regexp starts matching against the beginning of a
-	string; it doesn't look for a match anywhere within the
-	string.  To match anywhere in a string, start your pattern
-	with <quote><literal>.*</literal></quote>.</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>Filtering files</title>
-
-    <para id="x_563">Not only does Mercurial give you a variety of ways to
-      specify files; it lets you further winnow those files using
-      <emphasis>filters</emphasis>.  Commands that work with file
-      names accept two filtering options.</para>
-    <itemizedlist>
-      <listitem><para id="x_564"><option role="hg-opt-global">-I</option>, or
-	  <option role="hg-opt-global">--include</option>, lets you
-	  specify a pattern that file names must match in order to be
-	  processed.</para>
-      </listitem>
-      <listitem><para id="x_565"><option role="hg-opt-global">-X</option>, or
-	  <option role="hg-opt-global">--exclude</option>, gives you a
-	  way to <emphasis>avoid</emphasis> processing files, if they
-	  match this pattern.</para>
-      </listitem></itemizedlist>
-    <para id="x_566">You can provide multiple <option
-	role="hg-opt-global">-I</option> and <option
-	role="hg-opt-global">-X</option> options on the command line,
-      and intermix them as you please.  Mercurial interprets the
-      patterns you provide using glob syntax by default (but you can
-      use regexps if you need to).</para>
-
-    <para id="x_567">You can read a <option role="hg-opt-global">-I</option>
-      filter as <quote>process only the files that match this
-	filter</quote>.</para>
-
-    &interaction.filenames.filter.include;
-
-    <para id="x_568">The <option role="hg-opt-global">-X</option> filter is best
-      read as <quote>process only the files that don't match this
-	pattern</quote>.</para>
-
-    &interaction.filenames.filter.exclude;
-  </sect1>
-
-  <sect1>
-    <title>Permanently ignoring unwanted files and directories</title>
-
-    <para id="x_569">When you create a new repository, the chances are
-      that over time it will grow to contain files that ought to
-      <emphasis>not</emphasis> be managed by Mercurial, but which you
-      don't want to see listed every time you run <command>hg
-	status</command>.  For instance, <quote>build products</quote>
-      are files that are created as part of a build but which should
-      not be managed by a revision control system.  The most common
-      build products are output files produced by software tools such
-      as compilers.  As another example, many text editors litter a
-      directory with lock files, temporary working files, and backup
-      files, which it also makes no sense to manage.</para>
-
-    <para id="x_6b4">To have Mercurial permanently ignore such files, create a
-      file named <filename>.hgignore</filename> in the root of your
-      repository.  You <emphasis>should</emphasis> <command>hg
-      add</command> this file so that it gets tracked with the rest of
-      your repository contents, since your collaborators will probably
-      find it useful too.</para>
-
-    <para id="x_6b5">By default, the <filename>.hgignore</filename> file should
-      contain a list of regular expressions, one per line.  Empty
-      lines are skipped. Most people prefer to describe the files they
-      want to ignore using the <quote>glob</quote> syntax that we
-      described above, so a typical <filename>.hgignore</filename>
-      file will start with this directive:</para>
-
-    <programlisting>syntax: glob</programlisting>
-
-    <para id="x_6b6">This tells Mercurial to interpret the lines that follow as
-      glob patterns, not regular expressions.</para>
-
-    <para id="x_6b7">Here is a typical-looking <filename>.hgignore</filename>
-      file.</para>
-
-    <programlisting>syntax: glob
-# This line is a comment, and will be skipped.
-# Empty lines are skipped too.
-
-# Backup files left behind by the Emacs editor.
-*~
-
-# Lock files used by the Emacs editor.
-# Notice that the "#" character is quoted with a backslash.
-# This prevents it from being interpreted as starting a comment.
-.\#*
-
-# Temporary files used by the vim editor.
-.*.swp
-
-# A hidden file created by the Mac OS X Finder.
-.DS_Store
-</programlisting>
-  </sect1>
-
-  <sect1 id="sec:names:case">
-    <title>Case sensitivity</title>
-
-    <para id="x_56a">If you're working in a mixed development environment that
-      contains both Linux (or other Unix) systems and Macs or Windows
-      systems, you should keep in the back of your mind the knowledge
-      that they treat the case (<quote>N</quote> versus
-      <quote>n</quote>) of file names in incompatible ways.  This is
-      not very likely to affect you, and it's easy to deal with if it
-      does, but it could surprise you if you don't know about
-      it.</para>
-
-    <para id="x_56b">Operating systems and filesystems differ in the way they
-      handle the <emphasis>case</emphasis> of characters in file and
-      directory names.  There are three common ways to handle case in
-      names.</para>
-    <itemizedlist>
-      <listitem><para id="x_56c">Completely case insensitive.  Uppercase and
-	  lowercase versions of a letter are treated as identical,
-	  both when creating a file and during subsequent accesses.
-	  This is common on older DOS-based systems.</para>
-      </listitem>
-      <listitem><para id="x_56d">Case preserving, but insensitive.  When a file
-	  or directory is created, the case of its name is stored, and
-	  can be retrieved and displayed by the operating system.
-	  When an existing file is being looked up, its case is
-	  ignored.  This is the standard arrangement on Windows and
-	  MacOS.  The names <filename>foo</filename> and
-	  <filename>FoO</filename> identify the same file.  This
-	  treatment of uppercase and lowercase letters as
-	  interchangeable is also referred to as <emphasis>case
-	    folding</emphasis>.</para>
-      </listitem>
-      <listitem><para id="x_56e">Case sensitive.  The case of a name
-	  is significant at all times. The names
-	  <filename>foo</filename> and <filename>FoO</filename>
-	  identify different files.  This is the way Linux and Unix
-	  systems normally work.</para>
-      </listitem></itemizedlist>
-
-    <para id="x_56f">On Unix-like systems, it is possible to have any or all of
-      the above ways of handling case in action at once.  For example,
-      if you use a USB thumb drive formatted with a FAT32 filesystem
-      on a Linux system, Linux will handle names on that filesystem in
-      a case preserving, but insensitive, way.</para>
-
-    <sect2>
-      <title>Safe, portable repository storage</title>
-
-      <para id="x_570">Mercurial's repository storage mechanism is <emphasis>case
-	  safe</emphasis>.  It translates file names so that they can
-	be safely stored on both case sensitive and case insensitive
-	filesystems.  This means that you can use normal file copying
-	tools to transfer a Mercurial repository onto, for example, a
-	USB thumb drive, and safely move that drive and repository
-	back and forth between a Mac, a PC running Windows, and a
-	Linux box.</para>
-
-    </sect2>
-    <sect2>
-      <title>Detecting case conflicts</title>
-
-      <para id="x_571">When operating in the working directory, Mercurial honours
-	the naming policy of the filesystem where the working
-	directory is located.  If the filesystem is case preserving,
-	but insensitive, Mercurial will treat names that differ only
-	in case as the same.</para>
-
-      <para id="x_572">An important aspect of this approach is that it is
-	possible to commit a changeset on a case sensitive (typically
-	Linux or Unix) filesystem that will cause trouble for users on
-	case insensitive (usually Windows and MacOS) users.  If a
-	Linux user commits changes to two files, one named
-	<filename>myfile.c</filename> and the other named
-	<filename>MyFile.C</filename>, they will be stored correctly
-	in the repository.  And in the working directories of other
-	Linux users, they will be correctly represented as separate
-	files.</para>
-
-      <para id="x_573">If a Windows or Mac user pulls this change, they will not
-	initially have a problem, because Mercurial's repository
-	storage mechanism is case safe.  However, once they try to
-	<command role="hg-cmd">hg update</command> the working
-	directory to that changeset, or <command role="hg-cmd">hg
-	  merge</command> with that changeset, Mercurial will spot the
-	conflict between the two file names that the filesystem would
-	treat as the same, and forbid the update or merge from
-	occurring.</para>
-    </sect2>
-
-    <sect2>
-      <title>Fixing a case conflict</title>
-
-      <para id="x_574">If you are using Windows or a Mac in a mixed environment
-	where some of your collaborators are using Linux or Unix, and
-	Mercurial reports a case folding conflict when you try to
-	<command role="hg-cmd">hg update</command> or <command
-	  role="hg-cmd">hg merge</command>, the procedure to fix the
-	problem is simple.</para>
-
-      <para id="x_575">Just find a nearby Linux or Unix box, clone the problem
-	repository onto it, and use Mercurial's <command
-	  role="hg-cmd">hg rename</command> command to change the
-	names of any offending files or directories so that they will
-	no longer cause case folding conflicts.  Commit this change,
-	<command role="hg-cmd">hg pull</command> or <command
-	  role="hg-cmd">hg push</command> it across to your Windows or
-	MacOS system, and <command role="hg-cmd">hg update</command>
-	to the revision with the non-conflicting names.</para>
-
-      <para id="x_576">The changeset with case-conflicting names will remain in
-	your project's history, and you still won't be able to
-	<command role="hg-cmd">hg update</command> your working
-	directory to that changeset on a Windows or MacOS system, but
-	you can continue development unimpeded.</para>
-    </sect2>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- a/en/ch07-branch.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,533 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:branch">
-  <?dbhtml filename="managing-releases-and-branchy-development.html"?>
-  <title>Managing releases and branchy development</title>
-
-  <para id="x_369">Mercurial provides several mechanisms for you to manage a
-    project that is making progress on multiple fronts at once.  To
-    understand these mechanisms, let's first take a brief look at a
-    fairly normal software project structure.</para>
-
-  <para id="x_36a">Many software projects issue periodic <quote>major</quote>
-    releases that contain substantial new features.  In parallel, they
-    may issue <quote>minor</quote> releases.  These are usually
-    identical to the major releases off which they're based, but with
-    a few bugs fixed.</para>
-
-  <para id="x_36b">In this chapter, we'll start by talking about how to keep
-    records of project milestones such as releases.  We'll then
-    continue on to talk about the flow of work between different
-    phases of a project, and how Mercurial can help you to isolate and
-    manage this work.</para>
-
-  <sect1>
-    <title>Giving a persistent name to a revision</title>
-
-    <para id="x_36c">Once you decide that you'd like to call a particular
-      revision a <quote>release</quote>, it's a good idea to record
-      the identity of that revision. This will let you reproduce that
-      release at a later date, for whatever purpose you might need at
-      the time (reproducing a bug, porting to a new platform, etc).
-      &interaction.tag.init;</para>
-
-    <para id="x_36d">Mercurial lets you give a permanent name to any revision
-      using the <command role="hg-cmd">hg tag</command> command.  Not
-      surprisingly, these names are called <quote>tags</quote>.</para>
-
-    &interaction.tag.tag;
-
-    <para id="x_36e">A tag is nothing more than a <quote>symbolic name</quote>
-      for a revision.  Tags exist purely for your convenience, so that
-      you have a handy permanent way to refer to a revision; Mercurial
-      doesn't interpret the tag names you use in any way.  Neither
-      does Mercurial place any restrictions on the name of a tag,
-      beyond a few that are necessary to ensure that a tag can be
-      parsed unambiguously.  A tag name cannot contain any of the
-      following characters:</para>
-    <itemizedlist>
-      <listitem><para id="x_36f">Colon (ASCII 58,
-	  <quote><literal>:</literal></quote>)</para>
-      </listitem>
-      <listitem><para id="x_370">Carriage return (ASCII 13,
-	  <quote><literal>\r</literal></quote>)</para>
-      </listitem>
-      <listitem><para id="x_371">Newline (ASCII 10,
-	  <quote><literal>\n</literal></quote>)</para>
-      </listitem></itemizedlist>
-
-    <para id="x_372">You can use the <command role="hg-cmd">hg tags</command>
-      command to display the tags present in your repository.  In the
-      output, each tagged revision is identified first by its name,
-      then by revision number, and finally by the unique hash of the
-      revision.</para>
-
-    &interaction.tag.tags;
-
-    <para id="x_373">Notice that <literal>tip</literal> is listed in the output
-      of <command role="hg-cmd">hg tags</command>.  The
-      <literal>tip</literal> tag is a special <quote>floating</quote>
-      tag, which always identifies the newest revision in the
-      repository.</para>
-
-    <para id="x_374">In the output of the <command role="hg-cmd">hg
-	tags</command> command, tags are listed in reverse order, by
-      revision number.  This usually means that recent tags are listed
-      before older tags.  It also means that <literal>tip</literal> is
-      always going to be the first tag listed in the output of
-      <command role="hg-cmd">hg tags</command>.</para>
-
-    <para id="x_375">When you run <command role="hg-cmd">hg log</command>, if it
-      displays a revision that has tags associated with it, it will
-      print those tags.</para>
-
-    &interaction.tag.log;
-
-    <para id="x_376">Any time you need to provide a revision ID to a Mercurial
-      command, the command will accept a tag name in its place.
-      Internally, Mercurial will translate your tag name into the
-      corresponding revision ID, then use that.</para>
-
-    &interaction.tag.log.v1.0;
-
-    <para id="x_377">There's no limit on the number of tags you can have in a
-      repository, or on the number of tags that a single revision can
-      have.  As a practical matter, it's not a great idea to have
-      <quote>too many</quote> (a number which will vary from project
-      to project), simply because tags are supposed to help you to
-      find revisions.  If you have lots of tags, the ease of using
-      them to identify revisions diminishes rapidly.</para>
-
-    <para id="x_378">For example, if your project has milestones as frequent as
-      every few days, it's perfectly reasonable to tag each one of
-      those.  But if you have a continuous build system that makes
-      sure every revision can be built cleanly, you'd be introducing a
-      lot of noise if you were to tag every clean build.  Instead, you
-      could tag failed builds (on the assumption that they're rare!),
-      or simply not use tags to track buildability.</para>
-
-    <para id="x_379">If you want to remove a tag that you no longer want, use
-      <command role="hg-cmd">hg tag --remove</command>.</para>
-
-    &interaction.tag.remove;
-
-    <para id="x_37a">You can also modify a tag at any time, so that it identifies
-      a different revision, by simply issuing a new <command
-	role="hg-cmd">hg tag</command> command. You'll have to use the
-      <option role="hg-opt-tag">-f</option> option to tell Mercurial
-      that you <emphasis>really</emphasis> want to update the
-      tag.</para>
-
-    &interaction.tag.replace;
-
-    <para id="x_37b">There will still be a permanent record of the previous
-      identity of the tag, but Mercurial will no longer use it.
-      There's thus no penalty to tagging the wrong revision; all you
-      have to do is turn around and tag the correct revision once you
-      discover your error.</para>
-
-    <para id="x_37c">Mercurial stores tags in a normal revision-controlled file
-      in your repository.  If you've created any tags, you'll find
-      them in a file in the root of your repository named <filename
-	role="special">.hgtags</filename>.  When you run the <command
-	role="hg-cmd">hg tag</command> command, Mercurial modifies
-      this file, then automatically commits the change to it.  This
-      means that every time you run <command role="hg-cmd">hg
-	tag</command>, you'll see a corresponding changeset in the
-      output of <command role="hg-cmd">hg log</command>.</para>
-
-    &interaction.tag.tip;
-
-    <sect2>
-      <title>Handling tag conflicts during a merge</title>
-
-      <para id="x_37d">You won't often need to care about the <filename
-	  role="special">.hgtags</filename> file, but it sometimes
-	makes its presence known during a merge.  The format of the
-	file is simple: it consists of a series of lines.  Each line
-	starts with a changeset hash, followed by a space, followed by
-	the name of a tag.</para>
-
-      <para id="x_37e">If you're resolving a conflict in the <filename
-	  role="special">.hgtags</filename> file during a merge,
-	there's one twist to modifying the <filename
-	  role="special">.hgtags</filename> file: when Mercurial is
-	parsing the tags in a repository, it
-	<emphasis>never</emphasis> reads the working copy of the
-	<filename role="special">.hgtags</filename> file.  Instead, it
-	reads the <emphasis>most recently committed</emphasis>
-	revision of the file.</para>
-
-      <para id="x_37f">An unfortunate consequence of this design is that you
-	can't actually verify that your merged <filename
-	  role="special">.hgtags</filename> file is correct until
-	<emphasis>after</emphasis> you've committed a change.  So if
-	you find yourself resolving a conflict on <filename
-	  role="special">.hgtags</filename> during a merge, be sure to
-	run <command role="hg-cmd">hg tags</command> after you commit.
-	If it finds an error in the <filename
-	  role="special">.hgtags</filename> file, it will report the
-	location of the error, which you can then fix and commit.  You
-	should then run <command role="hg-cmd">hg tags</command>
-	again, just to be sure that your fix is correct.</para>
-    </sect2>
-
-    <sect2>
-      <title>Tags and cloning</title>
-
-      <para id="x_380">You may have noticed that the <command role="hg-cmd">hg
-	  clone</command> command has a <option
-	  role="hg-opt-clone">-r</option> option that lets you clone
-	an exact copy of the repository as of a particular changeset.
-	The new clone will not contain any project history that comes
-	after the revision you specified.  This has an interaction
-	with tags that can surprise the unwary.</para>
-
-      <para id="x_381">Recall that a tag is stored as a revision to
-	the <filename role="special">.hgtags</filename> file. When you
-	create a tag, the changeset in which its recorded refers to an
-	older changeset.  When you run <command role="hg-cmd">hg clone
-	  -r foo</command> to clone a repository as of tag
-	<literal>foo</literal>, the new clone <emphasis>will not
-	  contain any revision newer than the one the tag refers to,
-	  including the revision where the tag was created</emphasis>.
-	The result is that you'll get exactly the right subset of the
-	project's history in the new repository, but
-	<emphasis>not</emphasis> the tag you might have
-	expected.</para>
-    </sect2>
-
-    <sect2>
-      <title>When permanent tags are too much</title>
-
-      <para id="x_382">Since Mercurial's tags are revision controlled and carried
-	around with a project's history, everyone you work with will
-	see the tags you create.  But giving names to revisions has
-	uses beyond simply noting that revision
-	<literal>4237e45506ee</literal> is really
-	<literal>v2.0.2</literal>.  If you're trying to track down a
-	subtle bug, you might want a tag to remind you of something
-	like <quote>Anne saw the symptoms with this
-	  revision</quote>.</para>
-
-      <para id="x_383">For cases like this, what you might want to use are
-	<emphasis>local</emphasis> tags. You can create a local tag
-	with the <option role="hg-opt-tag">-l</option> option to the
-	<command role="hg-cmd">hg tag</command> command.  This will
-	store the tag in a file called <filename
-	  role="special">.hg/localtags</filename>.  Unlike <filename
-	  role="special">.hgtags</filename>, <filename
-	  role="special">.hg/localtags</filename> is not revision
-	controlled.  Any tags you create using <option
-	  role="hg-opt-tag">-l</option> remain strictly local to the
-	repository you're currently working in.</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>The flow of changes&emdash;big picture vs. little</title>
-
-    <para id="x_384">To return to the outline I sketched at the
-      beginning of the chapter, let's think about a project that has
-      multiple concurrent pieces of work under development at
-      once.</para>
-
-    <para id="x_385">There might be a push for a new <quote>main</quote> release;
-      a new minor bugfix release to the last main release; and an
-      unexpected <quote>hot fix</quote> to an old release that is now
-      in maintenance mode.</para>
-
-    <para id="x_386">The usual way people refer to these different concurrent
-      directions of development is as <quote>branches</quote>.
-      However, we've already seen numerous times that Mercurial treats
-      <emphasis>all of history</emphasis> as a series of branches and
-      merges.  Really, what we have here is two ideas that are
-      peripherally related, but which happen to share a name.</para>
-    <itemizedlist>
-      <listitem><para id="x_387"><quote>Big picture</quote> branches represent
-	  the sweep of a project's evolution; people give them names,
-	  and talk about them in conversation.</para>
-      </listitem>
-      <listitem><para id="x_388"><quote>Little picture</quote> branches are
-	  artefacts of the day-to-day activity of developing and
-	  merging changes.  They expose the narrative of how the code
-	  was developed.</para>
-      </listitem></itemizedlist>
-  </sect1>
-
-  <sect1>
-    <title>Managing big-picture branches in repositories</title>
-
-    <para id="x_389">The easiest way to isolate a <quote>big picture</quote>
-      branch in Mercurial is in a dedicated repository.  If you have
-      an existing shared repository&emdash;let's call it
-      <literal>myproject</literal>&emdash;that reaches a
-      <quote>1.0</quote> milestone, you can start to prepare for
-      future maintenance releases on top of version 1.0 by tagging the
-      revision from which you prepared the 1.0 release.</para>
-
-    &interaction.branch-repo.tag;
-
-    <para id="x_38a">You can then clone a new shared
-      <literal>myproject-1.0.1</literal> repository as of that
-      tag.</para>
-
-    &interaction.branch-repo.clone;
-
-    <para id="x_38b">Afterwards, if someone needs to work on a bug fix that ought
-      to go into an upcoming 1.0.1 minor release, they clone the
-      <literal>myproject-1.0.1</literal> repository, make their
-      changes, and push them back.</para>
-
-    &interaction.branch-repo.bugfix;
-
-    <para id="x_38c">Meanwhile, development for
-      the next major release can continue, isolated and unabated, in
-      the <literal>myproject</literal> repository.</para>
-
-    &interaction.branch-repo.new;
-  </sect1>
-
-  <sect1>
-    <title>Don't repeat yourself: merging across branches</title>
-
-    <para id="x_38d">In many cases, if you have a bug to fix on a maintenance
-      branch, the chances are good that the bug exists on your
-      project's main branch (and possibly other maintenance branches,
-      too).  It's a rare developer who wants to fix the same bug
-      multiple times, so let's look at a few ways that Mercurial can
-      help you to manage these bugfixes without duplicating your
-      work.</para>
-
-    <para id="x_38e">In the simplest instance, all you need to do is pull changes
-      from your maintenance branch into your local clone of the target
-      branch.</para>
-
-    &interaction.branch-repo.pull;
-
-    <para id="x_38f">You'll then need to merge the heads of the two branches, and
-      push back to the main branch.</para>
-
-    &interaction.branch-repo.merge;
-  </sect1>
-
-  <sect1>
-    <title>Naming branches within one repository</title>
-
-    <para id="x_390">In most instances, isolating branches in repositories is the
-      right approach.  Its simplicity makes it easy to understand; and
-      so it's hard to make mistakes.  There's a one-to-one
-      relationship between branches you're working in and directories
-      on your system.  This lets you use normal (non-Mercurial-aware)
-      tools to work on files within a branch/repository.</para>
-
-    <para id="x_391">If you're more in the <quote>power user</quote> category
-      (<emphasis>and</emphasis> your collaborators are too), there is
-      an alternative way of handling branches that you can consider.
-      I've already mentioned the human-level distinction between
-      <quote>small picture</quote> and <quote>big picture</quote>
-      branches.  While Mercurial works with multiple <quote>small
-	picture</quote> branches in a repository all the time (for
-      example after you pull changes in, but before you merge them),
-      it can <emphasis>also</emphasis> work with multiple <quote>big
-	picture</quote> branches.</para>
-
-    <para id="x_392">The key to working this way is that Mercurial lets you
-      assign a persistent <emphasis>name</emphasis> to a branch.
-      There always exists a branch named <literal>default</literal>.
-      Even before you start naming branches yourself, you can find
-      traces of the <literal>default</literal> branch if you look for
-      them.</para>
-
-    <para id="x_393">As an example, when you run the <command role="hg-cmd">hg
-	commit</command> command, and it pops up your editor so that
-      you can enter a commit message, look for a line that contains
-      the text <quote><literal>HG: branch default</literal></quote> at
-      the bottom. This is telling you that your commit will occur on
-      the branch named <literal>default</literal>.</para>
-
-    <para id="x_394">To start working with named branches, use the <command
-	role="hg-cmd">hg branches</command> command.  This command
-      lists the named branches already present in your repository,
-      telling you which changeset is the tip of each.</para>
-
-    &interaction.branch-named.branches;
-
-    <para id="x_395">Since you haven't created any named branches yet, the only
-      one that exists is <literal>default</literal>.</para>
-
-    <para id="x_396">To find out what the <quote>current</quote> branch is, run
-      the <command role="hg-cmd">hg branch</command> command, giving
-      it no arguments.  This tells you what branch the parent of the
-      current changeset is on.</para>
-
-    &interaction.branch-named.branch;
-
-    <para id="x_397">To create a new branch, run the <command role="hg-cmd">hg
-	branch</command> command again.  This time, give it one
-      argument: the name of the branch you want to create.</para>
-
-    &interaction.branch-named.create;
-
-    <para id="x_398">After you've created a branch, you might wonder what effect
-      the <command role="hg-cmd">hg branch</command> command has had.
-      What do the <command role="hg-cmd">hg status</command> and
-      <command role="hg-cmd">hg tip</command> commands report?</para>
-
-    &interaction.branch-named.status;
-
-    <para id="x_399">Nothing has changed in the
-      working directory, and there's been no new history created.  As
-      this suggests, running the <command role="hg-cmd">hg
-	branch</command> command has no permanent effect; it only
-      tells Mercurial what branch name to use the
-      <emphasis>next</emphasis> time you commit a changeset.</para>
-
-    <para id="x_39a">When you commit a change, Mercurial records the name of the
-      branch on which you committed.  Once you've switched from the
-      <literal>default</literal> branch to another and committed,
-      you'll see the name of the new branch show up in the output of
-      <command role="hg-cmd">hg log</command>, <command
-	role="hg-cmd">hg tip</command>, and other commands that
-      display the same kind of output.</para>
-
-    &interaction.branch-named.commit;
-
-    <para id="x_39b">The <command role="hg-cmd">hg log</command>-like commands
-      will print the branch name of every changeset that's not on the
-      <literal>default</literal> branch.  As a result, if you never
-      use named branches, you'll never see this information.</para>
-
-    <para id="x_39c">Once you've named a branch and committed a change with that
-      name, every subsequent commit that descends from that change
-      will inherit the same branch name.  You can change the name of a
-      branch at any time, using the <command role="hg-cmd">hg
-	branch</command> command.</para>
-
-    &interaction.branch-named.rebranch;
-
-    <para id="x_39d">In practice, this is something you won't do very often, as
-      branch names tend to have fairly long lifetimes.  (This isn't a
-      rule, just an observation.)</para>
-  </sect1>
-
-  <sect1>
-    <title>Dealing with multiple named branches in a
-      repository</title>
-
-    <para id="x_39e">If you have more than one named branch in a repository,
-      Mercurial will remember the branch that your working directory
-      is on when you start a command like <command role="hg-cmd">hg
-	update</command> or <command role="hg-cmd">hg pull
-	-u</command>.  It will update the working directory to the tip
-      of this branch, no matter what the <quote>repo-wide</quote> tip
-      is.  To update to a revision that's on a different named branch,
-      you may need to use the <option role="hg-opt-update">-C</option>
-      option to <command role="hg-cmd">hg update</command>.</para>
-
-    <para id="x_39f">This behavior is a little subtle, so let's see it in
-      action.  First, let's remind ourselves what branch we're
-      currently on, and what branches are in our repository.</para>
-
-    &interaction.branch-named.parents;
-
-    <para id="x_3a0">We're on the <literal>bar</literal> branch, but there also
-      exists an older <command role="hg-cmd">hg foo</command>
-      branch.</para>
-
-    <para id="x_3a1">We can <command role="hg-cmd">hg update</command> back and
-      forth between the tips of the <literal>foo</literal> and
-      <literal>bar</literal> branches without needing to use the
-      <option role="hg-opt-update">-C</option> option, because this
-      only involves going backwards and forwards linearly through our
-      change history.</para>
-
-    &interaction.branch-named.update-switchy;
-
-    <para id="x_3a2">If we go back to the <literal>foo</literal> branch and then
-      run <command role="hg-cmd">hg update</command>, it will keep us
-      on <literal>foo</literal>, not move us to the tip of
-      <literal>bar</literal>.</para>
-
-    &interaction.branch-named.update-nothing;
-
-    <para id="x_3a3">Committing a new change on the <literal>foo</literal> branch
-      introduces a new head.</para>
-
-    &interaction.branch-named.foo-commit;
-  </sect1>
-
-  <sect1>
-    <title>Branch names and merging</title>
-
-    <para id="x_3a4">As you've probably noticed, merges in Mercurial are not
-      symmetrical. Let's say our repository has two heads, 17 and 23.
-      If I <command role="hg-cmd">hg update</command> to 17 and then
-      <command role="hg-cmd">hg merge</command> with 23, Mercurial
-      records 17 as the first parent of the merge, and 23 as the
-      second.  Whereas if I <command role="hg-cmd">hg update</command>
-      to 23 and then <command role="hg-cmd">hg merge</command> with
-      17, it records 23 as the first parent, and 17 as the
-      second.</para>
-
-    <para id="x_3a5">This affects Mercurial's choice of branch name when you
-      merge.  After a merge, Mercurial will retain the branch name of
-      the first parent when you commit the result of the merge.  If
-      your first parent's branch name is <literal>foo</literal>, and
-      you merge with <literal>bar</literal>, the branch name will
-      still be <literal>foo</literal> after you merge.</para>
-
-    <para id="x_3a6">It's not unusual for a repository to contain multiple heads,
-      each with the same branch name.  Let's say I'm working on the
-      <literal>foo</literal> branch, and so are you.  We commit
-      different changes; I pull your changes; I now have two heads,
-      each claiming to be on the <literal>foo</literal> branch.  The
-      result of a merge will be a single head on the
-      <literal>foo</literal> branch, as you might hope.</para>
-
-    <para id="x_3a7">But if I'm working on the <literal>bar</literal> branch, and
-      I merge work from the <literal>foo</literal> branch, the result
-      will remain on the <literal>bar</literal> branch.</para>
-
-    &interaction.branch-named.merge;
-
-    <para id="x_3a8">To give a more concrete example, if I'm working on the
-      <literal>bleeding-edge</literal> branch, and I want to bring in
-      the latest fixes from the <literal>stable</literal> branch,
-      Mercurial will choose the <quote>right</quote>
-      (<literal>bleeding-edge</literal>) branch name when I pull and
-      merge from <literal>stable</literal>.</para>
-  </sect1>
-
-  <sect1>
-    <title>Branch naming is generally useful</title>
-
-    <para id="x_3a9">You shouldn't think of named branches as applicable only to
-      situations where you have multiple long-lived branches
-      cohabiting in a single repository.  They're very useful even in
-      the one-branch-per-repository case.</para>
-
-    <para id="x_3aa">In the simplest case, giving a name to each branch gives you
-      a permanent record of which branch a changeset originated on.
-      This gives you more context when you're trying to follow the
-      history of a long-lived branchy project.</para>
-
-    <para id="x_3ab">If you're working with shared repositories, you can set up a
-      <literal role="hook">pretxnchangegroup</literal> hook on each
-      that will block incoming changes that have the
-      <quote>wrong</quote> branch name.  This provides a simple, but
-      effective, defence against people accidentally pushing changes
-      from a <quote>bleeding edge</quote> branch to a
-      <quote>stable</quote> branch.  Such a hook might look like this
-      inside the shared repo's <filename role="special">
-	/.hgrc</filename>.</para>
-    <programlisting>[hooks]
-pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch</programlisting>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch07-filenames.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,451 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:names">
+  <?dbhtml filename="file-names-and-pattern-matching.html"?>
+  <title>File names and pattern matching</title>
+
+  <para id="x_543">Mercurial provides mechanisms that let you work with file
+    names in a consistent and expressive way.</para>
+
+  <sect1>
+    <title>Simple file naming</title>
+
+    <para id="x_544">Mercurial uses a unified piece of machinery <quote>under the
+	hood</quote> to handle file names.  Every command behaves
+      uniformly with respect to file names.  The way in which commands
+      work with file names is as follows.</para>
+
+    <para id="x_545">If you explicitly name real files on the command line,
+      Mercurial works with exactly those files, as you would expect.
+      &interaction.filenames.files;</para>
+
+    <para id="x_546">When you provide a directory name, Mercurial will interpret
+      this as <quote>operate on every file in this directory and its
+	subdirectories</quote>. Mercurial traverses the files and
+      subdirectories in a directory in alphabetical order.  When it
+      encounters a subdirectory, it will traverse that subdirectory
+      before continuing with the current directory.</para>
+
+      &interaction.filenames.dirs;
+  </sect1>
+
+  <sect1>
+    <title>Running commands without any file names</title>
+
+    <para id="x_547">Mercurial's commands that work with file names have useful
+      default behaviors when you invoke them without providing any
+      file names or patterns.  What kind of behavior you should
+      expect depends on what the command does.  Here are a few rules
+      of thumb you can use to predict what a command is likely to do
+      if you don't give it any names to work with.</para>
+    <itemizedlist>
+      <listitem><para id="x_548">Most commands will operate on the entire working
+	  directory. This is what the <command role="hg-cmd">hg
+	    add</command> command does, for example.</para>
+      </listitem>
+      <listitem><para id="x_549">If the command has effects that are difficult or
+	  impossible to reverse, it will force you to explicitly
+	  provide at least one name or pattern (see below).  This
+	  protects you from accidentally deleting files by running
+	  <command role="hg-cmd">hg remove</command> with no
+	  arguments, for example.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_54a">It's easy to work around these default behaviors if they
+      don't suit you.  If a command normally operates on the whole
+      working directory, you can invoke it on just the current
+      directory and its subdirectories by giving it the name
+      <quote><filename class="directory">.</filename></quote>.</para>
+
+    &interaction.filenames.wdir-subdir;
+
+    <para id="x_54b">Along the same lines, some commands normally print file
+      names relative to the root of the repository, even if you're
+      invoking them from a subdirectory.  Such a command will print
+      file names relative to your subdirectory if you give it explicit
+      names.  Here, we're going to run <command role="hg-cmd">hg
+	status</command> from a subdirectory, and get it to operate on
+      the entire working directory while printing file names relative
+      to our subdirectory, by passing it the output of the <command
+	role="hg-cmd">hg root</command> command.</para>
+
+      &interaction.filenames.wdir-relname;
+  </sect1>
+
+  <sect1>
+    <title>Telling you what's going on</title>
+
+    <para id="x_54c">The <command role="hg-cmd">hg add</command> example in the
+      preceding section illustrates something else that's helpful
+      about Mercurial commands.  If a command operates on a file that
+      you didn't name explicitly on the command line, it will usually
+      print the name of the file, so that you will not be surprised
+      what's going on.</para>
+
+    <para id="x_54d">The principle here is of <emphasis>least
+	surprise</emphasis>.  If you've exactly named a file on the
+      command line, there's no point in repeating it back at you.  If
+      Mercurial is acting on a file <emphasis>implicitly</emphasis>, e.g.
+      because you provided no names, or a directory, or a pattern (see
+      below), it is safest to tell you what files it's operating on.</para>
+
+    <para id="x_54e">For commands that behave this way, you can silence them
+      using the <option role="hg-opt-global">-q</option> option.  You
+      can also get them to print the name of every file, even those
+      you've named explicitly, using the <option
+	role="hg-opt-global">-v</option> option.</para>
+  </sect1>
+
+  <sect1>
+    <title>Using patterns to identify files</title>
+
+    <para id="x_54f">In addition to working with file and directory names,
+      Mercurial lets you use <emphasis>patterns</emphasis> to identify
+      files.  Mercurial's pattern handling is expressive.</para>
+
+    <para id="x_550">On Unix-like systems (Linux, MacOS, etc.), the job of
+      matching file names to patterns normally falls to the shell.  On
+      these systems, you must explicitly tell Mercurial that a name is
+      a pattern.  On Windows, the shell does not expand patterns, so
+      Mercurial will automatically identify names that are patterns,
+      and expand them for you.</para>
+
+    <para id="x_551">To provide a pattern in place of a regular name on the
+      command line, the mechanism is simple:</para>
+    <programlisting>syntax:patternbody</programlisting>
+    <para id="x_552">That is, a pattern is identified by a short text string that
+      says what kind of pattern this is, followed by a colon, followed
+      by the actual pattern.</para>
+
+    <para id="x_553">Mercurial supports two kinds of pattern syntax.  The most
+      frequently used is called <literal>glob</literal>; this is the
+      same kind of pattern matching used by the Unix shell, and should
+      be familiar to Windows command prompt users, too.</para>
+
+    <para id="x_554">When Mercurial does automatic pattern matching on Windows,
+      it uses <literal>glob</literal> syntax.  You can thus omit the
+      <quote><literal>glob:</literal></quote> prefix on Windows, but
+      it's safe to use it, too.</para>
+
+    <para id="x_555">The <literal>re</literal> syntax is more powerful; it lets
+      you specify patterns using regular expressions, also known as
+      regexps.</para>
+
+    <para id="x_556">By the way, in the examples that follow, notice that I'm
+      careful to wrap all of my patterns in quote characters, so that
+      they won't get expanded by the shell before Mercurial sees
+      them.</para>
+
+    <sect2>
+      <title>Shell-style <literal>glob</literal> patterns</title>
+
+      <para id="x_557">This is an overview of the kinds of patterns you can use
+	when you're matching on glob patterns.</para>
+
+      <para id="x_558">The <quote><literal>*</literal></quote> character matches
+	any string, within a single directory.</para>
+
+      &interaction.filenames.glob.star;
+
+      <para id="x_559">The <quote><literal>**</literal></quote> pattern matches
+	any string, and crosses directory boundaries.  It's not a
+	standard Unix glob token, but it's accepted by several popular
+	Unix shells, and is very useful.</para>
+
+      &interaction.filenames.glob.starstar;
+
+      <para id="x_55a">The <quote><literal>?</literal></quote> pattern matches
+	any single character.</para>
+
+      &interaction.filenames.glob.question;
+
+      <para id="x_55b">The <quote><literal>[</literal></quote> character begins a
+	<emphasis>character class</emphasis>.  This matches any single
+	character within the class.  The class ends with a
+	<quote><literal>]</literal></quote> character.  A class may
+	contain multiple <emphasis>range</emphasis>s of the form
+	<quote><literal>a-f</literal></quote>, which is shorthand for
+	<quote><literal>abcdef</literal></quote>.</para>
+
+	&interaction.filenames.glob.range;
+
+      <para id="x_55c">If the first character after the
+	<quote><literal>[</literal></quote> in a character class is a
+	<quote><literal>!</literal></quote>, it
+	<emphasis>negates</emphasis> the class, making it match any
+	single character not in the class.</para>
+
+      <para id="x_55d">A <quote><literal>{</literal></quote> begins a group of
+	subpatterns, where the whole group matches if any subpattern
+	in the group matches.  The <quote><literal>,</literal></quote>
+	character separates subpatterns, and
+	<quote><literal>}</literal></quote> ends the group.</para>
+
+      &interaction.filenames.glob.group;
+
+      <sect3>
+	<title>Watch out!</title>
+
+	<para id="x_55e">Don't forget that if you want to match a pattern in any
+	  directory, you should not be using the
+	  <quote><literal>*</literal></quote> match-any token, as this
+	  will only match within one directory.  Instead, use the
+	  <quote><literal>**</literal></quote> token.  This small
+	  example illustrates the difference between the two.</para>
+
+	  &interaction.filenames.glob.star-starstar;
+      </sect3>
+    </sect2>
+
+    <sect2>
+      <title>Regular expression matching with <literal>re</literal>
+	patterns</title>
+
+      <para id="x_55f">Mercurial accepts the same regular expression syntax as
+	the Python programming language (it uses Python's regexp
+	engine internally). This is based on the Perl language's
+	regexp syntax, which is the most popular dialect in use (it's
+	also used in Java, for example).</para>
+
+      <para id="x_560">I won't discuss Mercurial's regexp dialect in any detail
+	here, as regexps are not often used.  Perl-style regexps are
+	in any case already exhaustively documented on a multitude of
+	web sites, and in many books.  Instead, I will focus here on a
+	few things you should know if you find yourself needing to use
+	regexps with Mercurial.</para>
+
+      <para id="x_561">A regexp is matched against an entire file name, relative
+	to the root of the repository.  In other words, even if you're
+	already in subbdirectory <filename
+	  class="directory">foo</filename>, if you want to match files
+	under this directory, your pattern must start with
+	<quote><literal>foo/</literal></quote>.</para>
+
+      <para id="x_562">One thing to note, if you're familiar with Perl-style
+	regexps, is that Mercurial's are <emphasis>rooted</emphasis>.
+	That is, a regexp starts matching against the beginning of a
+	string; it doesn't look for a match anywhere within the
+	string.  To match anywhere in a string, start your pattern
+	with <quote><literal>.*</literal></quote>.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Filtering files</title>
+
+    <para id="x_563">Not only does Mercurial give you a variety of ways to
+      specify files; it lets you further winnow those files using
+      <emphasis>filters</emphasis>.  Commands that work with file
+      names accept two filtering options.</para>
+    <itemizedlist>
+      <listitem><para id="x_564"><option role="hg-opt-global">-I</option>, or
+	  <option role="hg-opt-global">--include</option>, lets you
+	  specify a pattern that file names must match in order to be
+	  processed.</para>
+      </listitem>
+      <listitem><para id="x_565"><option role="hg-opt-global">-X</option>, or
+	  <option role="hg-opt-global">--exclude</option>, gives you a
+	  way to <emphasis>avoid</emphasis> processing files, if they
+	  match this pattern.</para>
+      </listitem></itemizedlist>
+    <para id="x_566">You can provide multiple <option
+	role="hg-opt-global">-I</option> and <option
+	role="hg-opt-global">-X</option> options on the command line,
+      and intermix them as you please.  Mercurial interprets the
+      patterns you provide using glob syntax by default (but you can
+      use regexps if you need to).</para>
+
+    <para id="x_567">You can read a <option role="hg-opt-global">-I</option>
+      filter as <quote>process only the files that match this
+	filter</quote>.</para>
+
+    &interaction.filenames.filter.include;
+
+    <para id="x_568">The <option role="hg-opt-global">-X</option> filter is best
+      read as <quote>process only the files that don't match this
+	pattern</quote>.</para>
+
+    &interaction.filenames.filter.exclude;
+  </sect1>
+
+  <sect1>
+    <title>Permanently ignoring unwanted files and directories</title>
+
+    <para id="x_569">When you create a new repository, the chances are
+      that over time it will grow to contain files that ought to
+      <emphasis>not</emphasis> be managed by Mercurial, but which you
+      don't want to see listed every time you run <command>hg
+	status</command>.  For instance, <quote>build products</quote>
+      are files that are created as part of a build but which should
+      not be managed by a revision control system.  The most common
+      build products are output files produced by software tools such
+      as compilers.  As another example, many text editors litter a
+      directory with lock files, temporary working files, and backup
+      files, which it also makes no sense to manage.</para>
+
+    <para id="x_6b4">To have Mercurial permanently ignore such files, create a
+      file named <filename>.hgignore</filename> in the root of your
+      repository.  You <emphasis>should</emphasis> <command>hg
+      add</command> this file so that it gets tracked with the rest of
+      your repository contents, since your collaborators will probably
+      find it useful too.</para>
+
+    <para id="x_6b5">By default, the <filename>.hgignore</filename> file should
+      contain a list of regular expressions, one per line.  Empty
+      lines are skipped. Most people prefer to describe the files they
+      want to ignore using the <quote>glob</quote> syntax that we
+      described above, so a typical <filename>.hgignore</filename>
+      file will start with this directive:</para>
+
+    <programlisting>syntax: glob</programlisting>
+
+    <para id="x_6b6">This tells Mercurial to interpret the lines that follow as
+      glob patterns, not regular expressions.</para>
+
+    <para id="x_6b7">Here is a typical-looking <filename>.hgignore</filename>
+      file.</para>
+
+    <programlisting>syntax: glob
+# This line is a comment, and will be skipped.
+# Empty lines are skipped too.
+
+# Backup files left behind by the Emacs editor.
+*~
+
+# Lock files used by the Emacs editor.
+# Notice that the "#" character is quoted with a backslash.
+# This prevents it from being interpreted as starting a comment.
+.\#*
+
+# Temporary files used by the vim editor.
+.*.swp
+
+# A hidden file created by the Mac OS X Finder.
+.DS_Store
+</programlisting>
+  </sect1>
+
+  <sect1 id="sec:names:case">
+    <title>Case sensitivity</title>
+
+    <para id="x_56a">If you're working in a mixed development environment that
+      contains both Linux (or other Unix) systems and Macs or Windows
+      systems, you should keep in the back of your mind the knowledge
+      that they treat the case (<quote>N</quote> versus
+      <quote>n</quote>) of file names in incompatible ways.  This is
+      not very likely to affect you, and it's easy to deal with if it
+      does, but it could surprise you if you don't know about
+      it.</para>
+
+    <para id="x_56b">Operating systems and filesystems differ in the way they
+      handle the <emphasis>case</emphasis> of characters in file and
+      directory names.  There are three common ways to handle case in
+      names.</para>
+    <itemizedlist>
+      <listitem><para id="x_56c">Completely case insensitive.  Uppercase and
+	  lowercase versions of a letter are treated as identical,
+	  both when creating a file and during subsequent accesses.
+	  This is common on older DOS-based systems.</para>
+      </listitem>
+      <listitem><para id="x_56d">Case preserving, but insensitive.  When a file
+	  or directory is created, the case of its name is stored, and
+	  can be retrieved and displayed by the operating system.
+	  When an existing file is being looked up, its case is
+	  ignored.  This is the standard arrangement on Windows and
+	  MacOS.  The names <filename>foo</filename> and
+	  <filename>FoO</filename> identify the same file.  This
+	  treatment of uppercase and lowercase letters as
+	  interchangeable is also referred to as <emphasis>case
+	    folding</emphasis>.</para>
+      </listitem>
+      <listitem><para id="x_56e">Case sensitive.  The case of a name
+	  is significant at all times. The names
+	  <filename>foo</filename> and <filename>FoO</filename>
+	  identify different files.  This is the way Linux and Unix
+	  systems normally work.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_56f">On Unix-like systems, it is possible to have any or all of
+      the above ways of handling case in action at once.  For example,
+      if you use a USB thumb drive formatted with a FAT32 filesystem
+      on a Linux system, Linux will handle names on that filesystem in
+      a case preserving, but insensitive, way.</para>
+
+    <sect2>
+      <title>Safe, portable repository storage</title>
+
+      <para id="x_570">Mercurial's repository storage mechanism is <emphasis>case
+	  safe</emphasis>.  It translates file names so that they can
+	be safely stored on both case sensitive and case insensitive
+	filesystems.  This means that you can use normal file copying
+	tools to transfer a Mercurial repository onto, for example, a
+	USB thumb drive, and safely move that drive and repository
+	back and forth between a Mac, a PC running Windows, and a
+	Linux box.</para>
+
+    </sect2>
+    <sect2>
+      <title>Detecting case conflicts</title>
+
+      <para id="x_571">When operating in the working directory, Mercurial honours
+	the naming policy of the filesystem where the working
+	directory is located.  If the filesystem is case preserving,
+	but insensitive, Mercurial will treat names that differ only
+	in case as the same.</para>
+
+      <para id="x_572">An important aspect of this approach is that it is
+	possible to commit a changeset on a case sensitive (typically
+	Linux or Unix) filesystem that will cause trouble for users on
+	case insensitive (usually Windows and MacOS) users.  If a
+	Linux user commits changes to two files, one named
+	<filename>myfile.c</filename> and the other named
+	<filename>MyFile.C</filename>, they will be stored correctly
+	in the repository.  And in the working directories of other
+	Linux users, they will be correctly represented as separate
+	files.</para>
+
+      <para id="x_573">If a Windows or Mac user pulls this change, they will not
+	initially have a problem, because Mercurial's repository
+	storage mechanism is case safe.  However, once they try to
+	<command role="hg-cmd">hg update</command> the working
+	directory to that changeset, or <command role="hg-cmd">hg
+	  merge</command> with that changeset, Mercurial will spot the
+	conflict between the two file names that the filesystem would
+	treat as the same, and forbid the update or merge from
+	occurring.</para>
+    </sect2>
+
+    <sect2>
+      <title>Fixing a case conflict</title>
+
+      <para id="x_574">If you are using Windows or a Mac in a mixed environment
+	where some of your collaborators are using Linux or Unix, and
+	Mercurial reports a case folding conflict when you try to
+	<command role="hg-cmd">hg update</command> or <command
+	  role="hg-cmd">hg merge</command>, the procedure to fix the
+	problem is simple.</para>
+
+      <para id="x_575">Just find a nearby Linux or Unix box, clone the problem
+	repository onto it, and use Mercurial's <command
+	  role="hg-cmd">hg rename</command> command to change the
+	names of any offending files or directories so that they will
+	no longer cause case folding conflicts.  Commit this change,
+	<command role="hg-cmd">hg pull</command> or <command
+	  role="hg-cmd">hg push</command> it across to your Windows or
+	MacOS system, and <command role="hg-cmd">hg update</command>
+	to the revision with the non-conflicting names.</para>
+
+      <para id="x_576">The changeset with case-conflicting names will remain in
+	your project's history, and you still won't be able to
+	<command role="hg-cmd">hg update</command> your working
+	directory to that changeset on a Windows or MacOS system, but
+	you can continue development unimpeded.</para>
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch08-branch.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,533 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:branch">
+  <?dbhtml filename="managing-releases-and-branchy-development.html"?>
+  <title>Managing releases and branchy development</title>
+
+  <para id="x_369">Mercurial provides several mechanisms for you to manage a
+    project that is making progress on multiple fronts at once.  To
+    understand these mechanisms, let's first take a brief look at a
+    fairly normal software project structure.</para>
+
+  <para id="x_36a">Many software projects issue periodic <quote>major</quote>
+    releases that contain substantial new features.  In parallel, they
+    may issue <quote>minor</quote> releases.  These are usually
+    identical to the major releases off which they're based, but with
+    a few bugs fixed.</para>
+
+  <para id="x_36b">In this chapter, we'll start by talking about how to keep
+    records of project milestones such as releases.  We'll then
+    continue on to talk about the flow of work between different
+    phases of a project, and how Mercurial can help you to isolate and
+    manage this work.</para>
+
+  <sect1>
+    <title>Giving a persistent name to a revision</title>
+
+    <para id="x_36c">Once you decide that you'd like to call a particular
+      revision a <quote>release</quote>, it's a good idea to record
+      the identity of that revision. This will let you reproduce that
+      release at a later date, for whatever purpose you might need at
+      the time (reproducing a bug, porting to a new platform, etc).
+      &interaction.tag.init;</para>
+
+    <para id="x_36d">Mercurial lets you give a permanent name to any revision
+      using the <command role="hg-cmd">hg tag</command> command.  Not
+      surprisingly, these names are called <quote>tags</quote>.</para>
+
+    &interaction.tag.tag;
+
+    <para id="x_36e">A tag is nothing more than a <quote>symbolic name</quote>
+      for a revision.  Tags exist purely for your convenience, so that
+      you have a handy permanent way to refer to a revision; Mercurial
+      doesn't interpret the tag names you use in any way.  Neither
+      does Mercurial place any restrictions on the name of a tag,
+      beyond a few that are necessary to ensure that a tag can be
+      parsed unambiguously.  A tag name cannot contain any of the
+      following characters:</para>
+    <itemizedlist>
+      <listitem><para id="x_36f">Colon (ASCII 58,
+	  <quote><literal>:</literal></quote>)</para>
+      </listitem>
+      <listitem><para id="x_370">Carriage return (ASCII 13,
+	  <quote><literal>\r</literal></quote>)</para>
+      </listitem>
+      <listitem><para id="x_371">Newline (ASCII 10,
+	  <quote><literal>\n</literal></quote>)</para>
+      </listitem></itemizedlist>
+
+    <para id="x_372">You can use the <command role="hg-cmd">hg tags</command>
+      command to display the tags present in your repository.  In the
+      output, each tagged revision is identified first by its name,
+      then by revision number, and finally by the unique hash of the
+      revision.</para>
+
+    &interaction.tag.tags;
+
+    <para id="x_373">Notice that <literal>tip</literal> is listed in the output
+      of <command role="hg-cmd">hg tags</command>.  The
+      <literal>tip</literal> tag is a special <quote>floating</quote>
+      tag, which always identifies the newest revision in the
+      repository.</para>
+
+    <para id="x_374">In the output of the <command role="hg-cmd">hg
+	tags</command> command, tags are listed in reverse order, by
+      revision number.  This usually means that recent tags are listed
+      before older tags.  It also means that <literal>tip</literal> is
+      always going to be the first tag listed in the output of
+      <command role="hg-cmd">hg tags</command>.</para>
+
+    <para id="x_375">When you run <command role="hg-cmd">hg log</command>, if it
+      displays a revision that has tags associated with it, it will
+      print those tags.</para>
+
+    &interaction.tag.log;
+
+    <para id="x_376">Any time you need to provide a revision ID to a Mercurial
+      command, the command will accept a tag name in its place.
+      Internally, Mercurial will translate your tag name into the
+      corresponding revision ID, then use that.</para>
+
+    &interaction.tag.log.v1.0;
+
+    <para id="x_377">There's no limit on the number of tags you can have in a
+      repository, or on the number of tags that a single revision can
+      have.  As a practical matter, it's not a great idea to have
+      <quote>too many</quote> (a number which will vary from project
+      to project), simply because tags are supposed to help you to
+      find revisions.  If you have lots of tags, the ease of using
+      them to identify revisions diminishes rapidly.</para>
+
+    <para id="x_378">For example, if your project has milestones as frequent as
+      every few days, it's perfectly reasonable to tag each one of
+      those.  But if you have a continuous build system that makes
+      sure every revision can be built cleanly, you'd be introducing a
+      lot of noise if you were to tag every clean build.  Instead, you
+      could tag failed builds (on the assumption that they're rare!),
+      or simply not use tags to track buildability.</para>
+
+    <para id="x_379">If you want to remove a tag that you no longer want, use
+      <command role="hg-cmd">hg tag --remove</command>.</para>
+
+    &interaction.tag.remove;
+
+    <para id="x_37a">You can also modify a tag at any time, so that it identifies
+      a different revision, by simply issuing a new <command
+	role="hg-cmd">hg tag</command> command. You'll have to use the
+      <option role="hg-opt-tag">-f</option> option to tell Mercurial
+      that you <emphasis>really</emphasis> want to update the
+      tag.</para>
+
+    &interaction.tag.replace;
+
+    <para id="x_37b">There will still be a permanent record of the previous
+      identity of the tag, but Mercurial will no longer use it.
+      There's thus no penalty to tagging the wrong revision; all you
+      have to do is turn around and tag the correct revision once you
+      discover your error.</para>
+
+    <para id="x_37c">Mercurial stores tags in a normal revision-controlled file
+      in your repository.  If you've created any tags, you'll find
+      them in a file in the root of your repository named <filename
+	role="special">.hgtags</filename>.  When you run the <command
+	role="hg-cmd">hg tag</command> command, Mercurial modifies
+      this file, then automatically commits the change to it.  This
+      means that every time you run <command role="hg-cmd">hg
+	tag</command>, you'll see a corresponding changeset in the
+      output of <command role="hg-cmd">hg log</command>.</para>
+
+    &interaction.tag.tip;
+
+    <sect2>
+      <title>Handling tag conflicts during a merge</title>
+
+      <para id="x_37d">You won't often need to care about the <filename
+	  role="special">.hgtags</filename> file, but it sometimes
+	makes its presence known during a merge.  The format of the
+	file is simple: it consists of a series of lines.  Each line
+	starts with a changeset hash, followed by a space, followed by
+	the name of a tag.</para>
+
+      <para id="x_37e">If you're resolving a conflict in the <filename
+	  role="special">.hgtags</filename> file during a merge,
+	there's one twist to modifying the <filename
+	  role="special">.hgtags</filename> file: when Mercurial is
+	parsing the tags in a repository, it
+	<emphasis>never</emphasis> reads the working copy of the
+	<filename role="special">.hgtags</filename> file.  Instead, it
+	reads the <emphasis>most recently committed</emphasis>
+	revision of the file.</para>
+
+      <para id="x_37f">An unfortunate consequence of this design is that you
+	can't actually verify that your merged <filename
+	  role="special">.hgtags</filename> file is correct until
+	<emphasis>after</emphasis> you've committed a change.  So if
+	you find yourself resolving a conflict on <filename
+	  role="special">.hgtags</filename> during a merge, be sure to
+	run <command role="hg-cmd">hg tags</command> after you commit.
+	If it finds an error in the <filename
+	  role="special">.hgtags</filename> file, it will report the
+	location of the error, which you can then fix and commit.  You
+	should then run <command role="hg-cmd">hg tags</command>
+	again, just to be sure that your fix is correct.</para>
+    </sect2>
+
+    <sect2>
+      <title>Tags and cloning</title>
+
+      <para id="x_380">You may have noticed that the <command role="hg-cmd">hg
+	  clone</command> command has a <option
+	  role="hg-opt-clone">-r</option> option that lets you clone
+	an exact copy of the repository as of a particular changeset.
+	The new clone will not contain any project history that comes
+	after the revision you specified.  This has an interaction
+	with tags that can surprise the unwary.</para>
+
+      <para id="x_381">Recall that a tag is stored as a revision to
+	the <filename role="special">.hgtags</filename> file. When you
+	create a tag, the changeset in which its recorded refers to an
+	older changeset.  When you run <command role="hg-cmd">hg clone
+	  -r foo</command> to clone a repository as of tag
+	<literal>foo</literal>, the new clone <emphasis>will not
+	  contain any revision newer than the one the tag refers to,
+	  including the revision where the tag was created</emphasis>.
+	The result is that you'll get exactly the right subset of the
+	project's history in the new repository, but
+	<emphasis>not</emphasis> the tag you might have
+	expected.</para>
+    </sect2>
+
+    <sect2>
+      <title>When permanent tags are too much</title>
+
+      <para id="x_382">Since Mercurial's tags are revision controlled and carried
+	around with a project's history, everyone you work with will
+	see the tags you create.  But giving names to revisions has
+	uses beyond simply noting that revision
+	<literal>4237e45506ee</literal> is really
+	<literal>v2.0.2</literal>.  If you're trying to track down a
+	subtle bug, you might want a tag to remind you of something
+	like <quote>Anne saw the symptoms with this
+	  revision</quote>.</para>
+
+      <para id="x_383">For cases like this, what you might want to use are
+	<emphasis>local</emphasis> tags. You can create a local tag
+	with the <option role="hg-opt-tag">-l</option> option to the
+	<command role="hg-cmd">hg tag</command> command.  This will
+	store the tag in a file called <filename
+	  role="special">.hg/localtags</filename>.  Unlike <filename
+	  role="special">.hgtags</filename>, <filename
+	  role="special">.hg/localtags</filename> is not revision
+	controlled.  Any tags you create using <option
+	  role="hg-opt-tag">-l</option> remain strictly local to the
+	repository you're currently working in.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>The flow of changes&emdash;big picture vs. little</title>
+
+    <para id="x_384">To return to the outline I sketched at the
+      beginning of the chapter, let's think about a project that has
+      multiple concurrent pieces of work under development at
+      once.</para>
+
+    <para id="x_385">There might be a push for a new <quote>main</quote> release;
+      a new minor bugfix release to the last main release; and an
+      unexpected <quote>hot fix</quote> to an old release that is now
+      in maintenance mode.</para>
+
+    <para id="x_386">The usual way people refer to these different concurrent
+      directions of development is as <quote>branches</quote>.
+      However, we've already seen numerous times that Mercurial treats
+      <emphasis>all of history</emphasis> as a series of branches and
+      merges.  Really, what we have here is two ideas that are
+      peripherally related, but which happen to share a name.</para>
+    <itemizedlist>
+      <listitem><para id="x_387"><quote>Big picture</quote> branches represent
+	  the sweep of a project's evolution; people give them names,
+	  and talk about them in conversation.</para>
+      </listitem>
+      <listitem><para id="x_388"><quote>Little picture</quote> branches are
+	  artefacts of the day-to-day activity of developing and
+	  merging changes.  They expose the narrative of how the code
+	  was developed.</para>
+      </listitem></itemizedlist>
+  </sect1>
+
+  <sect1>
+    <title>Managing big-picture branches in repositories</title>
+
+    <para id="x_389">The easiest way to isolate a <quote>big picture</quote>
+      branch in Mercurial is in a dedicated repository.  If you have
+      an existing shared repository&emdash;let's call it
+      <literal>myproject</literal>&emdash;that reaches a
+      <quote>1.0</quote> milestone, you can start to prepare for
+      future maintenance releases on top of version 1.0 by tagging the
+      revision from which you prepared the 1.0 release.</para>
+
+    &interaction.branch-repo.tag;
+
+    <para id="x_38a">You can then clone a new shared
+      <literal>myproject-1.0.1</literal> repository as of that
+      tag.</para>
+
+    &interaction.branch-repo.clone;
+
+    <para id="x_38b">Afterwards, if someone needs to work on a bug fix that ought
+      to go into an upcoming 1.0.1 minor release, they clone the
+      <literal>myproject-1.0.1</literal> repository, make their
+      changes, and push them back.</para>
+
+    &interaction.branch-repo.bugfix;
+
+    <para id="x_38c">Meanwhile, development for
+      the next major release can continue, isolated and unabated, in
+      the <literal>myproject</literal> repository.</para>
+
+    &interaction.branch-repo.new;
+  </sect1>
+
+  <sect1>
+    <title>Don't repeat yourself: merging across branches</title>
+
+    <para id="x_38d">In many cases, if you have a bug to fix on a maintenance
+      branch, the chances are good that the bug exists on your
+      project's main branch (and possibly other maintenance branches,
+      too).  It's a rare developer who wants to fix the same bug
+      multiple times, so let's look at a few ways that Mercurial can
+      help you to manage these bugfixes without duplicating your
+      work.</para>
+
+    <para id="x_38e">In the simplest instance, all you need to do is pull changes
+      from your maintenance branch into your local clone of the target
+      branch.</para>
+
+    &interaction.branch-repo.pull;
+
+    <para id="x_38f">You'll then need to merge the heads of the two branches, and
+      push back to the main branch.</para>
+
+    &interaction.branch-repo.merge;
+  </sect1>
+
+  <sect1>
+    <title>Naming branches within one repository</title>
+
+    <para id="x_390">In most instances, isolating branches in repositories is the
+      right approach.  Its simplicity makes it easy to understand; and
+      so it's hard to make mistakes.  There's a one-to-one
+      relationship between branches you're working in and directories
+      on your system.  This lets you use normal (non-Mercurial-aware)
+      tools to work on files within a branch/repository.</para>
+
+    <para id="x_391">If you're more in the <quote>power user</quote> category
+      (<emphasis>and</emphasis> your collaborators are too), there is
+      an alternative way of handling branches that you can consider.
+      I've already mentioned the human-level distinction between
+      <quote>small picture</quote> and <quote>big picture</quote>
+      branches.  While Mercurial works with multiple <quote>small
+	picture</quote> branches in a repository all the time (for
+      example after you pull changes in, but before you merge them),
+      it can <emphasis>also</emphasis> work with multiple <quote>big
+	picture</quote> branches.</para>
+
+    <para id="x_392">The key to working this way is that Mercurial lets you
+      assign a persistent <emphasis>name</emphasis> to a branch.
+      There always exists a branch named <literal>default</literal>.
+      Even before you start naming branches yourself, you can find
+      traces of the <literal>default</literal> branch if you look for
+      them.</para>
+
+    <para id="x_393">As an example, when you run the <command role="hg-cmd">hg
+	commit</command> command, and it pops up your editor so that
+      you can enter a commit message, look for a line that contains
+      the text <quote><literal>HG: branch default</literal></quote> at
+      the bottom. This is telling you that your commit will occur on
+      the branch named <literal>default</literal>.</para>
+
+    <para id="x_394">To start working with named branches, use the <command
+	role="hg-cmd">hg branches</command> command.  This command
+      lists the named branches already present in your repository,
+      telling you which changeset is the tip of each.</para>
+
+    &interaction.branch-named.branches;
+
+    <para id="x_395">Since you haven't created any named branches yet, the only
+      one that exists is <literal>default</literal>.</para>
+
+    <para id="x_396">To find out what the <quote>current</quote> branch is, run
+      the <command role="hg-cmd">hg branch</command> command, giving
+      it no arguments.  This tells you what branch the parent of the
+      current changeset is on.</para>
+
+    &interaction.branch-named.branch;
+
+    <para id="x_397">To create a new branch, run the <command role="hg-cmd">hg
+	branch</command> command again.  This time, give it one
+      argument: the name of the branch you want to create.</para>
+
+    &interaction.branch-named.create;
+
+    <para id="x_398">After you've created a branch, you might wonder what effect
+      the <command role="hg-cmd">hg branch</command> command has had.
+      What do the <command role="hg-cmd">hg status</command> and
+      <command role="hg-cmd">hg tip</command> commands report?</para>
+
+    &interaction.branch-named.status;
+
+    <para id="x_399">Nothing has changed in the
+      working directory, and there's been no new history created.  As
+      this suggests, running the <command role="hg-cmd">hg
+	branch</command> command has no permanent effect; it only
+      tells Mercurial what branch name to use the
+      <emphasis>next</emphasis> time you commit a changeset.</para>
+
+    <para id="x_39a">When you commit a change, Mercurial records the name of the
+      branch on which you committed.  Once you've switched from the
+      <literal>default</literal> branch to another and committed,
+      you'll see the name of the new branch show up in the output of
+      <command role="hg-cmd">hg log</command>, <command
+	role="hg-cmd">hg tip</command>, and other commands that
+      display the same kind of output.</para>
+
+    &interaction.branch-named.commit;
+
+    <para id="x_39b">The <command role="hg-cmd">hg log</command>-like commands
+      will print the branch name of every changeset that's not on the
+      <literal>default</literal> branch.  As a result, if you never
+      use named branches, you'll never see this information.</para>
+
+    <para id="x_39c">Once you've named a branch and committed a change with that
+      name, every subsequent commit that descends from that change
+      will inherit the same branch name.  You can change the name of a
+      branch at any time, using the <command role="hg-cmd">hg
+	branch</command> command.</para>
+
+    &interaction.branch-named.rebranch;
+
+    <para id="x_39d">In practice, this is something you won't do very often, as
+      branch names tend to have fairly long lifetimes.  (This isn't a
+      rule, just an observation.)</para>
+  </sect1>
+
+  <sect1>
+    <title>Dealing with multiple named branches in a
+      repository</title>
+
+    <para id="x_39e">If you have more than one named branch in a repository,
+      Mercurial will remember the branch that your working directory
+      is on when you start a command like <command role="hg-cmd">hg
+	update</command> or <command role="hg-cmd">hg pull
+	-u</command>.  It will update the working directory to the tip
+      of this branch, no matter what the <quote>repo-wide</quote> tip
+      is.  To update to a revision that's on a different named branch,
+      you may need to use the <option role="hg-opt-update">-C</option>
+      option to <command role="hg-cmd">hg update</command>.</para>
+
+    <para id="x_39f">This behavior is a little subtle, so let's see it in
+      action.  First, let's remind ourselves what branch we're
+      currently on, and what branches are in our repository.</para>
+
+    &interaction.branch-named.parents;
+
+    <para id="x_3a0">We're on the <literal>bar</literal> branch, but there also
+      exists an older <command role="hg-cmd">hg foo</command>
+      branch.</para>
+
+    <para id="x_3a1">We can <command role="hg-cmd">hg update</command> back and
+      forth between the tips of the <literal>foo</literal> and
+      <literal>bar</literal> branches without needing to use the
+      <option role="hg-opt-update">-C</option> option, because this
+      only involves going backwards and forwards linearly through our
+      change history.</para>
+
+    &interaction.branch-named.update-switchy;
+
+    <para id="x_3a2">If we go back to the <literal>foo</literal> branch and then
+      run <command role="hg-cmd">hg update</command>, it will keep us
+      on <literal>foo</literal>, not move us to the tip of
+      <literal>bar</literal>.</para>
+
+    &interaction.branch-named.update-nothing;
+
+    <para id="x_3a3">Committing a new change on the <literal>foo</literal> branch
+      introduces a new head.</para>
+
+    &interaction.branch-named.foo-commit;
+  </sect1>
+
+  <sect1>
+    <title>Branch names and merging</title>
+
+    <para id="x_3a4">As you've probably noticed, merges in Mercurial are not
+      symmetrical. Let's say our repository has two heads, 17 and 23.
+      If I <command role="hg-cmd">hg update</command> to 17 and then
+      <command role="hg-cmd">hg merge</command> with 23, Mercurial
+      records 17 as the first parent of the merge, and 23 as the
+      second.  Whereas if I <command role="hg-cmd">hg update</command>
+      to 23 and then <command role="hg-cmd">hg merge</command> with
+      17, it records 23 as the first parent, and 17 as the
+      second.</para>
+
+    <para id="x_3a5">This affects Mercurial's choice of branch name when you
+      merge.  After a merge, Mercurial will retain the branch name of
+      the first parent when you commit the result of the merge.  If
+      your first parent's branch name is <literal>foo</literal>, and
+      you merge with <literal>bar</literal>, the branch name will
+      still be <literal>foo</literal> after you merge.</para>
+
+    <para id="x_3a6">It's not unusual for a repository to contain multiple heads,
+      each with the same branch name.  Let's say I'm working on the
+      <literal>foo</literal> branch, and so are you.  We commit
+      different changes; I pull your changes; I now have two heads,
+      each claiming to be on the <literal>foo</literal> branch.  The
+      result of a merge will be a single head on the
+      <literal>foo</literal> branch, as you might hope.</para>
+
+    <para id="x_3a7">But if I'm working on the <literal>bar</literal> branch, and
+      I merge work from the <literal>foo</literal> branch, the result
+      will remain on the <literal>bar</literal> branch.</para>
+
+    &interaction.branch-named.merge;
+
+    <para id="x_3a8">To give a more concrete example, if I'm working on the
+      <literal>bleeding-edge</literal> branch, and I want to bring in
+      the latest fixes from the <literal>stable</literal> branch,
+      Mercurial will choose the <quote>right</quote>
+      (<literal>bleeding-edge</literal>) branch name when I pull and
+      merge from <literal>stable</literal>.</para>
+  </sect1>
+
+  <sect1>
+    <title>Branch naming is generally useful</title>
+
+    <para id="x_3a9">You shouldn't think of named branches as applicable only to
+      situations where you have multiple long-lived branches
+      cohabiting in a single repository.  They're very useful even in
+      the one-branch-per-repository case.</para>
+
+    <para id="x_3aa">In the simplest case, giving a name to each branch gives you
+      a permanent record of which branch a changeset originated on.
+      This gives you more context when you're trying to follow the
+      history of a long-lived branchy project.</para>
+
+    <para id="x_3ab">If you're working with shared repositories, you can set up a
+      <literal role="hook">pretxnchangegroup</literal> hook on each
+      that will block incoming changes that have the
+      <quote>wrong</quote> branch name.  This provides a simple, but
+      effective, defence against people accidentally pushing changes
+      from a <quote>bleeding edge</quote> branch to a
+      <quote>stable</quote> branch.  Such a hook might look like this
+      inside the shared repo's <filename role="special">
+	/.hgrc</filename>.</para>
+    <programlisting>[hooks]
+pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch</programlisting>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- a/en/ch08-undo.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1201 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:undo">
-  <?dbhtml filename="finding-and-fixing-mistakes.html"?>
-  <title>Finding and fixing mistakes</title>
-
-  <para id="x_d2">To err might be human, but to really handle the consequences
-    well takes a top-notch revision control system.  In this chapter,
-    we'll discuss some of the techniques you can use when you find
-    that a problem has crept into your project.  Mercurial has some
-    highly capable features that will help you to isolate the sources
-    of problems, and to handle them appropriately.</para>
-
-  <sect1>
-    <title>Erasing local history</title>
-
-    <sect2>
-      <title>The accidental commit</title>
-
-      <para id="x_d3">I have the occasional but persistent problem of typing
-	rather more quickly than I can think, which sometimes results
-	in me committing a changeset that is either incomplete or
-	plain wrong.  In my case, the usual kind of incomplete
-	changeset is one in which I've created a new source file, but
-	forgotten to <command role="hg-cmd">hg add</command> it.  A
-	<quote>plain wrong</quote> changeset is not as common, but no
-	less annoying.</para>
-
-    </sect2>
-    <sect2 id="sec:undo:rollback">
-      <title>Rolling back a transaction</title>
-
-      <para id="x_d4">In <xref linkend="sec:concepts:txn"/>, I
-	mentioned that Mercurial treats each modification of a
-	repository as a <emphasis>transaction</emphasis>.  Every time
-	you commit a changeset or pull changes from another
-	repository, Mercurial remembers what you did.  You can undo,
-	or <emphasis>roll back</emphasis>, exactly one of these
-	actions using the <command role="hg-cmd">hg rollback</command>
-	command.  (See <xref linkend="sec:undo:rollback-after-push"/>
-	for an important caveat about the use of this command.)</para>
-
-      <para id="x_d5">Here's a mistake that I often find myself making:
-	committing a change in which I've created a new file, but
-	forgotten to <command role="hg-cmd">hg add</command>
-	it.</para>
-
-      &interaction.rollback.commit;
-
-      <para id="x_d6">Looking at the output of <command role="hg-cmd">hg
-	  status</command> after the commit immediately confirms the
-	error.</para>
-
-      &interaction.rollback.status;
-
-      <para id="x_d7">The commit captured the changes to the file
-	<filename>a</filename>, but not the new file
-	<filename>b</filename>.  If I were to push this changeset to a
-	repository that I shared with a colleague, the chances are
-	high that something in <filename>a</filename> would refer to
-	<filename>b</filename>, which would not be present in their
-	repository when they pulled my changes.  I would thus become
-	the object of some indignation.</para>
-
-      <para id="x_d8">However, luck is with me&emdash;I've caught my error
-	before I pushed the changeset.  I use the <command
-	  role="hg-cmd">hg rollback</command> command, and Mercurial
-	makes that last changeset vanish.</para>
-
-      &interaction.rollback.rollback;
-
-      <para id="x_d9">Notice that the changeset is no longer present in the
-	repository's history, and the working directory once again
-	thinks that the file <filename>a</filename> is modified.  The
-	commit and rollback have left the working directory exactly as
-	it was prior to the commit; the changeset has been completely
-	erased.  I can now safely <command role="hg-cmd">hg
-	  add</command> the file <filename>b</filename>, and rerun my
-	commit.</para>
-
-      &interaction.rollback.add;
-
-    </sect2>
-    <sect2>
-      <title>The erroneous pull</title>
-
-      <para id="x_da">It's common practice with Mercurial to maintain separate
-	development branches of a project in different repositories.
-	Your development team might have one shared repository for
-	your project's <quote>0.9</quote> release, and another,
-	containing different changes, for the <quote>1.0</quote>
-	release.</para>
-
-      <para id="x_db">Given this, you can imagine that the consequences could be
-	messy if you had a local <quote>0.9</quote> repository, and
-	accidentally pulled changes from the shared <quote>1.0</quote>
-	repository into it.  At worst, you could be paying
-	insufficient attention, and push those changes into the shared
-	<quote>0.9</quote> tree, confusing your entire team (but don't
-	worry, we'll return to this horror scenario later).  However,
-	it's more likely that you'll notice immediately, because
-	Mercurial will display the URL it's pulling from, or you will
-	see it pull a suspiciously large number of changes into the
-	repository.</para>
-
-      <para id="x_dc">The <command role="hg-cmd">hg rollback</command> command
-	will work nicely to expunge all of the changesets that you
-	just pulled.  Mercurial groups all changes from one <command
-	  role="hg-cmd">hg pull</command> into a single transaction,
-	so one <command role="hg-cmd">hg rollback</command> is all you
-	need to undo this mistake.</para>
-
-    </sect2>
-    <sect2 id="sec:undo:rollback-after-push">
-      <title>Rolling back is useless once you've pushed</title>
-
-      <para id="x_dd">The value of the <command role="hg-cmd">hg
-	  rollback</command> command drops to zero once you've pushed
-	your changes to another repository.  Rolling back a change
-	makes it disappear entirely, but <emphasis>only</emphasis> in
-	the repository in which you perform the <command
-	  role="hg-cmd">hg rollback</command>.  Because a rollback
-	eliminates history, there's no way for the disappearance of a
-	change to propagate between repositories.</para>
-
-      <para id="x_de">If you've pushed a change to another
-	repository&emdash;particularly if it's a shared
-	repository&emdash;it has essentially <quote>escaped into the
-	  wild,</quote> and you'll have to recover from your mistake
-	in a different way.  If you push a changeset somewhere, then
-	roll it back, then pull from the repository you pushed to, the
-	changeset you thought you'd gotten rid of will simply reappear
-	in your repository.</para>
-
-      <para id="x_df">(If you absolutely know for sure that the change
-	you want to roll back is the most recent change in the
-	repository that you pushed to, <emphasis>and</emphasis> you
-	know that nobody else could have pulled it from that
-	repository, you can roll back the changeset there, too, but
-	you really should not expect this to work reliably.  Sooner or
-	later a change really will make it into a repository that you
-	don't directly control (or have forgotten about), and come
-	back to bite you.)</para>
-
-    </sect2>
-    <sect2>
-      <title>You can only roll back once</title>
-
-      <para id="x_e0">Mercurial stores exactly one transaction in its
-	transaction log; that transaction is the most recent one that
-	occurred in the repository. This means that you can only roll
-	back one transaction.  If you expect to be able to roll back
-	one transaction, then its predecessor, this is not the
-	behavior you will get.</para>
-
-      &interaction.rollback.twice;
-
-      <para id="x_e1">Once you've rolled back one transaction in a repository,
-	you can't roll back again in that repository until you perform
-	another commit or pull.</para>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Reverting the mistaken change</title>
-
-    <para id="x_e2">If you make a modification to a file, and decide that you
-      really didn't want to change the file at all, and you haven't
-      yet committed your changes, the <command role="hg-cmd">hg
-	revert</command> command is the one you'll need.  It looks at
-      the changeset that's the parent of the working directory, and
-      restores the contents of the file to their state as of that
-      changeset. (That's a long-winded way of saying that, in the
-      normal case, it undoes your modifications.)</para>
-
-    <para id="x_e3">Let's illustrate how the <command role="hg-cmd">hg
-	revert</command> command works with yet another small example.
-      We'll begin by modifying a file that Mercurial is already
-      tracking.</para>
-
-    &interaction.daily.revert.modify;
-
-    <para id="x_e4">If we don't
-      want that change, we can simply <command role="hg-cmd">hg
-	revert</command> the file.</para>
-
-      &interaction.daily.revert.unmodify;
-
-    <para id="x_e5">The <command role="hg-cmd">hg revert</command> command
-      provides us with an extra degree of safety by saving our
-      modified file with a <filename>.orig</filename>
-      extension.</para>
-
-    &interaction.daily.revert.status;
-
-    <tip>
-      <title>Be careful with <filename>.orig</filename> files</title>
-
-      <para id="x_6b8">It's extremely unlikely that you are either using
-	Mercurial to manage files with <filename>.orig</filename>
-	extensions or that you even care about the contents of such
-	files.  Just in case, though, it's useful to remember that
-	<command role="hg-cmd">hg revert</command> will
-	unconditionally overwrite an existing file with a
-	<filename>.orig</filename> extension. For instance, if you
-	already have a file named <filename>foo.orig</filename> when
-	you revert <filename>foo</filename>, the contents of
-	<filename>foo.orig</filename> will be clobbered.</para>
-    </tip>
-
-    <para id="x_e6">Here is a summary of the cases that the <command
-	role="hg-cmd">hg revert</command> command can deal with.  We
-      will describe each of these in more detail in the section that
-      follows.</para>
-    <itemizedlist>
-      <listitem><para id="x_e7">If you modify a file, it will restore the file
-	  to its unmodified state.</para>
-      </listitem>
-      <listitem><para id="x_e8">If you <command role="hg-cmd">hg add</command> a
-	  file, it will undo the <quote>added</quote> state of the
-	  file, but leave the file itself untouched.</para>
-      </listitem>
-      <listitem><para id="x_e9">If you delete a file without telling Mercurial,
-	  it will restore the file to its unmodified contents.</para>
-      </listitem>
-      <listitem><para id="x_ea">If you use the <command role="hg-cmd">hg
-	    remove</command> command to remove a file, it will undo
-	  the <quote>removed</quote> state of the file, and restore
-	  the file to its unmodified contents.</para>
-      </listitem></itemizedlist>
-
-    <sect2 id="sec:undo:mgmt">
-      <title>File management errors</title>
-
-      <para id="x_eb">The <command role="hg-cmd">hg revert</command> command is
-	useful for more than just modified files.  It lets you reverse
-	the results of all of Mercurial's file management
-	commands&emdash;<command role="hg-cmd">hg add</command>,
-	<command role="hg-cmd">hg remove</command>, and so on.</para>
-
-      <para id="x_ec">If you <command role="hg-cmd">hg add</command> a file,
-	then decide that in fact you don't want Mercurial to track it,
-	use <command role="hg-cmd">hg revert</command> to undo the
-	add.  Don't worry; Mercurial will not modify the file in any
-	way.  It will just <quote>unmark</quote> the file.</para>
-
-      &interaction.daily.revert.add;
-
-      <para id="x_ed">Similarly, if you ask Mercurial to <command
-	  role="hg-cmd">hg remove</command> a file, you can use
-	<command role="hg-cmd">hg revert</command> to restore it to
-	the contents it had as of the parent of the working directory.
-	&interaction.daily.revert.remove; This works just as
-	well for a file that you deleted by hand, without telling
-	Mercurial (recall that in Mercurial terminology, this kind of
-	file is called <quote>missing</quote>).</para>
-
-      &interaction.daily.revert.missing;
-
-      <para id="x_ee">If you revert a <command role="hg-cmd">hg copy</command>,
-	the copied-to file remains in your working directory
-	afterwards, untracked.  Since a copy doesn't affect the
-	copied-from file in any way, Mercurial doesn't do anything
-	with the copied-from file.</para>
-
-      &interaction.daily.revert.copy;
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>Dealing with committed changes</title>
-
-    <para id="x_f5">Consider a case where you have committed a change
-      <emphasis>a</emphasis>, and another change
-      <emphasis>b</emphasis> on top of it; you then realise that
-      change <emphasis>a</emphasis> was incorrect.  Mercurial lets you
-      <quote>back out</quote> an entire changeset automatically, and
-      building blocks that let you reverse part of a changeset by
-      hand.</para>
-
-    <para id="x_f6">Before you read this section, here's something to
-      keep in mind: the <command role="hg-cmd">hg backout</command>
-      command undoes the effect of a change by
-      <emphasis>adding</emphasis> to your repository's history, not by
-      modifying or erasing it.  It's the right tool to use if you're
-      fixing bugs, but not if you're trying to undo some change that
-      has catastrophic consequences.  To deal with those, see
-      <xref linkend="sec:undo:aaaiiieee"/>.</para>
-
-    <sect2>
-      <title>Backing out a changeset</title>
-
-      <para id="x_f7">The <command role="hg-cmd">hg backout</command> command
-	lets you <quote>undo</quote> the effects of an entire
-	changeset in an automated fashion.  Because Mercurial's
-	history is immutable, this command <emphasis>does
-	  not</emphasis> get rid of the changeset you want to undo.
-	Instead, it creates a new changeset that
-	<emphasis>reverses</emphasis> the effect of the to-be-undone
-	changeset.</para>
-
-      <para id="x_f8">The operation of the <command role="hg-cmd">hg
-	  backout</command> command is a little intricate, so let's
-	illustrate it with some examples.  First, we'll create a
-	repository with some simple changes.</para>
-
-      &interaction.backout.init;
-
-      <para id="x_f9">The <command role="hg-cmd">hg backout</command> command
-	takes a single changeset ID as its argument; this is the
-	changeset to back out.  Normally, <command role="hg-cmd">hg
-	  backout</command> will drop you into a text editor to write
-	a commit message, so you can record why you're backing the
-	change out.  In this example, we provide a commit message on
-	the command line using the <option
-	  role="hg-opt-backout">-m</option> option.</para>
-
-    </sect2>
-    <sect2>
-      <title>Backing out the tip changeset</title>
-
-      <para id="x_fa">We're going to start by backing out the last changeset we
-	committed.</para>
-
-      &interaction.backout.simple;
-
-      <para id="x_fb">You can see that the second line from
-	<filename>myfile</filename> is no longer present.  Taking a
-	look at the output of <command role="hg-cmd">hg log</command>
-	gives us an idea of what the <command role="hg-cmd">hg
-	  backout</command> command has done.
-	&interaction.backout.simple.log; Notice that the new changeset
-	that <command role="hg-cmd">hg backout</command> has created
-	is a child of the changeset we backed out.  It's easier to see
-	this in <xref linkend="fig:undo:backout"/>, which presents a
-	graphical view of the change history.  As you can see, the
-	history is nice and linear.</para>
-
-      <figure id="fig:undo:backout">
-	<title>Backing out a change using the <command
-	    role="hg-cmd">hg backout</command> command</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/undo-simple.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-    </sect2>
-    <sect2>
-      <title>Backing out a non-tip change</title>
-
-      <para id="x_fd">If you want to back out a change other than the last one
-	you committed, pass the <option
-	  role="hg-opt-backout">--merge</option> option to the
-	<command role="hg-cmd">hg backout</command> command.</para>
-
-      &interaction.backout.non-tip.clone;
-
-      <para id="x_fe">This makes backing out any changeset a
-	<quote>one-shot</quote> operation that's usually simple and
-	fast.</para>
-
-      &interaction.backout.non-tip.backout;
-
-      <para id="x_ff">If you take a look at the contents of
-	<filename>myfile</filename> after the backout finishes, you'll
-	see that the first and third changes are present, but not the
-	second.</para>
-
-      &interaction.backout.non-tip.cat;
-
-      <para id="x_100">As the graphical history in <xref
-	  linkend="fig:undo:backout-non-tip"/> illustrates, Mercurial
-	still commits one change in this kind of situation (the
-	box-shaped node is the ones that Mercurial commits
-	automatically), but the revision graph now looks different.
-	Before Mercurial begins the backout process, it first
-	remembers what the current parent of the working directory is.
-	It then backs out the target changeset, and commits that as a
-	changeset.  Finally, it merges back to the previous parent of
-	the working directory, but notice that it <emphasis>does not
-	  commit</emphasis> the result of the merge.  The repository
-	now contains two heads, and the working directory is in a
-	merge state.</para>
-
-      <figure id="fig:undo:backout-non-tip">
-	<title>Automated backout of a non-tip change using the
-	  <command role="hg-cmd">hg backout</command> command</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/undo-non-tip.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_103">The result is that you end up <quote>back where you
-	  were</quote>, only with some extra history that undoes the
-	effect of the changeset you wanted to back out.</para>
-
-      <para id="x_6b9">You might wonder why Mercurial does not commit the result
-	of the merge that it performed.  The reason lies in Mercurial
-	behaving conservatively: a merge naturally has more scope for
-	error than simply undoing the effect of the tip changeset,
-	so your work will be safest if you first inspect (and test!)
-	the result of the merge, <emphasis>then</emphasis> commit
-	it.</para>
-
-      <sect3>
-	<title>Always use the <option
-	    role="hg-opt-backout">--merge</option> option</title>
-
-	<para id="x_104">In fact, since the <option
-	    role="hg-opt-backout">--merge</option> option will do the
-	  <quote>right thing</quote> whether or not the changeset
-	  you're backing out is the tip (i.e. it won't try to merge if
-	  it's backing out the tip, since there's no need), you should
-	  <emphasis>always</emphasis> use this option when you run the
-	  <command role="hg-cmd">hg backout</command> command.</para>
-
-      </sect3>
-    </sect2>
-    <sect2>
-      <title>Gaining more control of the backout process</title>
-
-      <para id="x_105">While I've recommended that you always use the <option
-	  role="hg-opt-backout">--merge</option> option when backing
-	out a change, the <command role="hg-cmd">hg backout</command>
-	command lets you decide how to merge a backout changeset.
-	Taking control of the backout process by hand is something you
-	will rarely need to do, but it can be useful to understand
-	what the <command role="hg-cmd">hg backout</command> command
-	is doing for you automatically.  To illustrate this, let's
-	clone our first repository, but omit the backout change that
-	it contains.</para>
-
-      &interaction.backout.manual.clone;
-
-      <para id="x_106">As with our
-	earlier example, We'll commit a third changeset, then back out
-	its parent, and see what happens.</para>
-
-      &interaction.backout.manual.backout;
-
-      <para id="x_107">Our new changeset is again a descendant of the changeset
-	we backout out; it's thus a new head, <emphasis>not</emphasis>
-	a descendant of the changeset that was the tip.  The <command
-	  role="hg-cmd">hg backout</command> command was quite
-	explicit in telling us this.</para>
-
-      &interaction.backout.manual.log;
-
-      <para id="x_108">Again, it's easier to see what has happened by looking at
-	a graph of the revision history, in <xref
-	  linkend="fig:undo:backout-manual"/>.  This makes it clear
-	that when we use <command role="hg-cmd">hg backout</command>
-	to back out a change other than the tip, Mercurial adds a new
-	head to the repository (the change it committed is
-	box-shaped).</para>
-
-      <figure id="fig:undo:backout-manual">
-	<title>Backing out a change using the <command
-	    role="hg-cmd">hg backout</command> command</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/undo-manual.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_10a">After the <command role="hg-cmd">hg backout</command>
-	command has completed, it leaves the new
-	<quote>backout</quote> changeset as the parent of the working
-	directory.</para>
-
-      &interaction.backout.manual.parents;
-
-      <para id="x_10b">Now we have two isolated sets of changes.</para>
-
-      &interaction.backout.manual.heads;
-
-      <para id="x_10c">Let's think about what we expect to see as the contents of
-	<filename>myfile</filename> now.  The first change should be
-	present, because we've never backed it out.  The second change
-	should be missing, as that's the change we backed out.  Since
-	the history graph shows the third change as a separate head,
-	we <emphasis>don't</emphasis> expect to see the third change
-	present in <filename>myfile</filename>.</para>
-
-      &interaction.backout.manual.cat;
-
-      <para id="x_10d">To get the third change back into the file, we just do a
-	normal merge of our two heads.</para>
-
-      &interaction.backout.manual.merge;
-
-      <para id="x_10e">Afterwards, the graphical history of our
-	repository looks like
-	<xref linkend="fig:undo:backout-manual-merge"/>.</para>
-
-      <figure id="fig:undo:backout-manual-merge">
-	<title>Manually merging a backout change</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/undo-manual-merge.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-    </sect2>
-    <sect2>
-      <title>Why <command role="hg-cmd">hg backout</command> works as
-	it does</title>
-
-      <para id="x_110">Here's a brief description of how the <command
-	  role="hg-cmd">hg backout</command> command works.</para>
-      <orderedlist>
-	<listitem><para id="x_111">It ensures that the working directory is
-	    <quote>clean</quote>, i.e. that the output of <command
-	      role="hg-cmd">hg status</command> would be empty.</para>
-	</listitem>
-	<listitem><para id="x_112">It remembers the current parent of the working
-	    directory.  Let's call this changeset
-	    <literal>orig</literal>.</para>
-	</listitem>
-	<listitem><para id="x_113">It does the equivalent of a <command
-	      role="hg-cmd">hg update</command> to sync the working
-	    directory to the changeset you want to back out.  Let's
-	    call this changeset <literal>backout</literal>.</para>
-	</listitem>
-	<listitem><para id="x_114">It finds the parent of that changeset.  Let's
-	    call that changeset <literal>parent</literal>.</para>
-	</listitem>
-	<listitem><para id="x_115">For each file that the
-	    <literal>backout</literal> changeset affected, it does the
-	    equivalent of a <command role="hg-cmd">hg revert -r
-	      parent</command> on that file, to restore it to the
-	    contents it had before that changeset was
-	    committed.</para>
-	</listitem>
-	<listitem><para id="x_116">It commits the result as a new changeset.
-	    This changeset has <literal>backout</literal> as its
-	    parent.</para>
-	</listitem>
-	<listitem><para id="x_117">If you specify <option
-	      role="hg-opt-backout">--merge</option> on the command
-	    line, it merges with <literal>orig</literal>, and commits
-	    the result of the merge.</para>
-	</listitem></orderedlist>
-
-      <para id="x_118">An alternative way to implement the <command
-	  role="hg-cmd">hg backout</command> command would be to
-	<command role="hg-cmd">hg export</command> the
-	to-be-backed-out changeset as a diff, then use the <option
-	  role="cmd-opt-patch">--reverse</option> option to the
-	<command>patch</command> command to reverse the effect of the
-	change without fiddling with the working directory.  This
-	sounds much simpler, but it would not work nearly as
-	well.</para>
-
-      <para id="x_119">The reason that <command role="hg-cmd">hg
-	  backout</command> does an update, a commit, a merge, and
-	another commit is to give the merge machinery the best chance
-	to do a good job when dealing with all the changes
-	<emphasis>between</emphasis> the change you're backing out and
-	the current tip.</para>
-
-      <para id="x_11a">If you're backing out a changeset that's 100 revisions
-	back in your project's history, the chances that the
-	<command>patch</command> command will be able to apply a
-	reverse diff cleanly are not good, because intervening changes
-	are likely to have <quote>broken the context</quote> that
-	<command>patch</command> uses to determine whether it can
-	apply a patch (if this sounds like gibberish, see <xref
-	  linkend="sec:mq:patch"/> for a
-	discussion of the <command>patch</command> command).  Also,
-	Mercurial's merge machinery will handle files and directories
-	being renamed, permission changes, and modifications to binary
-	files, none of which <command>patch</command> can deal
-	with.</para>
-
-    </sect2>
-  </sect1>
-  <sect1 id="sec:undo:aaaiiieee">
-    <title>Changes that should never have been</title>
-
-    <para id="x_11b">Most of the time, the <command role="hg-cmd">hg
-	backout</command> command is exactly what you need if you want
-      to undo the effects of a change.  It leaves a permanent record
-      of exactly what you did, both when committing the original
-      changeset and when you cleaned up after it.</para>
-
-    <para id="x_11c">On rare occasions, though, you may find that you've
-      committed a change that really should not be present in the
-      repository at all.  For example, it would be very unusual, and
-      usually considered a mistake, to commit a software project's
-      object files as well as its source files.  Object files have
-      almost no intrinsic value, and they're <emphasis>big</emphasis>,
-      so they increase the size of the repository and the amount of
-      time it takes to clone or pull changes.</para>
-
-    <para id="x_11d">Before I discuss the options that you have if you commit a
-      <quote>brown paper bag</quote> change (the kind that's so bad
-      that you want to pull a brown paper bag over your head), let me
-      first discuss some approaches that probably won't work.</para>
-
-    <para id="x_11e">Since Mercurial treats history as
-      accumulative&emdash;every change builds on top of all changes
-      that preceded it&emdash;you generally can't just make disastrous
-      changes disappear.  The one exception is when you've just
-      committed a change, and it hasn't been pushed or pulled into
-      another repository.  That's when you can safely use the <command
-	role="hg-cmd">hg rollback</command> command, as I detailed in
-      <xref linkend="sec:undo:rollback"/>.</para>
-
-    <para id="x_11f">After you've pushed a bad change to another repository, you
-      <emphasis>could</emphasis> still use <command role="hg-cmd">hg
-	rollback</command> to make your local copy of the change
-      disappear, but it won't have the consequences you want.  The
-      change will still be present in the remote repository, so it
-      will reappear in your local repository the next time you
-      pull.</para>
-
-    <para id="x_120">If a situation like this arises, and you know which
-      repositories your bad change has propagated into, you can
-      <emphasis>try</emphasis> to get rid of the change from
-      <emphasis>every</emphasis> one of those repositories.  This is,
-      of course, not a satisfactory solution: if you miss even a
-      single repository while you're expunging, the change is still
-      <quote>in the wild</quote>, and could propagate further.</para>
-
-    <para id="x_121">If you've committed one or more changes
-      <emphasis>after</emphasis> the change that you'd like to see
-      disappear, your options are further reduced. Mercurial doesn't
-      provide a way to <quote>punch a hole</quote> in history, leaving
-      changesets intact.</para>
-
-    <sect2>
-      <title>Backing out a merge</title>
-
-      <para id="x_6ba">Since merges are often complicated, it is not unheard of
-	for a merge to be mangled badly, but committed erroneously.
-	Mercurial provides an important safeguard against bad merges
-	by refusing to commit unresolved files, but human ingenuity
-	guarantees that it is still possible to mess a merge up and
-	commit it.</para>
-
-      <para id="x_6bb">Given a bad merge that has been committed, usually the
-	best way to approach it is to simply try to repair the damage
-	by hand.  A complete disaster that cannot be easily fixed up
-	by hand ought to be very rare, but the <command
-	  role="hg-cmd">hg backout</command> command may help in
-	making the cleanup easier. It offers a <option
-	  role="hg-opt-backout">--parent</option> option, which lets
-	you specify which parent to revert to when backing out a
-	merge.</para>
-
-      <figure id="fig:undo:bad-merge-1">
-	<title>A bad merge</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/bad-merge-1.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_6bc">Suppose we have a revision graph like that in <xref
-	  linkend="fig:undo:bad-merge-1"/>.  What we'd like is to
-	<emphasis>redo</emphasis> the merge of revisions 2 and
-	3.</para>
-
-      <para id="x_6bd">One way to do so would be as follows.</para>
-
-      <orderedlist>
-	<listitem>
-	  <para id="x_6be">Call <command role="hg-cmd">hg backout --rev=4
-	      --parent=2</command>.  This tells <command
-	      role="hg-cmd">hg backout</command> to back out revision
-	    4, which is the bad merge, and to when deciding which
-	    revision to prefer, to choose parent 2, one of the parents
-	    of the merge.  The effect can be seen in <xref
-	      linkend="fig:undo:bad-merge-2"/>.</para>
-	  <figure id="fig:undo:bad-merge-2">
-	    <title>Backing out the merge, favoring one parent</title>
-	    <mediaobject>
-	      <imageobject><imagedata fileref="figs/bad-merge-2.png"/></imageobject>
-	      <textobject><phrase>XXX add text</phrase></textobject>
-	    </mediaobject>
-	  </figure>
-	</listitem>
-
-	<listitem>
-	  <para id="x_6bf">Call <command role="hg-cmd">hg backout --rev=4
-	      --parent=3</command>.  This tells <command
-	      role="hg-cmd">hg backout</command> to back out revision
-	    4 again, but this time to choose parent 3, the other
-	    parent of the merge.  The result is visible in <xref
-	    linkend="fig:undo:bad-merge-3"/>, in which the repository
-	    now contains three heads.</para>
-	  <figure id="fig:undo:bad-merge-3">
-	    <title>Backing out the merge, favoring the other
-	      parent</title>
-	    <mediaobject>
-	      <imageobject><imagedata fileref="figs/bad-merge-3.png"/></imageobject>
-	      <textobject><phrase>XXX add text</phrase></textobject>
-	    </mediaobject>
-	  </figure>
-	</listitem>
-
-	<listitem>
-	  <para id="x_6c0">Redo the bad merge by merging the two backout heads,
-	    which reduces the number of heads in the repository to
-	    two, as can be seen in <xref
-	      linkend="fig:undo:bad-merge-4"/>.</para>
-	  <figure id="fig:undo:bad-merge-4">
-	    <title>Merging the backouts</title>
-	    <mediaobject>
-	      <imageobject><imagedata fileref="figs/bad-merge-4.png"/></imageobject>
-	      <textobject><phrase>XXX add text</phrase></textobject>
-	    </mediaobject>
-	  </figure>
-	</listitem>
-
-	<listitem>
-	  <para id="x_6c1">Merge with the commit that was made after the bad
-	    merge, as shown in <xref
-	      linkend="fig:undo:bad-merge-5"/>.</para>
-	  <figure id="fig:undo:bad-merge-5">
-	    <title>Merging the backouts</title>
-	    <mediaobject>
-	      <imageobject><imagedata fileref="figs/bad-merge-5.png"/></imageobject>
-	      <textobject><phrase>XXX add text</phrase></textobject>
-	    </mediaobject>
-	  </figure>
-	</listitem>
-      </orderedlist>
-    </sect2>
-
-    <sect2>
-      <title>Protect yourself from <quote>escaped</quote>
-	changes</title>
-
-      <para id="x_123">If you've committed some changes to your local repository
-	and they've been pushed or pulled somewhere else, this isn't
-	necessarily a disaster.  You can protect yourself ahead of
-	time against some classes of bad changeset.  This is
-	particularly easy if your team usually pulls changes from a
-	central repository.</para>
-
-      <para id="x_124">By configuring some hooks on that repository to validate
-	incoming changesets (see chapter <xref linkend="chap:hook"/>),
-	you can
-	automatically prevent some kinds of bad changeset from being
-	pushed to the central repository at all.  With such a
-	configuration in place, some kinds of bad changeset will
-	naturally tend to <quote>die out</quote> because they can't
-	propagate into the central repository.  Better yet, this
-	happens without any need for explicit intervention.</para>
-
-      <para id="x_125">For instance, an incoming change hook that
-	verifies that a changeset will actually compile can prevent
-	people from inadvertently <quote>breaking the
-	  build</quote>.</para>
-    </sect2>
-
-    <sect2>
-      <title>What to do about sensitive changes that escape</title>
-
-      <para id="x_6c2">Even a carefully run project can suffer an unfortunate
-	event such as the committing and uncontrolled propagation of a
-	file that contains important passwords.</para>
-
-      <para id="x_6c3">If something like this happens to you, and the information
-	that gets accidentally propagated is truly sensitive, your
-	first step should be to mitigate the effect of the leak
-	without trying to control the leak itself. If you are not 100%
-	certain that you know exactly who could have seen the changes,
-	you should immediately change passwords, cancel credit cards,
-	or find some other way to make sure that the information that
-	has leaked is no longer useful.  In other words, assume that
-	the change has propagated far and wide, and that there's
-	nothing more you can do.</para>
-
-      <para id="x_6c4">You might hope that there would be mechanisms you could
-	use to either figure out who has seen a change or to erase the
-	change permanently everywhere, but there are good reasons why
-	these are not possible.</para>
-
-      <para id="x_6c5">Mercurial does not provide an audit trail of who has
-	pulled changes from a repository, because it is usually either
-	impossible to record such information or trivial to spoof it.
-	In a multi-user or networked environment, you should thus be
-	extremely skeptical of yourself if you think that you have
-	identified every place that a sensitive changeset has
-	propagated to.  Don't forget that people can and will send
-	bundles by email, have their backup software save data
-	offsite, carry repositories on USB sticks, and find other
-	completely innocent ways to confound your attempts to track
-	down every copy of a problematic change.</para>
-
-      <para id="x_6c6">Mercurial also does not provide a way to make a file or
-	changeset completely disappear from history, because there is
-	no way to enforce its disappearance; someone could easily
-	modify their copy of Mercurial to ignore such directives. In
-	addition, even if Mercurial provided such a capability,
-	someone who simply hadn't pulled a <quote>make this file
-	  disappear</quote> changeset wouldn't be affected by it, nor
-	would web crawlers visiting at the wrong time, disk backups,
-	or other mechanisms.  Indeed, no distributed revision control
-	system can make data reliably vanish. Providing the illusion
-	of such control could easily give a false sense of security,
-	and be worse than not providing it at all.</para>
-    </sect2>
-  </sect1>
-
-  <sect1 id="sec:undo:bisect">
-    <title>Finding the source of a bug</title>
-
-    <para id="x_126">While it's all very well to be able to back out a changeset
-      that introduced a bug, this requires that you know which
-      changeset to back out.  Mercurial provides an invaluable
-      command, called <command role="hg-cmd">hg bisect</command>, that
-      helps you to automate this process and accomplish it very
-      efficiently.</para>
-
-    <para id="x_127">The idea behind the <command role="hg-cmd">hg
-	bisect</command> command is that a changeset has introduced
-      some change of behavior that you can identify with a simple
-      pass/fail test.  You don't know which piece of code introduced the
-      change, but you know how to test for the presence of the bug.
-      The <command role="hg-cmd">hg bisect</command> command uses your
-      test to direct its search for the changeset that introduced the
-      code that caused the bug.</para>
-
-    <para id="x_128">Here are a few scenarios to help you understand how you
-      might apply this command.</para>
-    <itemizedlist>
-      <listitem><para id="x_129">The most recent version of your software has a
-	  bug that you remember wasn't present a few weeks ago, but
-	  you don't know when it was introduced.  Here, your binary
-	  test checks for the presence of that bug.</para>
-      </listitem>
-      <listitem><para id="x_12a">You fixed a bug in a rush, and now it's time to
-	  close the entry in your team's bug database.  The bug
-	  database requires a changeset ID when you close an entry,
-	  but you don't remember which changeset you fixed the bug in.
-	  Once again, your binary test checks for the presence of the
-	  bug.</para>
-      </listitem>
-      <listitem><para id="x_12b">Your software works correctly, but runs 15%
-	  slower than the last time you measured it.  You want to know
-	  which changeset introduced the performance regression.  In
-	  this case, your binary test measures the performance of your
-	  software, to see whether it's <quote>fast</quote> or
-	  <quote>slow</quote>.</para>
-      </listitem>
-      <listitem><para id="x_12c">The sizes of the components of your project that
-	  you ship exploded recently, and you suspect that something
-	  changed in the way you build your project.</para>
-      </listitem></itemizedlist>
-
-    <para id="x_12d">From these examples, it should be clear that the <command
-	role="hg-cmd">hg bisect</command> command is not useful only
-      for finding the sources of bugs.  You can use it to find any
-      <quote>emergent property</quote> of a repository (anything that
-      you can't find from a simple text search of the files in the
-      tree) for which you can write a binary test.</para>
-
-    <para id="x_12e">We'll introduce a little bit of terminology here, just to
-      make it clear which parts of the search process are your
-      responsibility, and which are Mercurial's.  A
-      <emphasis>test</emphasis> is something that
-      <emphasis>you</emphasis> run when <command role="hg-cmd">hg
-	bisect</command> chooses a changeset.  A
-      <emphasis>probe</emphasis> is what <command role="hg-cmd">hg
-	bisect</command> runs to tell whether a revision is good.
-      Finally, we'll use the word <quote>bisect</quote>, as both a
-      noun and a verb, to stand in for the phrase <quote>search using
-	the <command role="hg-cmd">hg bisect</command>
-	command</quote>.</para>
-
-    <para id="x_12f">One simple way to automate the searching process would be
-      simply to probe every changeset.  However, this scales poorly.
-      If it took ten minutes to test a single changeset, and you had
-      10,000 changesets in your repository, the exhaustive approach
-      would take on average 35 <emphasis>days</emphasis> to find the
-      changeset that introduced a bug.  Even if you knew that the bug
-      was introduced by one of the last 500 changesets, and limited
-      your search to those, you'd still be looking at over 40 hours to
-      find the changeset that introduced your bug.</para>
-
-    <para id="x_130">What the <command role="hg-cmd">hg bisect</command> command
-      does is use its knowledge of the <quote>shape</quote> of your
-      project's revision history to perform a search in time
-      proportional to the <emphasis>logarithm</emphasis> of the number
-      of changesets to check (the kind of search it performs is called
-      a dichotomic search).  With this approach, searching through
-      10,000 changesets will take less than three hours, even at ten
-      minutes per test (the search will require about 14 tests).
-      Limit your search to the last hundred changesets, and it will
-      take only about an hour (roughly seven tests).</para>
-
-    <para id="x_131">The <command role="hg-cmd">hg bisect</command> command is
-      aware of the <quote>branchy</quote> nature of a Mercurial
-      project's revision history, so it has no problems dealing with
-      branches, merges, or multiple heads in a repository.  It can
-      prune entire branches of history with a single probe, which is
-      how it operates so efficiently.</para>
-
-    <sect2>
-      <title>Using the <command role="hg-cmd">hg bisect</command>
-	command</title>
-
-      <para id="x_132">Here's an example of <command role="hg-cmd">hg
-	  bisect</command> in action.</para>
-
-      <note>
-	<para id="x_133">  In versions 0.9.5 and earlier of Mercurial, <command
-	    role="hg-cmd">hg bisect</command> was not a core command:
-	  it was distributed with Mercurial as an extension. This
-	  section describes the built-in command, not the old
-	  extension.</para>
-      </note>
-
-      <para id="x_134">Now let's create a repository, so that we can try out the
-	<command role="hg-cmd">hg bisect</command> command in
-	isolation.</para>
-
-      &interaction.bisect.init;
-
-      <para id="x_135">We'll simulate a project that has a bug in it in a
-	simple-minded way: create trivial changes in a loop, and
-	nominate one specific change that will have the
-	<quote>bug</quote>.  This loop creates 35 changesets, each
-	adding a single file to the repository. We'll represent our
-	<quote>bug</quote> with a file that contains the text <quote>i
-	  have a gub</quote>.</para>
-
-      &interaction.bisect.commits;
-
-      <para id="x_136">The next thing that we'd like to do is figure out how to
-	use the <command role="hg-cmd">hg bisect</command> command.
-	We can use Mercurial's normal built-in help mechanism for
-	this.</para>
-
-      &interaction.bisect.help;
-
-      <para id="x_137">The <command role="hg-cmd">hg bisect</command> command
-	works in steps.  Each step proceeds as follows.</para>
-      <orderedlist>
-	<listitem><para id="x_138">You run your binary test.</para>
-	  <itemizedlist>
-	    <listitem><para id="x_139">If the test succeeded, you tell <command
-		  role="hg-cmd">hg bisect</command> by running the
-		<command role="hg-cmd">hg bisect --good</command>
-		command.</para>
-	    </listitem>
-	    <listitem><para id="x_13a">If it failed, run the <command
-		  role="hg-cmd">hg bisect --bad</command>
-		command.</para></listitem></itemizedlist>
-	</listitem>
-	<listitem><para id="x_13b">The command uses your information to decide
-	    which changeset to test next.</para>
-	</listitem>
-	<listitem><para id="x_13c">It updates the working directory to that
-	    changeset, and the process begins again.</para>
-	</listitem></orderedlist>
-      <para id="x_13d">The process ends when <command role="hg-cmd">hg
-	  bisect</command> identifies a unique changeset that marks
-	the point where your test transitioned from
-	<quote>succeeding</quote> to <quote>failing</quote>.</para>
-
-      <para id="x_13e">To start the search, we must run the <command
-	  role="hg-cmd">hg bisect --reset</command> command.</para>
-
-      &interaction.bisect.search.init;
-
-      <para id="x_13f">In our case, the binary test we use is simple: we check to
-	see if any file in the repository contains the string <quote>i
-	  have a gub</quote>.  If it does, this changeset contains the
-	change that <quote>caused the bug</quote>.  By convention, a
-	changeset that has the property we're searching for is
-	<quote>bad</quote>, while one that doesn't is
-	<quote>good</quote>.</para>
-
-      <para id="x_140">Most of the time, the revision to which the working
-	directory is synced (usually the tip) already exhibits the
-	problem introduced by the buggy change, so we'll mark it as
-	<quote>bad</quote>.</para>
-
-      &interaction.bisect.search.bad-init;
-
-      <para id="x_141">Our next task is to nominate a changeset that we know
-	<emphasis>doesn't</emphasis> have the bug; the <command
-	  role="hg-cmd">hg bisect</command> command will
-	<quote>bracket</quote> its search between the first pair of
-	good and bad changesets.  In our case, we know that revision
-	10 didn't have the bug.  (I'll have more words about choosing
-	the first <quote>good</quote> changeset later.)</para>
-
-      &interaction.bisect.search.good-init;
-
-      <para id="x_142">Notice that this command printed some output.</para>
-      <itemizedlist>
-	<listitem><para id="x_143">It told us how many changesets it must
-	    consider before it can identify the one that introduced
-	    the bug, and how many tests that will require.</para>
-	</listitem>
-	<listitem><para id="x_144">It updated the working directory to the next
-	    changeset to test, and told us which changeset it's
-	    testing.</para>
-	</listitem></itemizedlist>
-
-      <para id="x_145">We now run our test in the working directory.  We use the
-	<command>grep</command> command to see if our
-	<quote>bad</quote> file is present in the working directory.
-	If it is, this revision is bad; if not, this revision is good.
-	&interaction.bisect.search.step1;</para>
-
-      <para id="x_146">This test looks like a perfect candidate for automation,
-	so let's turn it into a shell function.</para>
-      &interaction.bisect.search.mytest;
-
-      <para id="x_147">We can now run an entire test step with a single command,
-	<literal>mytest</literal>.</para>
-
-      &interaction.bisect.search.step2;
-
-      <para id="x_148">A few more invocations of our canned test step command,
-	and we're done.</para>
-
-      &interaction.bisect.search.rest;
-
-      <para id="x_149">Even though we had 40 changesets to search through, the
-	<command role="hg-cmd">hg bisect</command> command let us find
-	the changeset that introduced our <quote>bug</quote> with only
-	five tests.  Because the number of tests that the <command
-	  role="hg-cmd">hg bisect</command> command performs grows
-	logarithmically with the number of changesets to search, the
-	advantage that it has over the <quote>brute force</quote>
-	search approach increases with every changeset you add.</para>
-
-    </sect2>
-    <sect2>
-      <title>Cleaning up after your search</title>
-
-      <para id="x_14a">When you're finished using the <command role="hg-cmd">hg
-	  bisect</command> command in a repository, you can use the
-	<command role="hg-cmd">hg bisect --reset</command> command to
-	drop the information it was using to drive your search.  The
-	command doesn't use much space, so it doesn't matter if you
-	forget to run this command.  However, <command
-	  role="hg-cmd">hg bisect</command> won't let you start a new
-	search in that repository until you do a <command
-	  role="hg-cmd">hg bisect --reset</command>.</para>
-
-      &interaction.bisect.search.reset;
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Tips for finding bugs effectively</title>
-
-    <sect2>
-      <title>Give consistent input</title>
-
-      <para id="x_14b">The <command role="hg-cmd">hg bisect</command> command
-	requires that you correctly report the result of every test
-	you perform.  If you tell it that a test failed when it really
-	succeeded, it <emphasis>might</emphasis> be able to detect the
-	inconsistency.  If it can identify an inconsistency in your
-	reports, it will tell you that a particular changeset is both
-	good and bad. However, it can't do this perfectly; it's about
-	as likely to report the wrong changeset as the source of the
-	bug.</para>
-
-    </sect2>
-    <sect2>
-      <title>Automate as much as possible</title>
-
-      <para id="x_14c">When I started using the <command role="hg-cmd">hg
-	  bisect</command> command, I tried a few times to run my
-	tests by hand, on the command line.  This is an approach that
-	I, at least, am not suited to.  After a few tries, I found
-	that I was making enough mistakes that I was having to restart
-	my searches several times before finally getting correct
-	results.</para>
-
-      <para id="x_14d">My initial problems with driving the <command
-	  role="hg-cmd">hg bisect</command> command by hand occurred
-	even with simple searches on small repositories; if the
-	problem you're looking for is more subtle, or the number of
-	tests that <command role="hg-cmd">hg bisect</command> must
-	perform increases, the likelihood of operator error ruining
-	the search is much higher.  Once I started automating my
-	tests, I had much better results.</para>
-
-      <para id="x_14e">The key to automated testing is twofold:</para>
-      <itemizedlist>
-	<listitem><para id="x_14f">always test for the same symptom, and</para>
-	</listitem>
-	<listitem><para id="x_150">always feed consistent input to the <command
-	      role="hg-cmd">hg bisect</command> command.</para>
-	</listitem></itemizedlist>
-      <para id="x_151">In my tutorial example above, the <command>grep</command>
-	command tests for the symptom, and the <literal>if</literal>
-	statement takes the result of this check and ensures that we
-	always feed the same input to the <command role="hg-cmd">hg
-	  bisect</command> command.  The <literal>mytest</literal>
-	function marries these together in a reproducible way, so that
-	every test is uniform and consistent.</para>
-
-    </sect2>
-    <sect2>
-      <title>Check your results</title>
-
-      <para id="x_152">Because the output of a <command role="hg-cmd">hg
-	  bisect</command> search is only as good as the input you
-	give it, don't take the changeset it reports as the absolute
-	truth.  A simple way to cross-check its report is to manually
-	run your test at each of the following changesets:</para>
-      <itemizedlist>
-	<listitem><para id="x_153">The changeset that it reports as the first bad
-	    revision.  Your test should still report this as
-	    bad.</para>
-	</listitem>
-	<listitem><para id="x_154">The parent of that changeset (either parent,
-	    if it's a merge). Your test should report this changeset
-	    as good.</para>
-	</listitem>
-	<listitem><para id="x_155">A child of that changeset.  Your test should
-	    report this changeset as bad.</para>
-	</listitem></itemizedlist>
-
-    </sect2>
-    <sect2>
-      <title>Beware interference between bugs</title>
-
-      <para id="x_156">It's possible that your search for one bug could be
-	disrupted by the presence of another.  For example, let's say
-	your software crashes at revision 100, and worked correctly at
-	revision 50.  Unknown to you, someone else introduced a
-	different crashing bug at revision 60, and fixed it at
-	revision 80.  This could distort your results in one of
-	several ways.</para>
-
-      <para id="x_157">It is possible that this other bug completely
-	<quote>masks</quote> yours, which is to say that it occurs
-	before your bug has a chance to manifest itself.  If you can't
-	avoid that other bug (for example, it prevents your project
-	from building), and so can't tell whether your bug is present
-	in a particular changeset, the <command role="hg-cmd">hg
-	  bisect</command> command cannot help you directly.  Instead,
-	you can mark a changeset as untested by running <command
-	  role="hg-cmd">hg bisect --skip</command>.</para>
-
-      <para id="x_158">A different problem could arise if your test for a bug's
-	presence is not specific enough.  If you check for <quote>my
-	  program crashes</quote>, then both your crashing bug and an
-	unrelated crashing bug that masks it will look like the same
-	thing, and mislead <command role="hg-cmd">hg
-	  bisect</command>.</para>
-
-      <para id="x_159">Another useful situation in which to use <command
-	  role="hg-cmd">hg bisect --skip</command> is if you can't
-	test a revision because your project was in a broken and hence
-	untestable state at that revision, perhaps because someone
-	checked in a change that prevented the project from
-	building.</para>
-
-    </sect2>
-    <sect2>
-      <title>Bracket your search lazily</title>
-
-      <para id="x_15a">Choosing the first <quote>good</quote> and
-	<quote>bad</quote> changesets that will mark the end points of
-	your search is often easy, but it bears a little discussion
-	nevertheless.  From the perspective of <command
-	  role="hg-cmd">hg bisect</command>, the <quote>newest</quote>
-	changeset is conventionally <quote>bad</quote>, and the older
-	changeset is <quote>good</quote>.</para>
-
-      <para id="x_15b">If you're having trouble remembering when a suitable
-	<quote>good</quote> change was, so that you can tell <command
-	  role="hg-cmd">hg bisect</command>, you could do worse than
-	testing changesets at random.  Just remember to eliminate
-	contenders that can't possibly exhibit the bug (perhaps
-	because the feature with the bug isn't present yet) and those
-	where another problem masks the bug (as I discussed
-	above).</para>
-
-      <para id="x_15c">Even if you end up <quote>early</quote> by thousands of
-	changesets or months of history, you will only add a handful
-	of tests to the total number that <command role="hg-cmd">hg
-	  bisect</command> must perform, thanks to its logarithmic
-	behavior.</para>
-
-    </sect2>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- a/en/ch09-hook.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1928 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:hook">
-  <?dbhtml filename="handling-repository-events-with-hooks.html"?>
-  <title>Handling repository events with hooks</title>
-
-  <para id="x_1e6">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.</para>
-
-  <para id="x_1e7">The name Mercurial uses for one of these actions is a
-    <emphasis>hook</emphasis>. Hooks are called
-    <quote>triggers</quote> in some revision control systems, but the
-    two names refer to the same idea.</para>
-
-  <sect1>
-    <title>An overview of hooks in Mercurial</title>
-
-    <para id="x_1e8">Here is a brief list of the hooks that Mercurial
-      supports. We will revisit each of these hooks in more detail
-      later, in <xref linkend="sec:hook:ref"/>.</para>
-
-    <para id="x_1f6">Each of the hooks whose description begins with the word
-      <quote>Controlling</quote> 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.</para>
-
-    <itemizedlist>
-      <listitem><para id="x_1e9"><literal role="hook">changegroup</literal>: This
-	  is run after a group of changesets has been brought into the
-	  repository from elsewhere.</para>
-      </listitem>
-      <listitem><para id="x_1ea"><literal role="hook">commit</literal>: This is
-	  run after a new changeset has been created in the local
-	  repository.</para>
-      </listitem>
-      <listitem><para id="x_1eb"><literal role="hook">incoming</literal>: This is
-	  run once for each new changeset that is brought into the
-	  repository from elsewhere.  Notice the difference from
-	  <literal role="hook">changegroup</literal>, which is run
-	  once per <emphasis>group</emphasis> of changesets brought
-	  in.</para>
-      </listitem>
-      <listitem><para id="x_1ec"><literal role="hook">outgoing</literal>: This is
-	  run after a group of changesets has been transmitted from
-	  this repository.</para>
-      </listitem>
-      <listitem><para id="x_1ed"><literal role="hook">prechangegroup</literal>:
-	  This is run before starting to bring a group of changesets
-	  into the repository.
-	</para>
-      </listitem>
-      <listitem><para id="x_1ee"><literal role="hook">precommit</literal>:
-	  Controlling. This is run before starting a commit.
-	</para>
-      </listitem>
-      <listitem><para id="x_1ef"><literal role="hook">preoutgoing</literal>:
-	  Controlling. This is run before starting to transmit a group
-	  of changesets from this repository.
-	</para>
-      </listitem>
-      <listitem><para id="x_1f0"><literal role="hook">pretag</literal>:
-	  Controlling. This is run before creating a tag.
-	</para>
-      </listitem>
-      <listitem><para id="x_1f1"><literal
-	    role="hook">pretxnchangegroup</literal>: 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.
-	</para>
-      </listitem>
-      <listitem><para id="x_1f2"><literal role="hook">pretxncommit</literal>:
-	  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.
-	</para>
-      </listitem>
-      <listitem><para id="x_1f3"><literal role="hook">preupdate</literal>:
-	  Controlling. This is run before starting an update or merge
-	  of the working directory.
-	</para>
-      </listitem>
-      <listitem><para id="x_1f4"><literal role="hook">tag</literal>: This is run
-	  after a tag is created.
-	</para>
-      </listitem>
-      <listitem><para id="x_1f5"><literal role="hook">update</literal>: This is
-	  run after an update or merge of the working directory has
-	  finished.
-	</para>
-      </listitem></itemizedlist>
-
-  </sect1>
-  <sect1>
-    <title>Hooks and security</title>
-
-    <sect2>
-      <title>Hooks are run with your privileges</title>
-
-      <para id="x_1f7">When you run a Mercurial command in a repository, and the
-	command causes a hook to run, that hook runs on
-	<emphasis>your</emphasis> system, under
-	<emphasis>your</emphasis> user account, with
-	<emphasis>your</emphasis> 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.
-      </para>
-
-      <para id="x_1f8">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 <filename role="special">~/.hgrc</filename>
-	file.
-      </para>
-
-      <para id="x_1f9">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 <quote>you</quote>.
-	For example, if you <command role="hg-cmd">hg pull</command>
-	from that repository, and its <filename
-	  role="special">.hg/hgrc</filename> defines a local <literal
-	  role="hook">outgoing</literal> hook, that hook will run
-	under your user account, even though you don't own that
-	repository.
-      </para>
-
-      <note>
-	<para id="x_1fa">  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 <literal role="hook">outgoing</literal>
-	  hook will run under whatever account is executing the server
-	  process, on the server.
-	</para>
-      </note>
-
-      <para id="x_1fb">To see what hooks are defined in a repository,
-	use the <command role="hg-cmd">hg showconfig hooks</command>
-	command.  If you are working in one repository, but talking to
-	another that you do not own (e.g. using <command
-	  role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg
-	  incoming</command>), remember that it is the other
-	repository's hooks you should be checking, not your own.
-      </para>
-    </sect2>
-
-    <sect2>
-      <title>Hooks do not propagate</title>
-
-      <para id="x_1fc">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.
-      </para>
-
-      <para id="x_1fd">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.
-      </para>
-
-      <para id="x_1fe">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.
-      </para>
-
-      <para id="x_1ff">In a corporate intranet, this is somewhat easier to
-	control, as you can for example provide a
-	<quote>standard</quote> installation of Mercurial on an NFS
-	filesystem, and use a site-wide <filename role="special">~/.hgrc</filename> file to define hooks that all users will
-	see.  However, this too has its limits; see below.
-      </para>
-    </sect2>
-
-    <sect2>
-      <title>Hooks can be overridden</title>
-
-      <para id="x_200">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 behavior as you wish.
-      </para>
-
-      <para id="x_201">If you deploy a system- or site-wide <filename
-	  role="special">~/.hgrc</filename> file that defines some
-	hooks, you should thus understand that your users can disable
-	or override those hooks.
-      </para>
-    </sect2>
-
-    <sect2>
-      <title>Ensuring that critical hooks are run</title>
-
-      <para id="x_202">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 <filename role="special">~/.hgrc</filename> won't
-	work for remote users on laptops, and of course local users
-	can subvert it at will by overriding the hook.
-      </para>
-
-      <para id="x_203">Instead, you can set up your policies for use of Mercurial
-	so that people are expected to propagate changes through a
-	well-known <quote>canonical</quote> server that you have
-	locked down and configured appropriately.
-      </para>
-
-      <para id="x_204">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.
-      </para>
-
-      <para id="x_205">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.
-      </para>
-
-    </sect2>
-  </sect1>
-
-  <sect1 id="sec:hook:simple">
-    <title>A short tutorial on using hooks</title>
-
-    <para id="x_212">It is easy to write a Mercurial hook.  Let's start with a
-      hook that runs when you finish a <command role="hg-cmd">hg
-	commit</command>, and simply prints the hash of the changeset
-      you just created.  The hook is called <literal
-	role="hook">commit</literal>.
-    </para>
-
-    <para id="x_213">All hooks follow the pattern in this example.</para>
-
-&interaction.hook.simple.init;
-
-    <para id="x_214">You add an entry to the <literal
-	role="rc-hooks">hooks</literal> section of your <filename
-	role="special">~/.hgrc</filename>.  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</envar> in the example).
-    </para>
-
-    <sect2>
-      <title>Performing multiple actions per event</title>
-
-      <para id="x_215">Quite often, you will want to define more than one hook
-	for a particular kind of event, as shown below.</para>
-
-&interaction.hook.simple.ext;
-
-      <para id="x_216">Mercurial lets you do this by adding an
-	<emphasis>extension</emphasis> 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
-	<quote><literal>.</literal></quote> character), followed by
-	some more text of your choosing.  For example, Mercurial will
-	run both <literal>commit.foo</literal> and
-	<literal>commit.bar</literal> when the
-	<literal>commit</literal> event occurs.
-      </para>
-
-      <para id="x_217">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
-	<literal>commit.bar</literal> before
-	<literal>commit.foo</literal>, and <literal>commit</literal>
-	before both.
-      </para>
-
-      <para id="x_218">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 <xref
-	  linkend="sec:hook:perm"/> for an example).
-      </para>
-
-    </sect2>
-    <sect2 id="sec:hook:perm">
-      <title>Controlling whether an activity can proceed</title>
-
-      <para id="x_219">In our earlier examples, we used the <literal
-	  role="hook">commit</literal> 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.
-      </para>
-
-      <para id="x_21a">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.
-      </para>
-
-      <para id="x_21b">The <literal role="hook">pretxncommit</literal> 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 <literal role="hook">pretxncommit</literal>
-	hook has the ability to decide whether the transaction can
-	complete, or must be rolled back.
-      </para>
-
-      <para id="x_21c">If the <literal role="hook">pretxncommit</literal> hook
-	exits with a status code of zero, the transaction is allowed
-	to complete; the commit finishes; and the <literal
-	  role="hook">commit</literal> hook is run.  If the <literal
-	  role="hook">pretxncommit</literal> hook exits with a
-	non-zero status code, the transaction is rolled back; the
-	metadata representing the changeset is erased; and the
-	<literal role="hook">commit</literal> hook is not run.
-      </para>
-
-&interaction.hook.simple.pretxncommit;
-
-      <para id="x_21d">The hook in the example above checks that a commit comment
-	contains a bug ID.  If it does, the commit can complete.  If
-	not, the commit is rolled back.
-      </para>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Writing your own hooks</title>
-
-    <para id="x_21e">When you are writing a hook, you might find it useful to run
-      Mercurial either with the <option
-	role="hg-opt-global">-v</option> option, or the <envar
-	role="rc-item-ui">verbose</envar> config item set to
-      <quote>true</quote>.  When you do so, Mercurial will print a
-      message before it calls each hook.
-    </para>
-
-    <sect2 id="sec:hook:lang">
-      <title>Choosing how your hook should run</title>
-
-      <para id="x_21f">You can write a hook either as a normal
-	program&emdash;typically a shell script&emdash;or as a Python
-	function that is executed within the Mercurial process.
-      </para>
-
-      <para id="x_220">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.
-      </para>
-
-      <para id="x_221">An in-process Python hook has complete access to the
-	Mercurial API, and does not <quote>shell out</quote> 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.
-      </para>
-
-      <para id="x_222">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.
-      </para>
-
-    </sect2>
-    <sect2 id="sec:hook:param">
-      <title>Hook parameters</title>
-
-      <para id="x_223">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.
-      </para>
-
-      <para id="x_224">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
-	<quote>true</quote>) or 0 (for <quote>false</quote>) as an
-	environment variable for an external hook.  If a hook
-	parameter is named <literal>foo</literal>, the keyword
-	argument for a Python hook will also be named
-	<literal>foo</literal>, while the environment variable for an
-	external hook will be named <literal>HG_FOO</literal>.
-      </para>
-    </sect2>
-
-    <sect2>
-      <title>Hook return values and activity control</title>
-
-      <para id="x_225">A hook that executes successfully must exit with a status
-	of zero if external, or return boolean <quote>false</quote> if
-	in-process.  Failure is indicated with a non-zero exit status
-	from an external hook, or an in-process hook returning boolean
-	<quote>true</quote>.  If an in-process hook raises an
-	exception, the hook is considered to have failed.
-      </para>
-
-      <para id="x_226">For a hook that controls whether an activity can proceed,
-	zero/false means <quote>allow</quote>, while
-	non-zero/true/exception means <quote>deny</quote>.
-      </para>
-    </sect2>
-
-    <sect2>
-      <title>Writing an external hook</title>
-
-      <para id="x_227">When you define an external hook in your <filename
-	  role="special">~/.hgrc</filename> 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.
-      </para>
-
-      <para id="x_228">An executable hook is always run with its current
-	directory set to a repository's root directory.
-      </para>
-
-      <para id="x_229">Each hook parameter is passed in as an environment
-	variable; the name is upper-cased, and prefixed with the
-	string <quote><literal>HG_</literal></quote>.
-      </para>
-
-      <para id="x_22a">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.
-      </para>
-    </sect2>
-
-    <sect2>
-      <title>Telling Mercurial to use an in-process hook</title>
-
-      <para id="x_22b">The <filename role="special">~/.hgrc</filename> 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 <quote><literal>python:</literal></quote>, and continue
-	with the fully-qualified name of a callable object to use as
-	the hook's value.
-      </para>
-
-      <para id="x_22c">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</envar> right, it should <quote>just
-	  work</quote>.
-      </para>
-
-      <para id="x_22d">The following <filename role="special">~/.hgrc</filename>
-	example snippet illustrates the syntax and meaning of the
-	notions we just described.
-      </para>
-      <programlisting>[hooks]
-commit.example = python:mymodule.submodule.myhook</programlisting>
-      <para id="x_22e">When Mercurial runs the <literal>commit.example</literal>
-	hook, it imports <literal>mymodule.submodule</literal>, looks
-	for the callable object named <literal>myhook</literal>, and
-	calls it.
-      </para>
-    </sect2>
-
-    <sect2>
-      <title>Writing an in-process hook</title>
-
-      <para id="x_22f">The simplest in-process hook does nothing, but illustrates
-	the basic shape of the hook API:
-      </para>
-      <programlisting>def myhook(ui, repo, **kwargs):
-    pass</programlisting>
-      <para id="x_230">The first argument to a Python hook is always a <literal
-	  role="py-mod-mercurial.ui">ui</literal> object.  The second
-	is a repository object; at the moment, it is always an
-	instance of <literal
-	  role="py-mod-mercurial.localrepo">localrepository</literal>.
-	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
-	<literal>**kwargs</literal> above.
-      </para>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Some hook examples</title>
-
-    <sect2>
-      <title>Writing meaningful commit messages</title>
-
-      <para id="x_231">It's hard to imagine a useful commit message being very
-	short. The simple <literal role="hook">pretxncommit</literal>
-	hook of the example below will prevent you from committing a
-	changeset with a message that is less than ten bytes long.
-      </para>
-
-&interaction.hook.msglen.go;
-    </sect2>
-
-    <sect2>
-      <title>Checking for trailing whitespace</title>
-
-      <para id="x_232">An interesting use of a commit-related hook is to help you
-	to write cleaner code.  A simple example of <quote>cleaner
-	  code</quote> is the dictum that a change should not add any
-	new lines of text that contain <quote>trailing
-	  whitespace</quote>.  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.
-      </para>
-
-      <para id="x_233">You can use either the <literal
-	  role="hook">precommit</literal> or <literal
-	  role="hook">pretxncommit</literal> hook to tell whether you
-	have a trailing whitespace problem.  If you use the <literal
-	  role="hook">precommit</literal> 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</filename>, but the file
-	<filename>bar</filename> contains trailing whitespace, doing a
-	check in the <literal role="hook">precommit</literal> hook
-	will prevent you from committing <filename>foo</filename> due
-	to the problem with <filename>bar</filename>.  This doesn't
-	seem right.
-      </para>
-
-      <para id="x_234">Should you choose the <literal
-	  role="hook">pretxncommit</literal> 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 <command
-	  role="hg-cmd">hg commit</command> again.
-      </para>
-
-      &interaction.ch09-hook.ws.simple;
-
-      <para id="x_235">In this example, we introduce a simple <literal
-	  role="hook">pretxncommit</literal> 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.
-      </para>
-
-      &ch09-check_whitespace.py.lst;
-
-      <para id="x_236">The above version 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 the <option role="hg-opt-commit">-l filename</option>
-	option to <command role="hg-cmd">hg commit</command> to reuse
-	the saved commit message once you've corrected the problem.
-      </para>
-
-      &interaction.ch09-hook.ws.better;
-
-      <para id="x_237">As a final aside, note in the example above the
-	use of <command>sed</command>'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 (using
-	<command>perl</command> for good measure).</para>
-      <programlisting>perl -pi -e 's,\s+$,,' filename</programlisting>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Bundled hooks</title>
-
-    <para id="x_238">Mercurial ships with several bundled hooks.  You can find
-      them in the <filename class="directory">hgext</filename>
-      directory of a Mercurial source tree.  If you are using a
-      Mercurial binary package, the hooks will be located in the
-      <filename class="directory">hgext</filename> directory of
-      wherever your package installer put Mercurial.
-    </para>
-
-    <sect2>
-      <title><literal role="hg-ext">acl</literal>&emdash;access
-	control for parts of a repository</title>
-
-      <para id="x_239">The <literal role="hg-ext">acl</literal> 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.
-      </para>
-
-      <para id="x_23a">This extension implements access control based on the
-	identity of the user performing a push,
-	<emphasis>not</emphasis> 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.
-      </para>
-
-      <sect3>
-	<title>Configuring the <literal role="hook">acl</literal>
-	  hook</title>
-
-	<para id="x_23b">In order to manage incoming changesets, the <literal
-	    role="hg-ext">acl</literal> hook must be used as a
-	  <literal role="hook">pretxnchangegroup</literal> hook.  This
-	  lets it see which files are modified by each incoming
-	  changeset, and roll back a group of changesets if they
-	  modify <quote>forbidden</quote> files.  Example:
-	</para>
-	<programlisting>[hooks]
-pretxnchangegroup.acl = python:hgext.acl.hook</programlisting>
-
-	<para id="x_23c">The <literal role="hg-ext">acl</literal> extension is
-	  configured using three sections.
-	</para>
-
-	<para id="x_23d">The <literal role="rc-acl">acl</literal> section has
-	  only one entry, <envar role="rc-item-acl">sources</envar>,
-	  which lists the sources of incoming changesets that the hook
-	  should pay attention to.  You don't normally need to
-	  configure this section.
-	</para>
-	<itemizedlist>
-	  <listitem><para id="x_23e"><envar role="rc-item-acl">serve</envar>:
-	      Control incoming changesets that are arriving from a
-	      remote repository over http or ssh.  This is the default
-	      value of <envar role="rc-item-acl">sources</envar>, and
-	      usually the only setting you'll need for this
-	      configuration item.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_23f"><envar role="rc-item-acl">pull</envar>:
-	      Control incoming changesets that are arriving via a pull
-	      from a local repository.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_240"><envar role="rc-item-acl">push</envar>:
-	      Control incoming changesets that are arriving via a push
-	      from a local repository.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_241"><envar role="rc-item-acl">bundle</envar>:
-	      Control incoming changesets that are arriving from
-	      another repository via a bundle.
-	    </para>
-	  </listitem></itemizedlist>
-
-	<para id="x_242">The <literal role="rc-acl.allow">acl.allow</literal>
-	  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).
-	</para>
-
-	<para id="x_243">The <literal role="rc-acl.deny">acl.deny</literal>
-	  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.
-	</para>
-
-	<para id="x_244">The syntaxes for the <literal
-	    role="rc-acl.allow">acl.allow</literal> and <literal
-	    role="rc-acl.deny">acl.deny</literal> 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.
-	</para>
-
-	<para id="x_245">In the following example, the user
-	  <literal>docwriter</literal> can only push changes to the
-	  <filename class="directory">docs</filename> subtree of the
-	  repository, while <literal>intern</literal> can push changes
-	  to any file or directory except <filename
-	    class="directory">source/sensitive</filename>.
-	</para>
-	<programlisting>[acl.allow]
-docs/** = docwriter
-[acl.deny]
-source/sensitive/** = intern</programlisting>
-
-      </sect3>
-      <sect3>
-	<title>Testing and troubleshooting</title>
-
-	<para id="x_246">If you want to test the <literal
-	    role="hg-ext">acl</literal> 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 <option
-	    role="hg-opt-global">--debug</option> option, don't forget
-	  that you can enable debugging output in your <filename
-	    role="special">~/.hgrc</filename>:
-	</para>
-	<programlisting>[ui]
-debug = true</programlisting>
-	<para id="x_247">With this enabled, the <literal
-	    role="hg-ext">acl</literal> hook will print enough
-	  information to let you figure out why it is allowing or
-	  forbidding pushes from specific users.
-	</para>
-
-      </sect3>    </sect2>
-
-    <sect2>
-      <title><literal
-	  role="hg-ext">bugzilla</literal>&emdash;integration with
-	Bugzilla</title>
-
-      <para id="x_248">The <literal role="hg-ext">bugzilla</literal> 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.
-      </para>
-
-      <para id="x_249">It adds a comment to the bug that looks like this (you can
-	configure the contents of the comment&emdash;see below):
-      </para>
-      <programlisting>Changeset aad8b264143a, made by Joe User
-	&lt;joe.user@domain.com&gt; 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</programlisting>
-      <para id="x_24a">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.
-      </para>
-
-      <para id="x_24b">You can use the code in this hook as a starting point for
-	some more exotic Bugzilla integration recipes.  Here are a few
-	possibilities:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_24c">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 <literal
-	      role="hook">pretxncommit</literal> hook.  This would
-	    allow the hook to reject changes that didn't contain bug
-	    IDs.
-	  </para>
-	</listitem>
-	<listitem><para id="x_24d">Allow incoming changesets to automatically
-	    modify the <emphasis>state</emphasis> of a bug, as well as
-	    simply adding a comment.  For example, the hook could
-	    recognise the string <quote>fixed bug 31337</quote> as
-	    indicating that it should update the state of bug 31337 to
-	    <quote>requires testing</quote>.
-	  </para>
-	</listitem></itemizedlist>
-
-      <sect3 id="sec:hook:bugzilla:config">
-	<title>Configuring the <literal role="hook">bugzilla</literal>
-	  hook</title>
-
-	<para id="x_24e">You should configure this hook in your server's
-	  <filename role="special">~/.hgrc</filename> as an <literal
-	    role="hook">incoming</literal> hook, for example as
-	  follows:
-	</para>
-	<programlisting>[hooks]
-incoming.bugzilla = python:hgext.bugzilla.hook</programlisting>
-
-	<para id="x_24f">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.
-	</para>
-
-	<para id="x_250">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
-	  <citation>web:mysql-python</citation>.
-	</para>
-
-	<para id="x_251">Configuration information for this hook lives in the
-	  <literal role="rc-bugzilla">bugzilla</literal> section of
-	  your <filename role="special">~/.hgrc</filename>.
-	</para>
-	<itemizedlist>
-	  <listitem><para id="x_252"><envar
-		role="rc-item-bugzilla">version</envar>: 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.</para>
-	  </listitem>
-	  <listitem><para id="x_253"><envar role="rc-item-bugzilla">host</envar>:
-	      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
-	      <literal role="hook">bugzilla</literal> hook on.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_254"><envar role="rc-item-bugzilla">user</envar>:
-	      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 <literal
-		role="hook">bugzilla</literal> hook on.  This user
-	      must be able to access and modify Bugzilla tables.  The
-	      default value of this item is <literal>bugs</literal>,
-	      which is the standard name of the Bugzilla user in a
-	      MySQL database.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_255"><envar
-		role="rc-item-bugzilla">password</envar>: 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 <filename
-		role="special">~/.hgrc</filename> file where you
-	      store this information.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_256"><envar role="rc-item-bugzilla">db</envar>:
-	      The name of the Bugzilla database on the MySQL server.
-	      The default value of this item is
-	      <literal>bugs</literal>, which is the standard name of
-	      the MySQL database where Bugzilla stores its data.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_257"><envar
-		role="rc-item-bugzilla">notify</envar>: 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 <filename
-		class="directory">/var/www/html/bugzilla</filename>:
-	    </para>
-	    <programlisting>cd /var/www/html/bugzilla &amp;&amp;
-	      ./processmail %s nobody@nowhere.com</programlisting>
-	  </listitem>
-	  <listitem><para id="x_258">  The Bugzilla
-	      <literal>processmail</literal> program expects to be
-	      given a bug ID (the hook replaces
-	      <quote><literal>%s</literal></quote> 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
-	      <literal>processmail</literal> on the server where
-	      Bugzilla is installed.
-	    </para>
-	  </listitem></itemizedlist>
-
-      </sect3>
-      <sect3>
-	<title>Mapping committer names to Bugzilla user names</title>
-
-	<para id="x_259">By default, the <literal
-	    role="hg-ext">bugzilla</literal> 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 <literal
-	    role="rc-usermap">usermap</literal> section.
-	</para>
-
-	<para id="x_25a">Each item in the <literal
-	    role="rc-usermap">usermap</literal> section contains an
-	  email address on the left, and a Bugzilla user name on the
-	  right.
-	</para>
-	<programlisting>[usermap]
-jane.user@example.com = jane</programlisting>
-	<para id="x_25b">You can either keep the <literal
-	    role="rc-usermap">usermap</literal> data in a normal
-	  <filename role="special">~/.hgrc</filename>, or tell the
-	  <literal role="hg-ext">bugzilla</literal> hook to read the
-	  information from an external <filename>usermap</filename>
-	  file.  In the latter case, you can store
-	  <filename>usermap</filename> data by itself in (for example)
-	  a user-modifiable repository.  This makes it possible to let
-	  your users maintain their own <envar
-	    role="rc-item-bugzilla">usermap</envar> entries.  The main
-	  <filename role="special">~/.hgrc</filename> file might look
-	  like this:
-	</para>
-	<programlisting># regular hgrc file refers to external usermap file
-[bugzilla]
-usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting>
-	<para id="x_25c">While the <filename>usermap</filename> file that it
-	  refers to might look like this:
-	</para>
-	<programlisting># bugzilla-usermap.conf - inside a hg repository
-[usermap] stephanie@example.com = steph</programlisting>
-
-      </sect3>
-      <sect3>
-	<title>Configuring the text that gets added to a bug</title>
-
-	<para id="x_25d">You can configure the text that this hook adds as a
-	  comment; you specify it in the form of a Mercurial template.
-	  Several <filename role="special">~/.hgrc</filename> entries
-	  (still in the <literal role="rc-bugzilla">bugzilla</literal>
-	  section) control this behavior.
-	</para>
-	<itemizedlist>
-	  <listitem><para id="x_25e"><literal>strip</literal>: 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 <filename
-		class="directory">/home/hg/repos</filename>, and you
-	      have a repository whose path is <filename
-		class="directory">/home/hg/repos/app/tests</filename>,
-	      then setting <literal>strip</literal> to
-	      <literal>4</literal> will give a partial path of
-	      <filename class="directory">app/tests</filename>.  The
-	      hook will make this partial path available when
-	      expanding a template, as <literal>webroot</literal>.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_25f"><literal>template</literal>: The text of the
-	      template to use.  In addition to the usual
-	      changeset-related variables, this template can use
-	      <literal>hgweb</literal> (the value of the
-	      <literal>hgweb</literal> configuration item above) and
-	      <literal>webroot</literal> (the path constructed using
-	      <literal>strip</literal> above).
-	    </para>
-	  </listitem></itemizedlist>
-
-	<para id="x_260">In addition, you can add a <envar
-	    role="rc-item-web">baseurl</envar> item to the <literal
-	    role="rc-web">web</literal> section of your <filename
-	    role="special">~/.hgrc</filename>.  The <literal
-	    role="hg-ext">bugzilla</literal> 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:
-	</para>
-	<programlisting>[web]
-baseurl = http://hg.domain.com/</programlisting>
-
-	<para id="x_261">Here is an example set of <literal
-	    role="hg-ext">bugzilla</literal> hook config information.
-	</para>
-
-	&ch10-bugzilla-config.lst;
-
-      </sect3>
-      <sect3>
-	<title>Testing and troubleshooting</title>
-
-	<para id="x_262">The most common problems with configuring the <literal
-	    role="hg-ext">bugzilla</literal> hook relate to running
-	  Bugzilla's <filename>processmail</filename> script and
-	  mapping committer names to user names.
-	</para>
-
-	<para id="x_263">Recall from <xref
-	    linkend="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</filename>
-	  script.  The <filename>processmail</filename> 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.
-	</para>
-
-	<para id="x_264">You can cause <filename>processmail</filename> to be run
-	  with the suitable user's identity using the
-	  <command>sudo</command> command.  Here is an example entry
-	  for a <filename>sudoers</filename> file.
-	</para>
-	<programlisting>hg_user = (httpd_user)
-NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting>
-	<para id="x_265">This allows the <literal>hg_user</literal> user to run a
-	  <filename>processmail-wrapper</filename> program under the
-	  identity of <literal>httpd_user</literal>.
-	</para>
-
-	<para id="x_266">This indirection through a wrapper script is necessary,
-	  because <filename>processmail</filename> 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</filename> file.  The contents of the
-	  wrapper script are simple:
-	</para>
-	<programlisting>#!/bin/sh
-cd `dirname $0` &amp;&amp; ./processmail "$1" nobody@example.com</programlisting>
-	<para id="x_267">It doesn't seem to matter what email address you pass to
-	  <filename>processmail</filename>.
-	</para>
-
-	<para id="x_268">If your <literal role="rc-usermap">usermap</literal> is
-	  not set up correctly, users will see an error message from
-	  the <literal role="hg-ext">bugzilla</literal> hook when they
-	  push changes to the server.  The error message will look
-	  like this:
-	</para>
-	<programlisting>cannot find bugzilla user id for john.q.public@example.com</programlisting>
-	<para id="x_269">What this means is that the committer's address,
-	  <literal>john.q.public@example.com</literal>, is not a valid
-	  Bugzilla user name, nor does it have an entry in your
-	  <literal role="rc-usermap">usermap</literal> that maps it to
-	  a valid Bugzilla user name.
-	</para>
-
-      </sect3>    </sect2>
-
-    <sect2>
-      <title><literal role="hg-ext">notify</literal>&emdash;send email
-	notifications</title>
-
-      <para id="x_26a">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 <literal
-	  role="hg-ext">notify</literal> hook lets you send out
-	notifications to a set of email addresses whenever changesets
-	arrive that those subscribers are interested in.
-      </para>
-
-      <para id="x_26b">As with the <literal role="hg-ext">bugzilla</literal>
-	hook, the <literal role="hg-ext">notify</literal> hook is
-	template-driven, so you can customise the contents of the
-	notification messages that it sends.
-      </para>
-
-      <para id="x_26c">By default, the <literal role="hg-ext">notify</literal>
-	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.
-      </para>
-
-      <sect3>
-	<title>Configuring the <literal role="hg-ext">notify</literal>
-	  hook</title>
-
-	<para id="x_26d">You can set up the <literal
-	    role="hg-ext">notify</literal> 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).
-	</para>
-	<programlisting>[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</programlisting>
-
-	<para id="x_26e">Configuration information for this hook lives in the
-	  <literal role="rc-notify">notify</literal> section of a
-	  <filename role="special">~/.hgrc</filename> file.
-	</para>
-	<itemizedlist>
-	  <listitem><para id="x_26f"><envar role="rc-item-notify">test</envar>:
-	      By default, this hook does not send out email at all;
-	      instead, it prints the message that it
-	      <emphasis>would</emphasis> send.  Set this item to
-	      <literal>false</literal> 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 <quote>broken</quote>
-	      notifications while you debug your configuration.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_270"><envar role="rc-item-notify">config</envar>:
-	      The path to a configuration file that contains
-	      subscription information.  This is kept separate from
-	      the main <filename role="special">~/.hgrc</filename> 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.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_271"><envar role="rc-item-notify">strip</envar>:
-	      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 <filename
-		class="directory">/home/hg/repos</filename>, and
-	      <literal role="hg-ext">notify</literal> is considering a
-	      repository named <filename
-		class="directory">/home/hg/repos/shared/test</filename>, 
-	      setting <envar role="rc-item-notify">strip</envar> to
-	      <literal>4</literal> will cause <literal
-		role="hg-ext">notify</literal> to trim the path it
-	      considers down to <filename
-		class="directory">shared/test</filename>, and it will
-	      match subscribers against that.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_272"><envar
-		role="rc-item-notify">template</envar>: The template
-	      text to use when sending messages.  This specifies both
-	      the contents of the message header and its body.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_273"><envar
-		role="rc-item-notify">maxdiff</envar>: 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
-	      <literal>0</literal> to omit diffs from notification
-	      emails.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_274"><envar
-		role="rc-item-notify">sources</envar>: A list of
-	      sources of changesets to consider.  This lets you limit
-	      <literal role="hg-ext">notify</literal> to only sending
-	      out email about changes that remote users pushed into
-	      this repository via a server, for example.  See 
-	      <xref linkend="sec:hook:sources"/> for the sources you
-	      can specify here.
-	    </para>
-	  </listitem></itemizedlist>
-
-	<para id="x_275">If you set the <envar role="rc-item-web">baseurl</envar>
-	  item in the <literal role="rc-web">web</literal> section,
-	  you can use it in a template; it will be available as
-	  <literal>webroot</literal>.
-	</para>
-
-	<para id="x_276">Here is an example set of <literal
-	    role="hg-ext">notify</literal> configuration information.
-	</para>
-
-	&ch10-notify-config.lst;
-
-	<para id="x_277">This will produce a message that looks like the
-	  following:
-	</para>
-
-	&ch10-notify-config-mail.lst;
-
-      </sect3>
-      <sect3>
-	<title>Testing and troubleshooting</title>
-
-	<para id="x_278">Do not forget that by default, the <literal
-		role="hg-ext">notify</literal> extension <emphasis>will not
-	  send any mail</emphasis> until you explicitly configure it to do so,
-	  by setting <envar role="rc-item-notify">test</envar> to
-	  <literal>false</literal>.  Until you do that, it simply
-	  prints the message it <emphasis>would</emphasis> send.
-	</para>
-
-      </sect3>
-    </sect2>
-  </sect1>
-  <sect1 id="sec:hook:ref">
-    <title>Information for writers of hooks</title>
-
-    <sect2>
-      <title>In-process hook execution</title>
-
-      <para id="x_279">An in-process hook is called with arguments of the
-	following form:
-      </para>
-      <programlisting>def myhook(ui, repo, **kwargs): pass</programlisting>
-      <para id="x_27a">The <literal>ui</literal> parameter is a <literal
-	  role="py-mod-mercurial.ui">ui</literal> object. The
-	<literal>repo</literal> parameter is a <literal
-	  role="py-mod-mercurial.localrepo">localrepository</literal>
-	object.  The names and values of the
-	<literal>**kwargs</literal> parameters depend on the hook
-	being invoked, with the following common features:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_27b">If a parameter is named
-	    <literal>node</literal> or <literal>parentN</literal>, it
-	    will contain a hexadecimal changeset ID. The empty string
-	    is used to represent <quote>null changeset ID</quote>
-	    instead of a string of zeroes.
-	  </para>
-	</listitem>
-	<listitem><para id="x_27c">If a parameter is named
-	    <literal>url</literal>, it will contain the URL of a
-	    remote repository, if that can be determined.
-	  </para>
-	</listitem>
-	<listitem><para id="x_27d">Boolean-valued parameters are represented as
-	    Python <literal>bool</literal> objects.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_27e">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.
-      </para>
-
-      <para id="x_27f">If a hook returns a boolean <quote>false</quote> value, it
-	is considered to have succeeded.  If it returns a boolean
-	<quote>true</quote> value or raises an exception, it is
-	considered to have failed.  A useful way to think of the
-	calling convention is <quote>tell me if you fail</quote>.
-      </para>
-
-      <para id="x_280">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 <literal>bin</literal> function.
-      </para>
-    </sect2>
-
-    <sect2>
-      <title>External hook execution</title>
-
-      <para id="x_281">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).
-      </para>
-
-      <para id="x_282">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
-	<quote><literal>HG_</literal></quote>.  For example, if the
-	name of a parameter is <quote><literal>node</literal></quote>,
-	the name of the environment variable representing that
-	parameter will be <quote><literal>HG_NODE</literal></quote>.
-      </para>
-
-      <para id="x_283">A boolean parameter is represented as the string
-	<quote><literal>1</literal></quote> for <quote>true</quote>,
-	<quote><literal>0</literal></quote> for <quote>false</quote>.
-	If an environment variable is named <envar>HG_NODE</envar>,
-	<envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it
-	contains a changeset ID represented as a hexadecimal string.
-	The empty string is used to represent <quote>null changeset
-	  ID</quote> instead of a string of zeroes.  If an environment
-	variable is named <envar>HG_URL</envar>, it will contain the
-	URL of a remote repository, if that can be determined.
-      </para>
-
-      <para id="x_284">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.
-      </para>
-    </sect2>
-
-    <sect2>
-      <title>Finding out where changesets come from</title>
-
-      <para id="x_285">A hook that involves the transfer of changesets between a
-	local repository and another may be able to find out
-	information about the <quote>far side</quote>.  Mercurial
-	knows <emphasis>how</emphasis> changes are being transferred,
-	and in many cases <emphasis>where</emphasis> they are being
-	transferred to or from.
-      </para>
-
-      <sect3 id="sec:hook:sources">
-	<title>Sources of changesets</title>
-
-	<para id="x_286">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
-	  <literal>source</literal>, or an environment variable named
-	  <envar>HG_SOURCE</envar>.
-	</para>
-
-	<itemizedlist>
-	  <listitem><para id="x_287"><literal>serve</literal>: Changesets are
-	      transferred to or from a remote repository over http or
-	      ssh.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_288"><literal>pull</literal>: Changesets are
-	      being transferred via a pull from one repository into
-	      another.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_289"><literal>push</literal>: Changesets are
-	      being transferred via a push from one repository into
-	      another.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_28a"><literal>bundle</literal>: Changesets are
-	      being transferred to or from a bundle.
-	    </para>
-	  </listitem></itemizedlist>
-      </sect3>
-
-      <sect3 id="sec:hook:url">
-	<title>Where changes are going&emdash;remote repository
-	  URLs</title>
-
-	<para id="x_28b">When possible, Mercurial will tell a hook the location
-	  of the <quote>far side</quote> of an activity that transfers
-	  changeset data between repositories.  This is provided by
-	  Mercurial in a Python parameter named
-	  <literal>url</literal>, or an environment variable named
-	  <envar>HG_URL</envar>.
-	</para>
-
-	<para id="x_28c">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:
-	</para>
-	<itemizedlist>
-	  <listitem><para id="x_28d"><literal>remote:ssh:1.2.3.4</literal>&emdash;remote 
-	      ssh client, at the IP address
-	      <literal>1.2.3.4</literal>.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_28e"><literal>remote:http:1.2.3.4</literal>&emdash;remote 
-	      http client, at the IP address
-	      <literal>1.2.3.4</literal>.  If the client is using SSL,
-	      this will be of the form
-	      <literal>remote:https:1.2.3.4</literal>.
-	    </para>
-	  </listitem>
-	  <listitem><para id="x_28f">Empty&emdash;no information could be
-	      discovered about the remote client.
-	    </para>
-	  </listitem></itemizedlist>
-      </sect3>
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Hook reference</title>
-
-    <sect2 id="sec:hook:changegroup">
-      <title><literal role="hook">changegroup</literal>&emdash;after
-	remote changesets added</title>
-
-      <para id="x_290">This hook is run after a group of pre-existing changesets
-	has been added to the repository, for example via a <command
-	  role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg
-	  unbundle</command>.  This hook is run once per operation
-	that added one or more changesets.  This is in contrast to the
-	<literal role="hook">incoming</literal> hook, which is run
-	once per changeset, regardless of whether the changesets
-	arrive in a group.
-      </para>
-
-      <para id="x_291">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.
-      </para>
-
-      <para id="x_292">Parameters to this hook:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_293"><literal>node</literal>: A changeset ID.  The
-	    changeset ID of the first changeset in the group that was
-	    added.  All changesets between this and
-	    <literal role="tag">tip</literal>, inclusive, were added by a single
-	    <command role="hg-cmd">hg pull</command>, <command
-	      role="hg-cmd">hg push</command> or <command
-	      role="hg-cmd">hg unbundle</command>.
-	  </para>
-	</listitem>
-	<listitem><para id="x_294"><literal>source</literal>: A
-	    string.  The source of these changes.  See <xref
-	      linkend="sec:hook:sources"/> for details.
-	  </para>
-	</listitem>
-	<listitem><para id="x_295"><literal>url</literal>: A URL.  The
-	    location of the remote repository, if known.  See <xref
-	      linkend="sec:hook:url"/> for more information.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_296">See also: <literal
-	  role="hook">incoming</literal> (<xref
-	  linkend="sec:hook:incoming"/>), <literal
-	  role="hook">prechangegroup</literal> (<xref
-	  linkend="sec:hook:prechangegroup"/>), <literal
-	  role="hook">pretxnchangegroup</literal> (<xref
-	  linkend="sec:hook:pretxnchangegroup"/>)
-      </para>
-    </sect2>
-
-    <sect2 id="sec:hook:commit">
-      <title><literal role="hook">commit</literal>&emdash;after a new
-	changeset is created</title>
-
-      <para id="x_297">This hook is run after a new changeset has been created.
-      </para>
-
-      <para id="x_298">Parameters to this hook:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_299"><literal>node</literal>: A changeset ID.  The
-	    changeset ID of the newly committed changeset.
-	  </para>
-	</listitem>
-	<listitem><para id="x_29a"><literal>parent1</literal>: A changeset ID.
-	    The changeset ID of the first parent of the newly
-	    committed changeset.
-	  </para>
-	</listitem>
-	<listitem><para id="x_29b"><literal>parent2</literal>: A changeset ID.
-	    The changeset ID of the second parent of the newly
-	    committed changeset.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_29c">See also: <literal
-	  role="hook">precommit</literal> (<xref
-	  linkend="sec:hook:precommit"/>), <literal
-	  role="hook">pretxncommit</literal> (<xref
-	  linkend="sec:hook:pretxncommit"/>)
-      </para>
-    </sect2>
-
-    <sect2 id="sec:hook:incoming">
-      <title><literal role="hook">incoming</literal>&emdash;after one
-	remote changeset is added</title>
-
-      <para id="x_29d">This hook is run after a pre-existing changeset has been
-	added to the repository, for example via a <command
-	  role="hg-cmd">hg push</command>.  If a group of changesets
-	was added in a single operation, this hook is called once for
-	each added changeset.
-      </para>
-
-      <para id="x_29e">You can use this hook for the same purposes as
-	the <literal role="hook">changegroup</literal> hook (<xref
-	  linkend="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.
-      </para>
-
-      <para id="x_29f">Parameters to this hook:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_2a0"><literal>node</literal>: A changeset ID.  The
-	    ID of the newly added changeset.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2a1"><literal>source</literal>: A
-	    string.  The source of these changes.  See <xref
-	      linkend="sec:hook:sources"/> for details.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2a2"><literal>url</literal>: A URL.  The
-	    location of the remote repository, if known.  See <xref
-	      linkend="sec:hook:url"/> for more information.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_2a3">See also: <literal
-	  role="hook">changegroup</literal> (<xref
-	  linkend="sec:hook:changegroup"/>) <literal
-	  role="hook">prechangegroup</literal> (<xref
-	  linkend="sec:hook:prechangegroup"/>), <literal
-	  role="hook">pretxnchangegroup</literal> (<xref
-	  linkend="sec:hook:pretxnchangegroup"/>)
-      </para>
-    </sect2>
-
-    <sect2 id="sec:hook:outgoing">
-      <title><literal role="hook">outgoing</literal>&emdash;after
-	changesets are propagated</title>
-
-      <para id="x_2a4">This hook is run after a group of changesets has been
-	propagated out of this repository, for example by a <command
-	  role="hg-cmd">hg push</command> or <command role="hg-cmd">hg
-	  bundle</command> command.
-      </para>
-
-      <para id="x_2a5">One possible use for this hook is to notify administrators
-	that changes have been pulled.
-      </para>
-
-      <para id="x_2a6">Parameters to this hook:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_2a7"><literal>node</literal>: A changeset ID.  The
-	    changeset ID of the first changeset of the group that was
-	    sent.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2a8"><literal>source</literal>: A string.  The
-	    source of the of the operation (see <xref
-	      linkend="sec:hook:sources"/>).  If a remote
-	    client pulled changes from this repository,
-	    <literal>source</literal> will be
-	    <literal>serve</literal>.  If the client that obtained
-	    changes from this repository was local,
-	    <literal>source</literal> will be
-	    <literal>bundle</literal>, <literal>pull</literal>, or
-	    <literal>push</literal>, depending on the operation the
-	    client performed.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2a9"><literal>url</literal>: A URL.  The
-	    location of the remote repository, if known.  See <xref
-	      linkend="sec:hook:url"/> for more information.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_2aa">See also: <literal
-	  role="hook">preoutgoing</literal> (<xref
-	  linkend="sec:hook:preoutgoing"/>)
-      </para>
-    </sect2>
-
-    <sect2 id="sec:hook:prechangegroup">
-      <title><literal
-	  role="hook">prechangegroup</literal>&emdash;before starting
-	to add remote changesets</title>
-
-      <para id="x_2ab">This controlling hook is run before Mercurial begins to
-	add a group of changesets from another repository.
-      </para>
-
-      <para id="x_2ac">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.
-      </para>
-
-      <para id="x_2ad">One use for this hook is to prevent external changes from
-	being added to a repository.  For example, you could use this
-	to <quote>freeze</quote> a server-hosted branch temporarily or
-	permanently so that users cannot push to it, while still
-	allowing a local administrator to modify the repository.
-      </para>
-
-      <para id="x_2ae">Parameters to this hook:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_2af"><literal>source</literal>: A string.  The
-	    source of these changes.  See <xref
-	      linkend="sec:hook:sources"/> for details.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2b0"><literal>url</literal>: A URL.  The
-	    location of the remote repository, if known.  See <xref
-	      linkend="sec:hook:url"/> for more information.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_2b1">See also: <literal
-	  role="hook">changegroup</literal> (<xref
-	  linkend="sec:hook:changegroup"/>), <literal
-	  role="hook">incoming</literal> (<xref
-	  linkend="sec:hook:incoming"/>), <literal
-	  role="hook">pretxnchangegroup</literal> (<xref
-	  linkend="sec:hook:pretxnchangegroup"/>)
-      </para>
-    </sect2>
-
-    <sect2 id="sec:hook:precommit">
-      <title><literal role="hook">precommit</literal>&emdash;before
-	starting to commit a changeset</title>
-
-      <para id="x_2b2">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.
-      </para>
-
-      <para id="x_2b3">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.
-      </para>
-
-      <para id="x_2b4">Parameters to this hook:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_2b5"><literal>parent1</literal>: A changeset ID.
-	    The changeset ID of the first parent of the working
-	    directory.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2b6"><literal>parent2</literal>: A changeset ID.
-	    The changeset ID of the second parent of the working
-	    directory.
-	  </para>
-	</listitem></itemizedlist>
-      <para id="x_2b7">If the commit proceeds, the parents of the working
-	directory will become the parents of the new changeset.
-      </para>
-
-      <para id="x_2b8">See also: <literal role="hook">commit</literal>
-	(<xref linkend="sec:hook:commit"/>), <literal
-	  role="hook">pretxncommit</literal> (<xref
-	  linkend="sec:hook:pretxncommit"/>)
-      </para>
-    </sect2>
-
-    <sect2 id="sec:hook:preoutgoing">
-      <title><literal role="hook">preoutgoing</literal>&emdash;before
-	starting to propagate changesets</title>
-
-      <para id="x_2b9">This hook is invoked before Mercurial knows the identities
-	of the changesets to be transmitted.
-      </para>
-
-      <para id="x_2ba">One use for this hook is to prevent changes from being
-	transmitted to another repository.
-      </para>
-
-      <para id="x_2bb">Parameters to this hook:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_2bc"><literal>source</literal>: A
-	    string.  The source of the operation that is attempting to
-	    obtain changes from this repository (see <xref
-	      linkend="sec:hook:sources"/>).  See the documentation
-	    for the <literal>source</literal> parameter to the
-	    <literal role="hook">outgoing</literal> hook, in
-	    <xref linkend="sec:hook:outgoing"/>, for possible values
-	    of this parameter.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2bd"><literal>url</literal>: A URL.  The
-	    location of the remote repository, if known.  See <xref
-	      linkend="sec:hook:url"/> for more information.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_2be">See also: <literal
-	  role="hook">outgoing</literal> (<xref
-	  linkend="sec:hook:outgoing"/>)
-      </para>
-    </sect2>
-
-    <sect2 id="sec:hook:pretag">
-      <title><literal role="hook">pretag</literal>&emdash;before
-	tagging a changeset</title>
-
-      <para id="x_2bf">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.
-      </para>
-
-      <para id="x_2c0">Parameters to this hook:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_2c1"><literal>local</literal>: A boolean.  Whether
-	    the tag is local to this repository instance (i.e. stored
-	    in <filename role="special">.hg/localtags</filename>) or
-	    managed by Mercurial (stored in <filename
-	      role="special">.hgtags</filename>).
-	  </para>
-	</listitem>
-	<listitem><para id="x_2c2"><literal>node</literal>: A changeset ID.  The
-	    ID of the changeset to be tagged.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2c3"><literal>tag</literal>: A string.  The name of
-	    the tag to be created.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_2c4">If the tag to be created is
-	revision-controlled, the <literal
-	  role="hook">precommit</literal> and <literal
-	  role="hook">pretxncommit</literal> hooks (<xref
-	  linkend="sec:hook:commit"/> and <xref
-	  linkend="sec:hook:pretxncommit"/>) will also be run.
-      </para>
-
-      <para id="x_2c5">See also: <literal role="hook">tag</literal>
-	(<xref linkend="sec:hook:tag"/>)
-      </para>
-    </sect2>
-
-    <sect2 id="sec:hook:pretxnchangegroup">
-      <title><literal
-	  role="hook">pretxnchangegroup</literal>&emdash;before
-	completing addition of remote changesets</title>
-
-      <para id="x_2c6">This controlling hook is run before a
-	transaction&emdash;that manages the addition of a group of new
-	changesets from outside the repository&emdash;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.
-      </para>
-
-      <para id="x_2c7">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.
-      </para>
-
-      <para id="x_2c8">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.
-      </para>
-
-      <para id="x_2c9">This hook can be used to automatically vet a group of
-	changesets.  If the hook fails, all of the changesets are
-	<quote>rejected</quote> when the transaction rolls back.
-      </para>
-
-      <para id="x_2ca">Parameters to this hook:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_2cb"><literal>node</literal>: A changeset ID.  The
-	    changeset ID of the first changeset in the group that was
-	    added.  All changesets between this and
-	    <literal role="tag">tip</literal>,
-	    inclusive, were added by a single <command
-	      role="hg-cmd">hg pull</command>, <command
-	      role="hg-cmd">hg push</command> or <command
-	      role="hg-cmd">hg unbundle</command>.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2cc"><literal>source</literal>: A
-	    string.  The source of these changes.  See <xref
-	      linkend="sec:hook:sources"/> for details.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2cd"><literal>url</literal>: A URL.  The
-	    location of the remote repository, if known.  See <xref
-	      linkend="sec:hook:url"/> for more information.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_2ce">See also: <literal
-	  role="hook">changegroup</literal> (<xref
-	  linkend="sec:hook:changegroup"/>), <literal
-	  role="hook">incoming</literal> (<xref
-	  linkend="sec:hook:incoming"/>), <literal
-	  role="hook">prechangegroup</literal> (<xref
-	  linkend="sec:hook:prechangegroup"/>)
-      </para>
-    </sect2>
-
-    <sect2 id="sec:hook:pretxncommit">
-      <title><literal role="hook">pretxncommit</literal>&emdash;before
-	completing commit of new changeset</title>
-
-      <para id="x_2cf">This controlling hook is run before a
-	transaction&emdash;that manages a new commit&emdash;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.
-      </para>
-
-      <para id="x_2d0">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.
-      </para>
-
-      <para id="x_2d1">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.
-      </para>
-
-      <para id="x_2d2">Parameters to this hook:</para>
-
-      <itemizedlist>
-	<listitem><para id="x_2d3"><literal>node</literal>: A changeset ID.  The
-	    changeset ID of the newly committed changeset.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2d4"><literal>parent1</literal>: A changeset ID.
-	    The changeset ID of the first parent of the newly
-	    committed changeset.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2d5"><literal>parent2</literal>: A changeset ID.
-	    The changeset ID of the second parent of the newly
-	    committed changeset.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_2d6">See also: <literal
-	  role="hook">precommit</literal> (<xref
-	  linkend="sec:hook:precommit"/>)
-      </para>
-    </sect2>
-
-    <sect2 id="sec:hook:preupdate">
-      <title><literal role="hook">preupdate</literal>&emdash;before
-	updating or merging working directory</title>
-
-      <para id="x_2d7">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.
-      </para>
-
-      <para id="x_2d8">Parameters to this hook:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_2d9"><literal>parent1</literal>: 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.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2da"><literal>parent2</literal>: 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.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_2db">See also: <literal role="hook">update</literal>
-	(<xref linkend="sec:hook:update"/>)</para>
-    </sect2>
-
-    <sect2 id="sec:hook:tag">
-      <title><literal role="hook">tag</literal>&emdash;after tagging a
-	changeset</title>
-
-      <para id="x_2dc">This hook is run after a tag has been created.
-      </para>
-
-      <para id="x_2dd">Parameters to this hook:
-      </para>
-      <itemizedlist>
-	<listitem><para id="x_2de"><literal>local</literal>: A boolean.  Whether
-	    the new tag is local to this repository instance (i.e.
-	    stored in <filename
-	      role="special">.hg/localtags</filename>) or managed by
-	    Mercurial (stored in <filename
-	      role="special">.hgtags</filename>).
-	  </para>
-	</listitem>
-	<listitem><para id="x_2df"><literal>node</literal>: A changeset ID.  The
-	    ID of the changeset that was tagged.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2e0"><literal>tag</literal>: A string.  The name of
-	    the tag that was created.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_2e1">If the created tag is revision-controlled, the <literal
-	  role="hook">commit</literal> hook (section <xref
-	  linkend="sec:hook:commit"/>) is run before this hook.
-      </para>
-
-      <para id="x_2e2">See also: <literal role="hook">pretag</literal>
-	(<xref linkend="sec:hook:pretag"/>)
-      </para>
-    </sect2>
-
-    <sect2 id="sec:hook:update">
-      <title><literal role="hook">update</literal>&emdash;after
-	updating or merging working directory</title>
-
-      <para id="x_2e3">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> command fails to resolve conflicts
-	in a file), this hook communicates whether the update or merge
-	completed cleanly.
-      </para>
-
-      <itemizedlist>
-	<listitem><para id="x_2e4"><literal>error</literal>: A boolean.
-	    Indicates whether the update or merge completed
-	    successfully.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2e5"><literal>parent1</literal>: 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.
-	  </para>
-	</listitem>
-	<listitem><para id="x_2e6"><literal>parent2</literal>: A changeset ID.
-	    Only set if the working directory was merged.  The ID of
-	    the revision that the working directory was merged with.
-	  </para>
-	</listitem></itemizedlist>
-
-      <para id="x_2e7">See also: <literal role="hook">preupdate</literal>
-	(<xref linkend="sec:hook:preupdate"/>)
-      </para>
-
-    </sect2>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch09-undo.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,1201 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:undo">
+  <?dbhtml filename="finding-and-fixing-mistakes.html"?>
+  <title>Finding and fixing mistakes</title>
+
+  <para id="x_d2">To err might be human, but to really handle the consequences
+    well takes a top-notch revision control system.  In this chapter,
+    we'll discuss some of the techniques you can use when you find
+    that a problem has crept into your project.  Mercurial has some
+    highly capable features that will help you to isolate the sources
+    of problems, and to handle them appropriately.</para>
+
+  <sect1>
+    <title>Erasing local history</title>
+
+    <sect2>
+      <title>The accidental commit</title>
+
+      <para id="x_d3">I have the occasional but persistent problem of typing
+	rather more quickly than I can think, which sometimes results
+	in me committing a changeset that is either incomplete or
+	plain wrong.  In my case, the usual kind of incomplete
+	changeset is one in which I've created a new source file, but
+	forgotten to <command role="hg-cmd">hg add</command> it.  A
+	<quote>plain wrong</quote> changeset is not as common, but no
+	less annoying.</para>
+
+    </sect2>
+    <sect2 id="sec:undo:rollback">
+      <title>Rolling back a transaction</title>
+
+      <para id="x_d4">In <xref linkend="sec:concepts:txn"/>, I
+	mentioned that Mercurial treats each modification of a
+	repository as a <emphasis>transaction</emphasis>.  Every time
+	you commit a changeset or pull changes from another
+	repository, Mercurial remembers what you did.  You can undo,
+	or <emphasis>roll back</emphasis>, exactly one of these
+	actions using the <command role="hg-cmd">hg rollback</command>
+	command.  (See <xref linkend="sec:undo:rollback-after-push"/>
+	for an important caveat about the use of this command.)</para>
+
+      <para id="x_d5">Here's a mistake that I often find myself making:
+	committing a change in which I've created a new file, but
+	forgotten to <command role="hg-cmd">hg add</command>
+	it.</para>
+
+      &interaction.rollback.commit;
+
+      <para id="x_d6">Looking at the output of <command role="hg-cmd">hg
+	  status</command> after the commit immediately confirms the
+	error.</para>
+
+      &interaction.rollback.status;
+
+      <para id="x_d7">The commit captured the changes to the file
+	<filename>a</filename>, but not the new file
+	<filename>b</filename>.  If I were to push this changeset to a
+	repository that I shared with a colleague, the chances are
+	high that something in <filename>a</filename> would refer to
+	<filename>b</filename>, which would not be present in their
+	repository when they pulled my changes.  I would thus become
+	the object of some indignation.</para>
+
+      <para id="x_d8">However, luck is with me&emdash;I've caught my error
+	before I pushed the changeset.  I use the <command
+	  role="hg-cmd">hg rollback</command> command, and Mercurial
+	makes that last changeset vanish.</para>
+
+      &interaction.rollback.rollback;
+
+      <para id="x_d9">Notice that the changeset is no longer present in the
+	repository's history, and the working directory once again
+	thinks that the file <filename>a</filename> is modified.  The
+	commit and rollback have left the working directory exactly as
+	it was prior to the commit; the changeset has been completely
+	erased.  I can now safely <command role="hg-cmd">hg
+	  add</command> the file <filename>b</filename>, and rerun my
+	commit.</para>
+
+      &interaction.rollback.add;
+
+    </sect2>
+    <sect2>
+      <title>The erroneous pull</title>
+
+      <para id="x_da">It's common practice with Mercurial to maintain separate
+	development branches of a project in different repositories.
+	Your development team might have one shared repository for
+	your project's <quote>0.9</quote> release, and another,
+	containing different changes, for the <quote>1.0</quote>
+	release.</para>
+
+      <para id="x_db">Given this, you can imagine that the consequences could be
+	messy if you had a local <quote>0.9</quote> repository, and
+	accidentally pulled changes from the shared <quote>1.0</quote>
+	repository into it.  At worst, you could be paying
+	insufficient attention, and push those changes into the shared
+	<quote>0.9</quote> tree, confusing your entire team (but don't
+	worry, we'll return to this horror scenario later).  However,
+	it's more likely that you'll notice immediately, because
+	Mercurial will display the URL it's pulling from, or you will
+	see it pull a suspiciously large number of changes into the
+	repository.</para>
+
+      <para id="x_dc">The <command role="hg-cmd">hg rollback</command> command
+	will work nicely to expunge all of the changesets that you
+	just pulled.  Mercurial groups all changes from one <command
+	  role="hg-cmd">hg pull</command> into a single transaction,
+	so one <command role="hg-cmd">hg rollback</command> is all you
+	need to undo this mistake.</para>
+
+    </sect2>
+    <sect2 id="sec:undo:rollback-after-push">
+      <title>Rolling back is useless once you've pushed</title>
+
+      <para id="x_dd">The value of the <command role="hg-cmd">hg
+	  rollback</command> command drops to zero once you've pushed
+	your changes to another repository.  Rolling back a change
+	makes it disappear entirely, but <emphasis>only</emphasis> in
+	the repository in which you perform the <command
+	  role="hg-cmd">hg rollback</command>.  Because a rollback
+	eliminates history, there's no way for the disappearance of a
+	change to propagate between repositories.</para>
+
+      <para id="x_de">If you've pushed a change to another
+	repository&emdash;particularly if it's a shared
+	repository&emdash;it has essentially <quote>escaped into the
+	  wild,</quote> and you'll have to recover from your mistake
+	in a different way.  If you push a changeset somewhere, then
+	roll it back, then pull from the repository you pushed to, the
+	changeset you thought you'd gotten rid of will simply reappear
+	in your repository.</para>
+
+      <para id="x_df">(If you absolutely know for sure that the change
+	you want to roll back is the most recent change in the
+	repository that you pushed to, <emphasis>and</emphasis> you
+	know that nobody else could have pulled it from that
+	repository, you can roll back the changeset there, too, but
+	you really should not expect this to work reliably.  Sooner or
+	later a change really will make it into a repository that you
+	don't directly control (or have forgotten about), and come
+	back to bite you.)</para>
+
+    </sect2>
+    <sect2>
+      <title>You can only roll back once</title>
+
+      <para id="x_e0">Mercurial stores exactly one transaction in its
+	transaction log; that transaction is the most recent one that
+	occurred in the repository. This means that you can only roll
+	back one transaction.  If you expect to be able to roll back
+	one transaction, then its predecessor, this is not the
+	behavior you will get.</para>
+
+      &interaction.rollback.twice;
+
+      <para id="x_e1">Once you've rolled back one transaction in a repository,
+	you can't roll back again in that repository until you perform
+	another commit or pull.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Reverting the mistaken change</title>
+
+    <para id="x_e2">If you make a modification to a file, and decide that you
+      really didn't want to change the file at all, and you haven't
+      yet committed your changes, the <command role="hg-cmd">hg
+	revert</command> command is the one you'll need.  It looks at
+      the changeset that's the parent of the working directory, and
+      restores the contents of the file to their state as of that
+      changeset. (That's a long-winded way of saying that, in the
+      normal case, it undoes your modifications.)</para>
+
+    <para id="x_e3">Let's illustrate how the <command role="hg-cmd">hg
+	revert</command> command works with yet another small example.
+      We'll begin by modifying a file that Mercurial is already
+      tracking.</para>
+
+    &interaction.daily.revert.modify;
+
+    <para id="x_e4">If we don't
+      want that change, we can simply <command role="hg-cmd">hg
+	revert</command> the file.</para>
+
+      &interaction.daily.revert.unmodify;
+
+    <para id="x_e5">The <command role="hg-cmd">hg revert</command> command
+      provides us with an extra degree of safety by saving our
+      modified file with a <filename>.orig</filename>
+      extension.</para>
+
+    &interaction.daily.revert.status;
+
+    <tip>
+      <title>Be careful with <filename>.orig</filename> files</title>
+
+      <para id="x_6b8">It's extremely unlikely that you are either using
+	Mercurial to manage files with <filename>.orig</filename>
+	extensions or that you even care about the contents of such
+	files.  Just in case, though, it's useful to remember that
+	<command role="hg-cmd">hg revert</command> will
+	unconditionally overwrite an existing file with a
+	<filename>.orig</filename> extension. For instance, if you
+	already have a file named <filename>foo.orig</filename> when
+	you revert <filename>foo</filename>, the contents of
+	<filename>foo.orig</filename> will be clobbered.</para>
+    </tip>
+
+    <para id="x_e6">Here is a summary of the cases that the <command
+	role="hg-cmd">hg revert</command> command can deal with.  We
+      will describe each of these in more detail in the section that
+      follows.</para>
+    <itemizedlist>
+      <listitem><para id="x_e7">If you modify a file, it will restore the file
+	  to its unmodified state.</para>
+      </listitem>
+      <listitem><para id="x_e8">If you <command role="hg-cmd">hg add</command> a
+	  file, it will undo the <quote>added</quote> state of the
+	  file, but leave the file itself untouched.</para>
+      </listitem>
+      <listitem><para id="x_e9">If you delete a file without telling Mercurial,
+	  it will restore the file to its unmodified contents.</para>
+      </listitem>
+      <listitem><para id="x_ea">If you use the <command role="hg-cmd">hg
+	    remove</command> command to remove a file, it will undo
+	  the <quote>removed</quote> state of the file, and restore
+	  the file to its unmodified contents.</para>
+      </listitem></itemizedlist>
+
+    <sect2 id="sec:undo:mgmt">
+      <title>File management errors</title>
+
+      <para id="x_eb">The <command role="hg-cmd">hg revert</command> command is
+	useful for more than just modified files.  It lets you reverse
+	the results of all of Mercurial's file management
+	commands&emdash;<command role="hg-cmd">hg add</command>,
+	<command role="hg-cmd">hg remove</command>, and so on.</para>
+
+      <para id="x_ec">If you <command role="hg-cmd">hg add</command> a file,
+	then decide that in fact you don't want Mercurial to track it,
+	use <command role="hg-cmd">hg revert</command> to undo the
+	add.  Don't worry; Mercurial will not modify the file in any
+	way.  It will just <quote>unmark</quote> the file.</para>
+
+      &interaction.daily.revert.add;
+
+      <para id="x_ed">Similarly, if you ask Mercurial to <command
+	  role="hg-cmd">hg remove</command> a file, you can use
+	<command role="hg-cmd">hg revert</command> to restore it to
+	the contents it had as of the parent of the working directory.
+	&interaction.daily.revert.remove; This works just as
+	well for a file that you deleted by hand, without telling
+	Mercurial (recall that in Mercurial terminology, this kind of
+	file is called <quote>missing</quote>).</para>
+
+      &interaction.daily.revert.missing;
+
+      <para id="x_ee">If you revert a <command role="hg-cmd">hg copy</command>,
+	the copied-to file remains in your working directory
+	afterwards, untracked.  Since a copy doesn't affect the
+	copied-from file in any way, Mercurial doesn't do anything
+	with the copied-from file.</para>
+
+      &interaction.daily.revert.copy;
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Dealing with committed changes</title>
+
+    <para id="x_f5">Consider a case where you have committed a change
+      <emphasis>a</emphasis>, and another change
+      <emphasis>b</emphasis> on top of it; you then realise that
+      change <emphasis>a</emphasis> was incorrect.  Mercurial lets you
+      <quote>back out</quote> an entire changeset automatically, and
+      building blocks that let you reverse part of a changeset by
+      hand.</para>
+
+    <para id="x_f6">Before you read this section, here's something to
+      keep in mind: the <command role="hg-cmd">hg backout</command>
+      command undoes the effect of a change by
+      <emphasis>adding</emphasis> to your repository's history, not by
+      modifying or erasing it.  It's the right tool to use if you're
+      fixing bugs, but not if you're trying to undo some change that
+      has catastrophic consequences.  To deal with those, see
+      <xref linkend="sec:undo:aaaiiieee"/>.</para>
+
+    <sect2>
+      <title>Backing out a changeset</title>
+
+      <para id="x_f7">The <command role="hg-cmd">hg backout</command> command
+	lets you <quote>undo</quote> the effects of an entire
+	changeset in an automated fashion.  Because Mercurial's
+	history is immutable, this command <emphasis>does
+	  not</emphasis> get rid of the changeset you want to undo.
+	Instead, it creates a new changeset that
+	<emphasis>reverses</emphasis> the effect of the to-be-undone
+	changeset.</para>
+
+      <para id="x_f8">The operation of the <command role="hg-cmd">hg
+	  backout</command> command is a little intricate, so let's
+	illustrate it with some examples.  First, we'll create a
+	repository with some simple changes.</para>
+
+      &interaction.backout.init;
+
+      <para id="x_f9">The <command role="hg-cmd">hg backout</command> command
+	takes a single changeset ID as its argument; this is the
+	changeset to back out.  Normally, <command role="hg-cmd">hg
+	  backout</command> will drop you into a text editor to write
+	a commit message, so you can record why you're backing the
+	change out.  In this example, we provide a commit message on
+	the command line using the <option
+	  role="hg-opt-backout">-m</option> option.</para>
+
+    </sect2>
+    <sect2>
+      <title>Backing out the tip changeset</title>
+
+      <para id="x_fa">We're going to start by backing out the last changeset we
+	committed.</para>
+
+      &interaction.backout.simple;
+
+      <para id="x_fb">You can see that the second line from
+	<filename>myfile</filename> is no longer present.  Taking a
+	look at the output of <command role="hg-cmd">hg log</command>
+	gives us an idea of what the <command role="hg-cmd">hg
+	  backout</command> command has done.
+	&interaction.backout.simple.log; Notice that the new changeset
+	that <command role="hg-cmd">hg backout</command> has created
+	is a child of the changeset we backed out.  It's easier to see
+	this in <xref linkend="fig:undo:backout"/>, which presents a
+	graphical view of the change history.  As you can see, the
+	history is nice and linear.</para>
+
+      <figure id="fig:undo:backout">
+	<title>Backing out a change using the <command
+	    role="hg-cmd">hg backout</command> command</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/undo-simple.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+    </sect2>
+    <sect2>
+      <title>Backing out a non-tip change</title>
+
+      <para id="x_fd">If you want to back out a change other than the last one
+	you committed, pass the <option
+	  role="hg-opt-backout">--merge</option> option to the
+	<command role="hg-cmd">hg backout</command> command.</para>
+
+      &interaction.backout.non-tip.clone;
+
+      <para id="x_fe">This makes backing out any changeset a
+	<quote>one-shot</quote> operation that's usually simple and
+	fast.</para>
+
+      &interaction.backout.non-tip.backout;
+
+      <para id="x_ff">If you take a look at the contents of
+	<filename>myfile</filename> after the backout finishes, you'll
+	see that the first and third changes are present, but not the
+	second.</para>
+
+      &interaction.backout.non-tip.cat;
+
+      <para id="x_100">As the graphical history in <xref
+	  linkend="fig:undo:backout-non-tip"/> illustrates, Mercurial
+	still commits one change in this kind of situation (the
+	box-shaped node is the ones that Mercurial commits
+	automatically), but the revision graph now looks different.
+	Before Mercurial begins the backout process, it first
+	remembers what the current parent of the working directory is.
+	It then backs out the target changeset, and commits that as a
+	changeset.  Finally, it merges back to the previous parent of
+	the working directory, but notice that it <emphasis>does not
+	  commit</emphasis> the result of the merge.  The repository
+	now contains two heads, and the working directory is in a
+	merge state.</para>
+
+      <figure id="fig:undo:backout-non-tip">
+	<title>Automated backout of a non-tip change using the
+	  <command role="hg-cmd">hg backout</command> command</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/undo-non-tip.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_103">The result is that you end up <quote>back where you
+	  were</quote>, only with some extra history that undoes the
+	effect of the changeset you wanted to back out.</para>
+
+      <para id="x_6b9">You might wonder why Mercurial does not commit the result
+	of the merge that it performed.  The reason lies in Mercurial
+	behaving conservatively: a merge naturally has more scope for
+	error than simply undoing the effect of the tip changeset,
+	so your work will be safest if you first inspect (and test!)
+	the result of the merge, <emphasis>then</emphasis> commit
+	it.</para>
+
+      <sect3>
+	<title>Always use the <option
+	    role="hg-opt-backout">--merge</option> option</title>
+
+	<para id="x_104">In fact, since the <option
+	    role="hg-opt-backout">--merge</option> option will do the
+	  <quote>right thing</quote> whether or not the changeset
+	  you're backing out is the tip (i.e. it won't try to merge if
+	  it's backing out the tip, since there's no need), you should
+	  <emphasis>always</emphasis> use this option when you run the
+	  <command role="hg-cmd">hg backout</command> command.</para>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Gaining more control of the backout process</title>
+
+      <para id="x_105">While I've recommended that you always use the <option
+	  role="hg-opt-backout">--merge</option> option when backing
+	out a change, the <command role="hg-cmd">hg backout</command>
+	command lets you decide how to merge a backout changeset.
+	Taking control of the backout process by hand is something you
+	will rarely need to do, but it can be useful to understand
+	what the <command role="hg-cmd">hg backout</command> command
+	is doing for you automatically.  To illustrate this, let's
+	clone our first repository, but omit the backout change that
+	it contains.</para>
+
+      &interaction.backout.manual.clone;
+
+      <para id="x_106">As with our
+	earlier example, We'll commit a third changeset, then back out
+	its parent, and see what happens.</para>
+
+      &interaction.backout.manual.backout;
+
+      <para id="x_107">Our new changeset is again a descendant of the changeset
+	we backout out; it's thus a new head, <emphasis>not</emphasis>
+	a descendant of the changeset that was the tip.  The <command
+	  role="hg-cmd">hg backout</command> command was quite
+	explicit in telling us this.</para>
+
+      &interaction.backout.manual.log;
+
+      <para id="x_108">Again, it's easier to see what has happened by looking at
+	a graph of the revision history, in <xref
+	  linkend="fig:undo:backout-manual"/>.  This makes it clear
+	that when we use <command role="hg-cmd">hg backout</command>
+	to back out a change other than the tip, Mercurial adds a new
+	head to the repository (the change it committed is
+	box-shaped).</para>
+
+      <figure id="fig:undo:backout-manual">
+	<title>Backing out a change using the <command
+	    role="hg-cmd">hg backout</command> command</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/undo-manual.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_10a">After the <command role="hg-cmd">hg backout</command>
+	command has completed, it leaves the new
+	<quote>backout</quote> changeset as the parent of the working
+	directory.</para>
+
+      &interaction.backout.manual.parents;
+
+      <para id="x_10b">Now we have two isolated sets of changes.</para>
+
+      &interaction.backout.manual.heads;
+
+      <para id="x_10c">Let's think about what we expect to see as the contents of
+	<filename>myfile</filename> now.  The first change should be
+	present, because we've never backed it out.  The second change
+	should be missing, as that's the change we backed out.  Since
+	the history graph shows the third change as a separate head,
+	we <emphasis>don't</emphasis> expect to see the third change
+	present in <filename>myfile</filename>.</para>
+
+      &interaction.backout.manual.cat;
+
+      <para id="x_10d">To get the third change back into the file, we just do a
+	normal merge of our two heads.</para>
+
+      &interaction.backout.manual.merge;
+
+      <para id="x_10e">Afterwards, the graphical history of our
+	repository looks like
+	<xref linkend="fig:undo:backout-manual-merge"/>.</para>
+
+      <figure id="fig:undo:backout-manual-merge">
+	<title>Manually merging a backout change</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/undo-manual-merge.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+    </sect2>
+    <sect2>
+      <title>Why <command role="hg-cmd">hg backout</command> works as
+	it does</title>
+
+      <para id="x_110">Here's a brief description of how the <command
+	  role="hg-cmd">hg backout</command> command works.</para>
+      <orderedlist>
+	<listitem><para id="x_111">It ensures that the working directory is
+	    <quote>clean</quote>, i.e. that the output of <command
+	      role="hg-cmd">hg status</command> would be empty.</para>
+	</listitem>
+	<listitem><para id="x_112">It remembers the current parent of the working
+	    directory.  Let's call this changeset
+	    <literal>orig</literal>.</para>
+	</listitem>
+	<listitem><para id="x_113">It does the equivalent of a <command
+	      role="hg-cmd">hg update</command> to sync the working
+	    directory to the changeset you want to back out.  Let's
+	    call this changeset <literal>backout</literal>.</para>
+	</listitem>
+	<listitem><para id="x_114">It finds the parent of that changeset.  Let's
+	    call that changeset <literal>parent</literal>.</para>
+	</listitem>
+	<listitem><para id="x_115">For each file that the
+	    <literal>backout</literal> changeset affected, it does the
+	    equivalent of a <command role="hg-cmd">hg revert -r
+	      parent</command> on that file, to restore it to the
+	    contents it had before that changeset was
+	    committed.</para>
+	</listitem>
+	<listitem><para id="x_116">It commits the result as a new changeset.
+	    This changeset has <literal>backout</literal> as its
+	    parent.</para>
+	</listitem>
+	<listitem><para id="x_117">If you specify <option
+	      role="hg-opt-backout">--merge</option> on the command
+	    line, it merges with <literal>orig</literal>, and commits
+	    the result of the merge.</para>
+	</listitem></orderedlist>
+
+      <para id="x_118">An alternative way to implement the <command
+	  role="hg-cmd">hg backout</command> command would be to
+	<command role="hg-cmd">hg export</command> the
+	to-be-backed-out changeset as a diff, then use the <option
+	  role="cmd-opt-patch">--reverse</option> option to the
+	<command>patch</command> command to reverse the effect of the
+	change without fiddling with the working directory.  This
+	sounds much simpler, but it would not work nearly as
+	well.</para>
+
+      <para id="x_119">The reason that <command role="hg-cmd">hg
+	  backout</command> does an update, a commit, a merge, and
+	another commit is to give the merge machinery the best chance
+	to do a good job when dealing with all the changes
+	<emphasis>between</emphasis> the change you're backing out and
+	the current tip.</para>
+
+      <para id="x_11a">If you're backing out a changeset that's 100 revisions
+	back in your project's history, the chances that the
+	<command>patch</command> command will be able to apply a
+	reverse diff cleanly are not good, because intervening changes
+	are likely to have <quote>broken the context</quote> that
+	<command>patch</command> uses to determine whether it can
+	apply a patch (if this sounds like gibberish, see <xref
+	  linkend="sec:mq:patch"/> for a
+	discussion of the <command>patch</command> command).  Also,
+	Mercurial's merge machinery will handle files and directories
+	being renamed, permission changes, and modifications to binary
+	files, none of which <command>patch</command> can deal
+	with.</para>
+
+    </sect2>
+  </sect1>
+  <sect1 id="sec:undo:aaaiiieee">
+    <title>Changes that should never have been</title>
+
+    <para id="x_11b">Most of the time, the <command role="hg-cmd">hg
+	backout</command> command is exactly what you need if you want
+      to undo the effects of a change.  It leaves a permanent record
+      of exactly what you did, both when committing the original
+      changeset and when you cleaned up after it.</para>
+
+    <para id="x_11c">On rare occasions, though, you may find that you've
+      committed a change that really should not be present in the
+      repository at all.  For example, it would be very unusual, and
+      usually considered a mistake, to commit a software project's
+      object files as well as its source files.  Object files have
+      almost no intrinsic value, and they're <emphasis>big</emphasis>,
+      so they increase the size of the repository and the amount of
+      time it takes to clone or pull changes.</para>
+
+    <para id="x_11d">Before I discuss the options that you have if you commit a
+      <quote>brown paper bag</quote> change (the kind that's so bad
+      that you want to pull a brown paper bag over your head), let me
+      first discuss some approaches that probably won't work.</para>
+
+    <para id="x_11e">Since Mercurial treats history as
+      accumulative&emdash;every change builds on top of all changes
+      that preceded it&emdash;you generally can't just make disastrous
+      changes disappear.  The one exception is when you've just
+      committed a change, and it hasn't been pushed or pulled into
+      another repository.  That's when you can safely use the <command
+	role="hg-cmd">hg rollback</command> command, as I detailed in
+      <xref linkend="sec:undo:rollback"/>.</para>
+
+    <para id="x_11f">After you've pushed a bad change to another repository, you
+      <emphasis>could</emphasis> still use <command role="hg-cmd">hg
+	rollback</command> to make your local copy of the change
+      disappear, but it won't have the consequences you want.  The
+      change will still be present in the remote repository, so it
+      will reappear in your local repository the next time you
+      pull.</para>
+
+    <para id="x_120">If a situation like this arises, and you know which
+      repositories your bad change has propagated into, you can
+      <emphasis>try</emphasis> to get rid of the change from
+      <emphasis>every</emphasis> one of those repositories.  This is,
+      of course, not a satisfactory solution: if you miss even a
+      single repository while you're expunging, the change is still
+      <quote>in the wild</quote>, and could propagate further.</para>
+
+    <para id="x_121">If you've committed one or more changes
+      <emphasis>after</emphasis> the change that you'd like to see
+      disappear, your options are further reduced. Mercurial doesn't
+      provide a way to <quote>punch a hole</quote> in history, leaving
+      changesets intact.</para>
+
+    <sect2>
+      <title>Backing out a merge</title>
+
+      <para id="x_6ba">Since merges are often complicated, it is not unheard of
+	for a merge to be mangled badly, but committed erroneously.
+	Mercurial provides an important safeguard against bad merges
+	by refusing to commit unresolved files, but human ingenuity
+	guarantees that it is still possible to mess a merge up and
+	commit it.</para>
+
+      <para id="x_6bb">Given a bad merge that has been committed, usually the
+	best way to approach it is to simply try to repair the damage
+	by hand.  A complete disaster that cannot be easily fixed up
+	by hand ought to be very rare, but the <command
+	  role="hg-cmd">hg backout</command> command may help in
+	making the cleanup easier. It offers a <option
+	  role="hg-opt-backout">--parent</option> option, which lets
+	you specify which parent to revert to when backing out a
+	merge.</para>
+
+      <figure id="fig:undo:bad-merge-1">
+	<title>A bad merge</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/bad-merge-1.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_6bc">Suppose we have a revision graph like that in <xref
+	  linkend="fig:undo:bad-merge-1"/>.  What we'd like is to
+	<emphasis>redo</emphasis> the merge of revisions 2 and
+	3.</para>
+
+      <para id="x_6bd">One way to do so would be as follows.</para>
+
+      <orderedlist>
+	<listitem>
+	  <para id="x_6be">Call <command role="hg-cmd">hg backout --rev=4
+	      --parent=2</command>.  This tells <command
+	      role="hg-cmd">hg backout</command> to back out revision
+	    4, which is the bad merge, and to when deciding which
+	    revision to prefer, to choose parent 2, one of the parents
+	    of the merge.  The effect can be seen in <xref
+	      linkend="fig:undo:bad-merge-2"/>.</para>
+	  <figure id="fig:undo:bad-merge-2">
+	    <title>Backing out the merge, favoring one parent</title>
+	    <mediaobject>
+	      <imageobject><imagedata fileref="figs/bad-merge-2.png"/></imageobject>
+	      <textobject><phrase>XXX add text</phrase></textobject>
+	    </mediaobject>
+	  </figure>
+	</listitem>
+
+	<listitem>
+	  <para id="x_6bf">Call <command role="hg-cmd">hg backout --rev=4
+	      --parent=3</command>.  This tells <command
+	      role="hg-cmd">hg backout</command> to back out revision
+	    4 again, but this time to choose parent 3, the other
+	    parent of the merge.  The result is visible in <xref
+	    linkend="fig:undo:bad-merge-3"/>, in which the repository
+	    now contains three heads.</para>
+	  <figure id="fig:undo:bad-merge-3">
+	    <title>Backing out the merge, favoring the other
+	      parent</title>
+	    <mediaobject>
+	      <imageobject><imagedata fileref="figs/bad-merge-3.png"/></imageobject>
+	      <textobject><phrase>XXX add text</phrase></textobject>
+	    </mediaobject>
+	  </figure>
+	</listitem>
+
+	<listitem>
+	  <para id="x_6c0">Redo the bad merge by merging the two backout heads,
+	    which reduces the number of heads in the repository to
+	    two, as can be seen in <xref
+	      linkend="fig:undo:bad-merge-4"/>.</para>
+	  <figure id="fig:undo:bad-merge-4">
+	    <title>Merging the backouts</title>
+	    <mediaobject>
+	      <imageobject><imagedata fileref="figs/bad-merge-4.png"/></imageobject>
+	      <textobject><phrase>XXX add text</phrase></textobject>
+	    </mediaobject>
+	  </figure>
+	</listitem>
+
+	<listitem>
+	  <para id="x_6c1">Merge with the commit that was made after the bad
+	    merge, as shown in <xref
+	      linkend="fig:undo:bad-merge-5"/>.</para>
+	  <figure id="fig:undo:bad-merge-5">
+	    <title>Merging the backouts</title>
+	    <mediaobject>
+	      <imageobject><imagedata fileref="figs/bad-merge-5.png"/></imageobject>
+	      <textobject><phrase>XXX add text</phrase></textobject>
+	    </mediaobject>
+	  </figure>
+	</listitem>
+      </orderedlist>
+    </sect2>
+
+    <sect2>
+      <title>Protect yourself from <quote>escaped</quote>
+	changes</title>
+
+      <para id="x_123">If you've committed some changes to your local repository
+	and they've been pushed or pulled somewhere else, this isn't
+	necessarily a disaster.  You can protect yourself ahead of
+	time against some classes of bad changeset.  This is
+	particularly easy if your team usually pulls changes from a
+	central repository.</para>
+
+      <para id="x_124">By configuring some hooks on that repository to validate
+	incoming changesets (see chapter <xref linkend="chap:hook"/>),
+	you can
+	automatically prevent some kinds of bad changeset from being
+	pushed to the central repository at all.  With such a
+	configuration in place, some kinds of bad changeset will
+	naturally tend to <quote>die out</quote> because they can't
+	propagate into the central repository.  Better yet, this
+	happens without any need for explicit intervention.</para>
+
+      <para id="x_125">For instance, an incoming change hook that
+	verifies that a changeset will actually compile can prevent
+	people from inadvertently <quote>breaking the
+	  build</quote>.</para>
+    </sect2>
+
+    <sect2>
+      <title>What to do about sensitive changes that escape</title>
+
+      <para id="x_6c2">Even a carefully run project can suffer an unfortunate
+	event such as the committing and uncontrolled propagation of a
+	file that contains important passwords.</para>
+
+      <para id="x_6c3">If something like this happens to you, and the information
+	that gets accidentally propagated is truly sensitive, your
+	first step should be to mitigate the effect of the leak
+	without trying to control the leak itself. If you are not 100%
+	certain that you know exactly who could have seen the changes,
+	you should immediately change passwords, cancel credit cards,
+	or find some other way to make sure that the information that
+	has leaked is no longer useful.  In other words, assume that
+	the change has propagated far and wide, and that there's
+	nothing more you can do.</para>
+
+      <para id="x_6c4">You might hope that there would be mechanisms you could
+	use to either figure out who has seen a change or to erase the
+	change permanently everywhere, but there are good reasons why
+	these are not possible.</para>
+
+      <para id="x_6c5">Mercurial does not provide an audit trail of who has
+	pulled changes from a repository, because it is usually either
+	impossible to record such information or trivial to spoof it.
+	In a multi-user or networked environment, you should thus be
+	extremely skeptical of yourself if you think that you have
+	identified every place that a sensitive changeset has
+	propagated to.  Don't forget that people can and will send
+	bundles by email, have their backup software save data
+	offsite, carry repositories on USB sticks, and find other
+	completely innocent ways to confound your attempts to track
+	down every copy of a problematic change.</para>
+
+      <para id="x_6c6">Mercurial also does not provide a way to make a file or
+	changeset completely disappear from history, because there is
+	no way to enforce its disappearance; someone could easily
+	modify their copy of Mercurial to ignore such directives. In
+	addition, even if Mercurial provided such a capability,
+	someone who simply hadn't pulled a <quote>make this file
+	  disappear</quote> changeset wouldn't be affected by it, nor
+	would web crawlers visiting at the wrong time, disk backups,
+	or other mechanisms.  Indeed, no distributed revision control
+	system can make data reliably vanish. Providing the illusion
+	of such control could easily give a false sense of security,
+	and be worse than not providing it at all.</para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="sec:undo:bisect">
+    <title>Finding the source of a bug</title>
+
+    <para id="x_126">While it's all very well to be able to back out a changeset
+      that introduced a bug, this requires that you know which
+      changeset to back out.  Mercurial provides an invaluable
+      command, called <command role="hg-cmd">hg bisect</command>, that
+      helps you to automate this process and accomplish it very
+      efficiently.</para>
+
+    <para id="x_127">The idea behind the <command role="hg-cmd">hg
+	bisect</command> command is that a changeset has introduced
+      some change of behavior that you can identify with a simple
+      pass/fail test.  You don't know which piece of code introduced the
+      change, but you know how to test for the presence of the bug.
+      The <command role="hg-cmd">hg bisect</command> command uses your
+      test to direct its search for the changeset that introduced the
+      code that caused the bug.</para>
+
+    <para id="x_128">Here are a few scenarios to help you understand how you
+      might apply this command.</para>
+    <itemizedlist>
+      <listitem><para id="x_129">The most recent version of your software has a
+	  bug that you remember wasn't present a few weeks ago, but
+	  you don't know when it was introduced.  Here, your binary
+	  test checks for the presence of that bug.</para>
+      </listitem>
+      <listitem><para id="x_12a">You fixed a bug in a rush, and now it's time to
+	  close the entry in your team's bug database.  The bug
+	  database requires a changeset ID when you close an entry,
+	  but you don't remember which changeset you fixed the bug in.
+	  Once again, your binary test checks for the presence of the
+	  bug.</para>
+      </listitem>
+      <listitem><para id="x_12b">Your software works correctly, but runs 15%
+	  slower than the last time you measured it.  You want to know
+	  which changeset introduced the performance regression.  In
+	  this case, your binary test measures the performance of your
+	  software, to see whether it's <quote>fast</quote> or
+	  <quote>slow</quote>.</para>
+      </listitem>
+      <listitem><para id="x_12c">The sizes of the components of your project that
+	  you ship exploded recently, and you suspect that something
+	  changed in the way you build your project.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_12d">From these examples, it should be clear that the <command
+	role="hg-cmd">hg bisect</command> command is not useful only
+      for finding the sources of bugs.  You can use it to find any
+      <quote>emergent property</quote> of a repository (anything that
+      you can't find from a simple text search of the files in the
+      tree) for which you can write a binary test.</para>
+
+    <para id="x_12e">We'll introduce a little bit of terminology here, just to
+      make it clear which parts of the search process are your
+      responsibility, and which are Mercurial's.  A
+      <emphasis>test</emphasis> is something that
+      <emphasis>you</emphasis> run when <command role="hg-cmd">hg
+	bisect</command> chooses a changeset.  A
+      <emphasis>probe</emphasis> is what <command role="hg-cmd">hg
+	bisect</command> runs to tell whether a revision is good.
+      Finally, we'll use the word <quote>bisect</quote>, as both a
+      noun and a verb, to stand in for the phrase <quote>search using
+	the <command role="hg-cmd">hg bisect</command>
+	command</quote>.</para>
+
+    <para id="x_12f">One simple way to automate the searching process would be
+      simply to probe every changeset.  However, this scales poorly.
+      If it took ten minutes to test a single changeset, and you had
+      10,000 changesets in your repository, the exhaustive approach
+      would take on average 35 <emphasis>days</emphasis> to find the
+      changeset that introduced a bug.  Even if you knew that the bug
+      was introduced by one of the last 500 changesets, and limited
+      your search to those, you'd still be looking at over 40 hours to
+      find the changeset that introduced your bug.</para>
+
+    <para id="x_130">What the <command role="hg-cmd">hg bisect</command> command
+      does is use its knowledge of the <quote>shape</quote> of your
+      project's revision history to perform a search in time
+      proportional to the <emphasis>logarithm</emphasis> of the number
+      of changesets to check (the kind of search it performs is called
+      a dichotomic search).  With this approach, searching through
+      10,000 changesets will take less than three hours, even at ten
+      minutes per test (the search will require about 14 tests).
+      Limit your search to the last hundred changesets, and it will
+      take only about an hour (roughly seven tests).</para>
+
+    <para id="x_131">The <command role="hg-cmd">hg bisect</command> command is
+      aware of the <quote>branchy</quote> nature of a Mercurial
+      project's revision history, so it has no problems dealing with
+      branches, merges, or multiple heads in a repository.  It can
+      prune entire branches of history with a single probe, which is
+      how it operates so efficiently.</para>
+
+    <sect2>
+      <title>Using the <command role="hg-cmd">hg bisect</command>
+	command</title>
+
+      <para id="x_132">Here's an example of <command role="hg-cmd">hg
+	  bisect</command> in action.</para>
+
+      <note>
+	<para id="x_133">  In versions 0.9.5 and earlier of Mercurial, <command
+	    role="hg-cmd">hg bisect</command> was not a core command:
+	  it was distributed with Mercurial as an extension. This
+	  section describes the built-in command, not the old
+	  extension.</para>
+      </note>
+
+      <para id="x_134">Now let's create a repository, so that we can try out the
+	<command role="hg-cmd">hg bisect</command> command in
+	isolation.</para>
+
+      &interaction.bisect.init;
+
+      <para id="x_135">We'll simulate a project that has a bug in it in a
+	simple-minded way: create trivial changes in a loop, and
+	nominate one specific change that will have the
+	<quote>bug</quote>.  This loop creates 35 changesets, each
+	adding a single file to the repository. We'll represent our
+	<quote>bug</quote> with a file that contains the text <quote>i
+	  have a gub</quote>.</para>
+
+      &interaction.bisect.commits;
+
+      <para id="x_136">The next thing that we'd like to do is figure out how to
+	use the <command role="hg-cmd">hg bisect</command> command.
+	We can use Mercurial's normal built-in help mechanism for
+	this.</para>
+
+      &interaction.bisect.help;
+
+      <para id="x_137">The <command role="hg-cmd">hg bisect</command> command
+	works in steps.  Each step proceeds as follows.</para>
+      <orderedlist>
+	<listitem><para id="x_138">You run your binary test.</para>
+	  <itemizedlist>
+	    <listitem><para id="x_139">If the test succeeded, you tell <command
+		  role="hg-cmd">hg bisect</command> by running the
+		<command role="hg-cmd">hg bisect --good</command>
+		command.</para>
+	    </listitem>
+	    <listitem><para id="x_13a">If it failed, run the <command
+		  role="hg-cmd">hg bisect --bad</command>
+		command.</para></listitem></itemizedlist>
+	</listitem>
+	<listitem><para id="x_13b">The command uses your information to decide
+	    which changeset to test next.</para>
+	</listitem>
+	<listitem><para id="x_13c">It updates the working directory to that
+	    changeset, and the process begins again.</para>
+	</listitem></orderedlist>
+      <para id="x_13d">The process ends when <command role="hg-cmd">hg
+	  bisect</command> identifies a unique changeset that marks
+	the point where your test transitioned from
+	<quote>succeeding</quote> to <quote>failing</quote>.</para>
+
+      <para id="x_13e">To start the search, we must run the <command
+	  role="hg-cmd">hg bisect --reset</command> command.</para>
+
+      &interaction.bisect.search.init;
+
+      <para id="x_13f">In our case, the binary test we use is simple: we check to
+	see if any file in the repository contains the string <quote>i
+	  have a gub</quote>.  If it does, this changeset contains the
+	change that <quote>caused the bug</quote>.  By convention, a
+	changeset that has the property we're searching for is
+	<quote>bad</quote>, while one that doesn't is
+	<quote>good</quote>.</para>
+
+      <para id="x_140">Most of the time, the revision to which the working
+	directory is synced (usually the tip) already exhibits the
+	problem introduced by the buggy change, so we'll mark it as
+	<quote>bad</quote>.</para>
+
+      &interaction.bisect.search.bad-init;
+
+      <para id="x_141">Our next task is to nominate a changeset that we know
+	<emphasis>doesn't</emphasis> have the bug; the <command
+	  role="hg-cmd">hg bisect</command> command will
+	<quote>bracket</quote> its search between the first pair of
+	good and bad changesets.  In our case, we know that revision
+	10 didn't have the bug.  (I'll have more words about choosing
+	the first <quote>good</quote> changeset later.)</para>
+
+      &interaction.bisect.search.good-init;
+
+      <para id="x_142">Notice that this command printed some output.</para>
+      <itemizedlist>
+	<listitem><para id="x_143">It told us how many changesets it must
+	    consider before it can identify the one that introduced
+	    the bug, and how many tests that will require.</para>
+	</listitem>
+	<listitem><para id="x_144">It updated the working directory to the next
+	    changeset to test, and told us which changeset it's
+	    testing.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_145">We now run our test in the working directory.  We use the
+	<command>grep</command> command to see if our
+	<quote>bad</quote> file is present in the working directory.
+	If it is, this revision is bad; if not, this revision is good.
+	&interaction.bisect.search.step1;</para>
+
+      <para id="x_146">This test looks like a perfect candidate for automation,
+	so let's turn it into a shell function.</para>
+      &interaction.bisect.search.mytest;
+
+      <para id="x_147">We can now run an entire test step with a single command,
+	<literal>mytest</literal>.</para>
+
+      &interaction.bisect.search.step2;
+
+      <para id="x_148">A few more invocations of our canned test step command,
+	and we're done.</para>
+
+      &interaction.bisect.search.rest;
+
+      <para id="x_149">Even though we had 40 changesets to search through, the
+	<command role="hg-cmd">hg bisect</command> command let us find
+	the changeset that introduced our <quote>bug</quote> with only
+	five tests.  Because the number of tests that the <command
+	  role="hg-cmd">hg bisect</command> command performs grows
+	logarithmically with the number of changesets to search, the
+	advantage that it has over the <quote>brute force</quote>
+	search approach increases with every changeset you add.</para>
+
+    </sect2>
+    <sect2>
+      <title>Cleaning up after your search</title>
+
+      <para id="x_14a">When you're finished using the <command role="hg-cmd">hg
+	  bisect</command> command in a repository, you can use the
+	<command role="hg-cmd">hg bisect --reset</command> command to
+	drop the information it was using to drive your search.  The
+	command doesn't use much space, so it doesn't matter if you
+	forget to run this command.  However, <command
+	  role="hg-cmd">hg bisect</command> won't let you start a new
+	search in that repository until you do a <command
+	  role="hg-cmd">hg bisect --reset</command>.</para>
+
+      &interaction.bisect.search.reset;
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Tips for finding bugs effectively</title>
+
+    <sect2>
+      <title>Give consistent input</title>
+
+      <para id="x_14b">The <command role="hg-cmd">hg bisect</command> command
+	requires that you correctly report the result of every test
+	you perform.  If you tell it that a test failed when it really
+	succeeded, it <emphasis>might</emphasis> be able to detect the
+	inconsistency.  If it can identify an inconsistency in your
+	reports, it will tell you that a particular changeset is both
+	good and bad. However, it can't do this perfectly; it's about
+	as likely to report the wrong changeset as the source of the
+	bug.</para>
+
+    </sect2>
+    <sect2>
+      <title>Automate as much as possible</title>
+
+      <para id="x_14c">When I started using the <command role="hg-cmd">hg
+	  bisect</command> command, I tried a few times to run my
+	tests by hand, on the command line.  This is an approach that
+	I, at least, am not suited to.  After a few tries, I found
+	that I was making enough mistakes that I was having to restart
+	my searches several times before finally getting correct
+	results.</para>
+
+      <para id="x_14d">My initial problems with driving the <command
+	  role="hg-cmd">hg bisect</command> command by hand occurred
+	even with simple searches on small repositories; if the
+	problem you're looking for is more subtle, or the number of
+	tests that <command role="hg-cmd">hg bisect</command> must
+	perform increases, the likelihood of operator error ruining
+	the search is much higher.  Once I started automating my
+	tests, I had much better results.</para>
+
+      <para id="x_14e">The key to automated testing is twofold:</para>
+      <itemizedlist>
+	<listitem><para id="x_14f">always test for the same symptom, and</para>
+	</listitem>
+	<listitem><para id="x_150">always feed consistent input to the <command
+	      role="hg-cmd">hg bisect</command> command.</para>
+	</listitem></itemizedlist>
+      <para id="x_151">In my tutorial example above, the <command>grep</command>
+	command tests for the symptom, and the <literal>if</literal>
+	statement takes the result of this check and ensures that we
+	always feed the same input to the <command role="hg-cmd">hg
+	  bisect</command> command.  The <literal>mytest</literal>
+	function marries these together in a reproducible way, so that
+	every test is uniform and consistent.</para>
+
+    </sect2>
+    <sect2>
+      <title>Check your results</title>
+
+      <para id="x_152">Because the output of a <command role="hg-cmd">hg
+	  bisect</command> search is only as good as the input you
+	give it, don't take the changeset it reports as the absolute
+	truth.  A simple way to cross-check its report is to manually
+	run your test at each of the following changesets:</para>
+      <itemizedlist>
+	<listitem><para id="x_153">The changeset that it reports as the first bad
+	    revision.  Your test should still report this as
+	    bad.</para>
+	</listitem>
+	<listitem><para id="x_154">The parent of that changeset (either parent,
+	    if it's a merge). Your test should report this changeset
+	    as good.</para>
+	</listitem>
+	<listitem><para id="x_155">A child of that changeset.  Your test should
+	    report this changeset as bad.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+    <sect2>
+      <title>Beware interference between bugs</title>
+
+      <para id="x_156">It's possible that your search for one bug could be
+	disrupted by the presence of another.  For example, let's say
+	your software crashes at revision 100, and worked correctly at
+	revision 50.  Unknown to you, someone else introduced a
+	different crashing bug at revision 60, and fixed it at
+	revision 80.  This could distort your results in one of
+	several ways.</para>
+
+      <para id="x_157">It is possible that this other bug completely
+	<quote>masks</quote> yours, which is to say that it occurs
+	before your bug has a chance to manifest itself.  If you can't
+	avoid that other bug (for example, it prevents your project
+	from building), and so can't tell whether your bug is present
+	in a particular changeset, the <command role="hg-cmd">hg
+	  bisect</command> command cannot help you directly.  Instead,
+	you can mark a changeset as untested by running <command
+	  role="hg-cmd">hg bisect --skip</command>.</para>
+
+      <para id="x_158">A different problem could arise if your test for a bug's
+	presence is not specific enough.  If you check for <quote>my
+	  program crashes</quote>, then both your crashing bug and an
+	unrelated crashing bug that masks it will look like the same
+	thing, and mislead <command role="hg-cmd">hg
+	  bisect</command>.</para>
+
+      <para id="x_159">Another useful situation in which to use <command
+	  role="hg-cmd">hg bisect --skip</command> is if you can't
+	test a revision because your project was in a broken and hence
+	untestable state at that revision, perhaps because someone
+	checked in a change that prevented the project from
+	building.</para>
+
+    </sect2>
+    <sect2>
+      <title>Bracket your search lazily</title>
+
+      <para id="x_15a">Choosing the first <quote>good</quote> and
+	<quote>bad</quote> changesets that will mark the end points of
+	your search is often easy, but it bears a little discussion
+	nevertheless.  From the perspective of <command
+	  role="hg-cmd">hg bisect</command>, the <quote>newest</quote>
+	changeset is conventionally <quote>bad</quote>, and the older
+	changeset is <quote>good</quote>.</para>
+
+      <para id="x_15b">If you're having trouble remembering when a suitable
+	<quote>good</quote> change was, so that you can tell <command
+	  role="hg-cmd">hg bisect</command>, you could do worse than
+	testing changesets at random.  Just remember to eliminate
+	contenders that can't possibly exhibit the bug (perhaps
+	because the feature with the bug isn't present yet) and those
+	where another problem masks the bug (as I discussed
+	above).</para>
+
+      <para id="x_15c">Even if you end up <quote>early</quote> by thousands of
+	changesets or months of history, you will only add a handful
+	of tests to the total number that <command role="hg-cmd">hg
+	  bisect</command> must perform, thanks to its logarithmic
+	behavior.</para>
+
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch10-hook.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,1928 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:hook">
+  <?dbhtml filename="handling-repository-events-with-hooks.html"?>
+  <title>Handling repository events with hooks</title>
+
+  <para id="x_1e6">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.</para>
+
+  <para id="x_1e7">The name Mercurial uses for one of these actions is a
+    <emphasis>hook</emphasis>. Hooks are called
+    <quote>triggers</quote> in some revision control systems, but the
+    two names refer to the same idea.</para>
+
+  <sect1>
+    <title>An overview of hooks in Mercurial</title>
+
+    <para id="x_1e8">Here is a brief list of the hooks that Mercurial
+      supports. We will revisit each of these hooks in more detail
+      later, in <xref linkend="sec:hook:ref"/>.</para>
+
+    <para id="x_1f6">Each of the hooks whose description begins with the word
+      <quote>Controlling</quote> 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.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_1e9"><literal role="hook">changegroup</literal>: This
+	  is run after a group of changesets has been brought into the
+	  repository from elsewhere.</para>
+      </listitem>
+      <listitem><para id="x_1ea"><literal role="hook">commit</literal>: This is
+	  run after a new changeset has been created in the local
+	  repository.</para>
+      </listitem>
+      <listitem><para id="x_1eb"><literal role="hook">incoming</literal>: This is
+	  run once for each new changeset that is brought into the
+	  repository from elsewhere.  Notice the difference from
+	  <literal role="hook">changegroup</literal>, which is run
+	  once per <emphasis>group</emphasis> of changesets brought
+	  in.</para>
+      </listitem>
+      <listitem><para id="x_1ec"><literal role="hook">outgoing</literal>: This is
+	  run after a group of changesets has been transmitted from
+	  this repository.</para>
+      </listitem>
+      <listitem><para id="x_1ed"><literal role="hook">prechangegroup</literal>:
+	  This is run before starting to bring a group of changesets
+	  into the repository.
+	</para>
+      </listitem>
+      <listitem><para id="x_1ee"><literal role="hook">precommit</literal>:
+	  Controlling. This is run before starting a commit.
+	</para>
+      </listitem>
+      <listitem><para id="x_1ef"><literal role="hook">preoutgoing</literal>:
+	  Controlling. This is run before starting to transmit a group
+	  of changesets from this repository.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f0"><literal role="hook">pretag</literal>:
+	  Controlling. This is run before creating a tag.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f1"><literal
+	    role="hook">pretxnchangegroup</literal>: 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.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f2"><literal role="hook">pretxncommit</literal>:
+	  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.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f3"><literal role="hook">preupdate</literal>:
+	  Controlling. This is run before starting an update or merge
+	  of the working directory.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f4"><literal role="hook">tag</literal>: This is run
+	  after a tag is created.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f5"><literal role="hook">update</literal>: This is
+	  run after an update or merge of the working directory has
+	  finished.
+	</para>
+      </listitem></itemizedlist>
+
+  </sect1>
+  <sect1>
+    <title>Hooks and security</title>
+
+    <sect2>
+      <title>Hooks are run with your privileges</title>
+
+      <para id="x_1f7">When you run a Mercurial command in a repository, and the
+	command causes a hook to run, that hook runs on
+	<emphasis>your</emphasis> system, under
+	<emphasis>your</emphasis> user account, with
+	<emphasis>your</emphasis> 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.
+      </para>
+
+      <para id="x_1f8">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 <filename role="special">~/.hgrc</filename>
+	file.
+      </para>
+
+      <para id="x_1f9">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 <quote>you</quote>.
+	For example, if you <command role="hg-cmd">hg pull</command>
+	from that repository, and its <filename
+	  role="special">.hg/hgrc</filename> defines a local <literal
+	  role="hook">outgoing</literal> hook, that hook will run
+	under your user account, even though you don't own that
+	repository.
+      </para>
+
+      <note>
+	<para id="x_1fa">  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 <literal role="hook">outgoing</literal>
+	  hook will run under whatever account is executing the server
+	  process, on the server.
+	</para>
+      </note>
+
+      <para id="x_1fb">To see what hooks are defined in a repository,
+	use the <command role="hg-cmd">hg showconfig hooks</command>
+	command.  If you are working in one repository, but talking to
+	another that you do not own (e.g. using <command
+	  role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg
+	  incoming</command>), remember that it is the other
+	repository's hooks you should be checking, not your own.
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>Hooks do not propagate</title>
+
+      <para id="x_1fc">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.
+      </para>
+
+      <para id="x_1fd">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.
+      </para>
+
+      <para id="x_1fe">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.
+      </para>
+
+      <para id="x_1ff">In a corporate intranet, this is somewhat easier to
+	control, as you can for example provide a
+	<quote>standard</quote> installation of Mercurial on an NFS
+	filesystem, and use a site-wide <filename role="special">~/.hgrc</filename> file to define hooks that all users will
+	see.  However, this too has its limits; see below.
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>Hooks can be overridden</title>
+
+      <para id="x_200">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 behavior as you wish.
+      </para>
+
+      <para id="x_201">If you deploy a system- or site-wide <filename
+	  role="special">~/.hgrc</filename> file that defines some
+	hooks, you should thus understand that your users can disable
+	or override those hooks.
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>Ensuring that critical hooks are run</title>
+
+      <para id="x_202">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 <filename role="special">~/.hgrc</filename> won't
+	work for remote users on laptops, and of course local users
+	can subvert it at will by overriding the hook.
+      </para>
+
+      <para id="x_203">Instead, you can set up your policies for use of Mercurial
+	so that people are expected to propagate changes through a
+	well-known <quote>canonical</quote> server that you have
+	locked down and configured appropriately.
+      </para>
+
+      <para id="x_204">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.
+      </para>
+
+      <para id="x_205">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.
+      </para>
+
+    </sect2>
+  </sect1>
+
+  <sect1 id="sec:hook:simple">
+    <title>A short tutorial on using hooks</title>
+
+    <para id="x_212">It is easy to write a Mercurial hook.  Let's start with a
+      hook that runs when you finish a <command role="hg-cmd">hg
+	commit</command>, and simply prints the hash of the changeset
+      you just created.  The hook is called <literal
+	role="hook">commit</literal>.
+    </para>
+
+    <para id="x_213">All hooks follow the pattern in this example.</para>
+
+&interaction.hook.simple.init;
+
+    <para id="x_214">You add an entry to the <literal
+	role="rc-hooks">hooks</literal> section of your <filename
+	role="special">~/.hgrc</filename>.  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</envar> in the example).
+    </para>
+
+    <sect2>
+      <title>Performing multiple actions per event</title>
+
+      <para id="x_215">Quite often, you will want to define more than one hook
+	for a particular kind of event, as shown below.</para>
+
+&interaction.hook.simple.ext;
+
+      <para id="x_216">Mercurial lets you do this by adding an
+	<emphasis>extension</emphasis> 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
+	<quote><literal>.</literal></quote> character), followed by
+	some more text of your choosing.  For example, Mercurial will
+	run both <literal>commit.foo</literal> and
+	<literal>commit.bar</literal> when the
+	<literal>commit</literal> event occurs.
+      </para>
+
+      <para id="x_217">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
+	<literal>commit.bar</literal> before
+	<literal>commit.foo</literal>, and <literal>commit</literal>
+	before both.
+      </para>
+
+      <para id="x_218">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 <xref
+	  linkend="sec:hook:perm"/> for an example).
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:perm">
+      <title>Controlling whether an activity can proceed</title>
+
+      <para id="x_219">In our earlier examples, we used the <literal
+	  role="hook">commit</literal> 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.
+      </para>
+
+      <para id="x_21a">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.
+      </para>
+
+      <para id="x_21b">The <literal role="hook">pretxncommit</literal> 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 <literal role="hook">pretxncommit</literal>
+	hook has the ability to decide whether the transaction can
+	complete, or must be rolled back.
+      </para>
+
+      <para id="x_21c">If the <literal role="hook">pretxncommit</literal> hook
+	exits with a status code of zero, the transaction is allowed
+	to complete; the commit finishes; and the <literal
+	  role="hook">commit</literal> hook is run.  If the <literal
+	  role="hook">pretxncommit</literal> hook exits with a
+	non-zero status code, the transaction is rolled back; the
+	metadata representing the changeset is erased; and the
+	<literal role="hook">commit</literal> hook is not run.
+      </para>
+
+&interaction.hook.simple.pretxncommit;
+
+      <para id="x_21d">The hook in the example above checks that a commit comment
+	contains a bug ID.  If it does, the commit can complete.  If
+	not, the commit is rolled back.
+      </para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Writing your own hooks</title>
+
+    <para id="x_21e">When you are writing a hook, you might find it useful to run
+      Mercurial either with the <option
+	role="hg-opt-global">-v</option> option, or the <envar
+	role="rc-item-ui">verbose</envar> config item set to
+      <quote>true</quote>.  When you do so, Mercurial will print a
+      message before it calls each hook.
+    </para>
+
+    <sect2 id="sec:hook:lang">
+      <title>Choosing how your hook should run</title>
+
+      <para id="x_21f">You can write a hook either as a normal
+	program&emdash;typically a shell script&emdash;or as a Python
+	function that is executed within the Mercurial process.
+      </para>
+
+      <para id="x_220">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.
+      </para>
+
+      <para id="x_221">An in-process Python hook has complete access to the
+	Mercurial API, and does not <quote>shell out</quote> 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.
+      </para>
+
+      <para id="x_222">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.
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:param">
+      <title>Hook parameters</title>
+
+      <para id="x_223">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.
+      </para>
+
+      <para id="x_224">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
+	<quote>true</quote>) or 0 (for <quote>false</quote>) as an
+	environment variable for an external hook.  If a hook
+	parameter is named <literal>foo</literal>, the keyword
+	argument for a Python hook will also be named
+	<literal>foo</literal>, while the environment variable for an
+	external hook will be named <literal>HG_FOO</literal>.
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>Hook return values and activity control</title>
+
+      <para id="x_225">A hook that executes successfully must exit with a status
+	of zero if external, or return boolean <quote>false</quote> if
+	in-process.  Failure is indicated with a non-zero exit status
+	from an external hook, or an in-process hook returning boolean
+	<quote>true</quote>.  If an in-process hook raises an
+	exception, the hook is considered to have failed.
+      </para>
+
+      <para id="x_226">For a hook that controls whether an activity can proceed,
+	zero/false means <quote>allow</quote>, while
+	non-zero/true/exception means <quote>deny</quote>.
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>Writing an external hook</title>
+
+      <para id="x_227">When you define an external hook in your <filename
+	  role="special">~/.hgrc</filename> 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.
+      </para>
+
+      <para id="x_228">An executable hook is always run with its current
+	directory set to a repository's root directory.
+      </para>
+
+      <para id="x_229">Each hook parameter is passed in as an environment
+	variable; the name is upper-cased, and prefixed with the
+	string <quote><literal>HG_</literal></quote>.
+      </para>
+
+      <para id="x_22a">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.
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>Telling Mercurial to use an in-process hook</title>
+
+      <para id="x_22b">The <filename role="special">~/.hgrc</filename> 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 <quote><literal>python:</literal></quote>, and continue
+	with the fully-qualified name of a callable object to use as
+	the hook's value.
+      </para>
+
+      <para id="x_22c">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</envar> right, it should <quote>just
+	  work</quote>.
+      </para>
+
+      <para id="x_22d">The following <filename role="special">~/.hgrc</filename>
+	example snippet illustrates the syntax and meaning of the
+	notions we just described.
+      </para>
+      <programlisting>[hooks]
+commit.example = python:mymodule.submodule.myhook</programlisting>
+      <para id="x_22e">When Mercurial runs the <literal>commit.example</literal>
+	hook, it imports <literal>mymodule.submodule</literal>, looks
+	for the callable object named <literal>myhook</literal>, and
+	calls it.
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>Writing an in-process hook</title>
+
+      <para id="x_22f">The simplest in-process hook does nothing, but illustrates
+	the basic shape of the hook API:
+      </para>
+      <programlisting>def myhook(ui, repo, **kwargs):
+    pass</programlisting>
+      <para id="x_230">The first argument to a Python hook is always a <literal
+	  role="py-mod-mercurial.ui">ui</literal> object.  The second
+	is a repository object; at the moment, it is always an
+	instance of <literal
+	  role="py-mod-mercurial.localrepo">localrepository</literal>.
+	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
+	<literal>**kwargs</literal> above.
+      </para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Some hook examples</title>
+
+    <sect2>
+      <title>Writing meaningful commit messages</title>
+
+      <para id="x_231">It's hard to imagine a useful commit message being very
+	short. The simple <literal role="hook">pretxncommit</literal>
+	hook of the example below will prevent you from committing a
+	changeset with a message that is less than ten bytes long.
+      </para>
+
+&interaction.hook.msglen.go;
+    </sect2>
+
+    <sect2>
+      <title>Checking for trailing whitespace</title>
+
+      <para id="x_232">An interesting use of a commit-related hook is to help you
+	to write cleaner code.  A simple example of <quote>cleaner
+	  code</quote> is the dictum that a change should not add any
+	new lines of text that contain <quote>trailing
+	  whitespace</quote>.  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.
+      </para>
+
+      <para id="x_233">You can use either the <literal
+	  role="hook">precommit</literal> or <literal
+	  role="hook">pretxncommit</literal> hook to tell whether you
+	have a trailing whitespace problem.  If you use the <literal
+	  role="hook">precommit</literal> 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</filename>, but the file
+	<filename>bar</filename> contains trailing whitespace, doing a
+	check in the <literal role="hook">precommit</literal> hook
+	will prevent you from committing <filename>foo</filename> due
+	to the problem with <filename>bar</filename>.  This doesn't
+	seem right.
+      </para>
+
+      <para id="x_234">Should you choose the <literal
+	  role="hook">pretxncommit</literal> 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 <command
+	  role="hg-cmd">hg commit</command> again.
+      </para>
+
+      &interaction.ch09-hook.ws.simple;
+
+      <para id="x_235">In this example, we introduce a simple <literal
+	  role="hook">pretxncommit</literal> 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.
+      </para>
+
+      &ch09-check_whitespace.py.lst;
+
+      <para id="x_236">The above version 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 the <option role="hg-opt-commit">-l filename</option>
+	option to <command role="hg-cmd">hg commit</command> to reuse
+	the saved commit message once you've corrected the problem.
+      </para>
+
+      &interaction.ch09-hook.ws.better;
+
+      <para id="x_237">As a final aside, note in the example above the
+	use of <command>sed</command>'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 (using
+	<command>perl</command> for good measure).</para>
+      <programlisting>perl -pi -e 's,\s+$,,' filename</programlisting>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Bundled hooks</title>
+
+    <para id="x_238">Mercurial ships with several bundled hooks.  You can find
+      them in the <filename class="directory">hgext</filename>
+      directory of a Mercurial source tree.  If you are using a
+      Mercurial binary package, the hooks will be located in the
+      <filename class="directory">hgext</filename> directory of
+      wherever your package installer put Mercurial.
+    </para>
+
+    <sect2>
+      <title><literal role="hg-ext">acl</literal>&emdash;access
+	control for parts of a repository</title>
+
+      <para id="x_239">The <literal role="hg-ext">acl</literal> 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.
+      </para>
+
+      <para id="x_23a">This extension implements access control based on the
+	identity of the user performing a push,
+	<emphasis>not</emphasis> 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.
+      </para>
+
+      <sect3>
+	<title>Configuring the <literal role="hook">acl</literal>
+	  hook</title>
+
+	<para id="x_23b">In order to manage incoming changesets, the <literal
+	    role="hg-ext">acl</literal> hook must be used as a
+	  <literal role="hook">pretxnchangegroup</literal> hook.  This
+	  lets it see which files are modified by each incoming
+	  changeset, and roll back a group of changesets if they
+	  modify <quote>forbidden</quote> files.  Example:
+	</para>
+	<programlisting>[hooks]
+pretxnchangegroup.acl = python:hgext.acl.hook</programlisting>
+
+	<para id="x_23c">The <literal role="hg-ext">acl</literal> extension is
+	  configured using three sections.
+	</para>
+
+	<para id="x_23d">The <literal role="rc-acl">acl</literal> section has
+	  only one entry, <envar role="rc-item-acl">sources</envar>,
+	  which lists the sources of incoming changesets that the hook
+	  should pay attention to.  You don't normally need to
+	  configure this section.
+	</para>
+	<itemizedlist>
+	  <listitem><para id="x_23e"><envar role="rc-item-acl">serve</envar>:
+	      Control incoming changesets that are arriving from a
+	      remote repository over http or ssh.  This is the default
+	      value of <envar role="rc-item-acl">sources</envar>, and
+	      usually the only setting you'll need for this
+	      configuration item.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_23f"><envar role="rc-item-acl">pull</envar>:
+	      Control incoming changesets that are arriving via a pull
+	      from a local repository.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_240"><envar role="rc-item-acl">push</envar>:
+	      Control incoming changesets that are arriving via a push
+	      from a local repository.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_241"><envar role="rc-item-acl">bundle</envar>:
+	      Control incoming changesets that are arriving from
+	      another repository via a bundle.
+	    </para>
+	  </listitem></itemizedlist>
+
+	<para id="x_242">The <literal role="rc-acl.allow">acl.allow</literal>
+	  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).
+	</para>
+
+	<para id="x_243">The <literal role="rc-acl.deny">acl.deny</literal>
+	  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.
+	</para>
+
+	<para id="x_244">The syntaxes for the <literal
+	    role="rc-acl.allow">acl.allow</literal> and <literal
+	    role="rc-acl.deny">acl.deny</literal> 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.
+	</para>
+
+	<para id="x_245">In the following example, the user
+	  <literal>docwriter</literal> can only push changes to the
+	  <filename class="directory">docs</filename> subtree of the
+	  repository, while <literal>intern</literal> can push changes
+	  to any file or directory except <filename
+	    class="directory">source/sensitive</filename>.
+	</para>
+	<programlisting>[acl.allow]
+docs/** = docwriter
+[acl.deny]
+source/sensitive/** = intern</programlisting>
+
+      </sect3>
+      <sect3>
+	<title>Testing and troubleshooting</title>
+
+	<para id="x_246">If you want to test the <literal
+	    role="hg-ext">acl</literal> 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 <option
+	    role="hg-opt-global">--debug</option> option, don't forget
+	  that you can enable debugging output in your <filename
+	    role="special">~/.hgrc</filename>:
+	</para>
+	<programlisting>[ui]
+debug = true</programlisting>
+	<para id="x_247">With this enabled, the <literal
+	    role="hg-ext">acl</literal> hook will print enough
+	  information to let you figure out why it is allowing or
+	  forbidding pushes from specific users.
+	</para>
+
+      </sect3>    </sect2>
+
+    <sect2>
+      <title><literal
+	  role="hg-ext">bugzilla</literal>&emdash;integration with
+	Bugzilla</title>
+
+      <para id="x_248">The <literal role="hg-ext">bugzilla</literal> 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.
+      </para>
+
+      <para id="x_249">It adds a comment to the bug that looks like this (you can
+	configure the contents of the comment&emdash;see below):
+      </para>
+      <programlisting>Changeset aad8b264143a, made by Joe User
+	&lt;joe.user@domain.com&gt; 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</programlisting>
+      <para id="x_24a">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.
+      </para>
+
+      <para id="x_24b">You can use the code in this hook as a starting point for
+	some more exotic Bugzilla integration recipes.  Here are a few
+	possibilities:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_24c">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 <literal
+	      role="hook">pretxncommit</literal> hook.  This would
+	    allow the hook to reject changes that didn't contain bug
+	    IDs.
+	  </para>
+	</listitem>
+	<listitem><para id="x_24d">Allow incoming changesets to automatically
+	    modify the <emphasis>state</emphasis> of a bug, as well as
+	    simply adding a comment.  For example, the hook could
+	    recognise the string <quote>fixed bug 31337</quote> as
+	    indicating that it should update the state of bug 31337 to
+	    <quote>requires testing</quote>.
+	  </para>
+	</listitem></itemizedlist>
+
+      <sect3 id="sec:hook:bugzilla:config">
+	<title>Configuring the <literal role="hook">bugzilla</literal>
+	  hook</title>
+
+	<para id="x_24e">You should configure this hook in your server's
+	  <filename role="special">~/.hgrc</filename> as an <literal
+	    role="hook">incoming</literal> hook, for example as
+	  follows:
+	</para>
+	<programlisting>[hooks]
+incoming.bugzilla = python:hgext.bugzilla.hook</programlisting>
+
+	<para id="x_24f">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.
+	</para>
+
+	<para id="x_250">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
+	  <citation>web:mysql-python</citation>.
+	</para>
+
+	<para id="x_251">Configuration information for this hook lives in the
+	  <literal role="rc-bugzilla">bugzilla</literal> section of
+	  your <filename role="special">~/.hgrc</filename>.
+	</para>
+	<itemizedlist>
+	  <listitem><para id="x_252"><envar
+		role="rc-item-bugzilla">version</envar>: 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.</para>
+	  </listitem>
+	  <listitem><para id="x_253"><envar role="rc-item-bugzilla">host</envar>:
+	      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
+	      <literal role="hook">bugzilla</literal> hook on.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_254"><envar role="rc-item-bugzilla">user</envar>:
+	      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 <literal
+		role="hook">bugzilla</literal> hook on.  This user
+	      must be able to access and modify Bugzilla tables.  The
+	      default value of this item is <literal>bugs</literal>,
+	      which is the standard name of the Bugzilla user in a
+	      MySQL database.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_255"><envar
+		role="rc-item-bugzilla">password</envar>: 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 <filename
+		role="special">~/.hgrc</filename> file where you
+	      store this information.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_256"><envar role="rc-item-bugzilla">db</envar>:
+	      The name of the Bugzilla database on the MySQL server.
+	      The default value of this item is
+	      <literal>bugs</literal>, which is the standard name of
+	      the MySQL database where Bugzilla stores its data.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_257"><envar
+		role="rc-item-bugzilla">notify</envar>: 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 <filename
+		class="directory">/var/www/html/bugzilla</filename>:
+	    </para>
+	    <programlisting>cd /var/www/html/bugzilla &amp;&amp;
+	      ./processmail %s nobody@nowhere.com</programlisting>
+	  </listitem>
+	  <listitem><para id="x_258">  The Bugzilla
+	      <literal>processmail</literal> program expects to be
+	      given a bug ID (the hook replaces
+	      <quote><literal>%s</literal></quote> 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
+	      <literal>processmail</literal> on the server where
+	      Bugzilla is installed.
+	    </para>
+	  </listitem></itemizedlist>
+
+      </sect3>
+      <sect3>
+	<title>Mapping committer names to Bugzilla user names</title>
+
+	<para id="x_259">By default, the <literal
+	    role="hg-ext">bugzilla</literal> 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 <literal
+	    role="rc-usermap">usermap</literal> section.
+	</para>
+
+	<para id="x_25a">Each item in the <literal
+	    role="rc-usermap">usermap</literal> section contains an
+	  email address on the left, and a Bugzilla user name on the
+	  right.
+	</para>
+	<programlisting>[usermap]
+jane.user@example.com = jane</programlisting>
+	<para id="x_25b">You can either keep the <literal
+	    role="rc-usermap">usermap</literal> data in a normal
+	  <filename role="special">~/.hgrc</filename>, or tell the
+	  <literal role="hg-ext">bugzilla</literal> hook to read the
+	  information from an external <filename>usermap</filename>
+	  file.  In the latter case, you can store
+	  <filename>usermap</filename> data by itself in (for example)
+	  a user-modifiable repository.  This makes it possible to let
+	  your users maintain their own <envar
+	    role="rc-item-bugzilla">usermap</envar> entries.  The main
+	  <filename role="special">~/.hgrc</filename> file might look
+	  like this:
+	</para>
+	<programlisting># regular hgrc file refers to external usermap file
+[bugzilla]
+usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting>
+	<para id="x_25c">While the <filename>usermap</filename> file that it
+	  refers to might look like this:
+	</para>
+	<programlisting># bugzilla-usermap.conf - inside a hg repository
+[usermap] stephanie@example.com = steph</programlisting>
+
+      </sect3>
+      <sect3>
+	<title>Configuring the text that gets added to a bug</title>
+
+	<para id="x_25d">You can configure the text that this hook adds as a
+	  comment; you specify it in the form of a Mercurial template.
+	  Several <filename role="special">~/.hgrc</filename> entries
+	  (still in the <literal role="rc-bugzilla">bugzilla</literal>
+	  section) control this behavior.
+	</para>
+	<itemizedlist>
+	  <listitem><para id="x_25e"><literal>strip</literal>: 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 <filename
+		class="directory">/home/hg/repos</filename>, and you
+	      have a repository whose path is <filename
+		class="directory">/home/hg/repos/app/tests</filename>,
+	      then setting <literal>strip</literal> to
+	      <literal>4</literal> will give a partial path of
+	      <filename class="directory">app/tests</filename>.  The
+	      hook will make this partial path available when
+	      expanding a template, as <literal>webroot</literal>.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_25f"><literal>template</literal>: The text of the
+	      template to use.  In addition to the usual
+	      changeset-related variables, this template can use
+	      <literal>hgweb</literal> (the value of the
+	      <literal>hgweb</literal> configuration item above) and
+	      <literal>webroot</literal> (the path constructed using
+	      <literal>strip</literal> above).
+	    </para>
+	  </listitem></itemizedlist>
+
+	<para id="x_260">In addition, you can add a <envar
+	    role="rc-item-web">baseurl</envar> item to the <literal
+	    role="rc-web">web</literal> section of your <filename
+	    role="special">~/.hgrc</filename>.  The <literal
+	    role="hg-ext">bugzilla</literal> 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:
+	</para>
+	<programlisting>[web]
+baseurl = http://hg.domain.com/</programlisting>
+
+	<para id="x_261">Here is an example set of <literal
+	    role="hg-ext">bugzilla</literal> hook config information.
+	</para>
+
+	&ch10-bugzilla-config.lst;
+
+      </sect3>
+      <sect3>
+	<title>Testing and troubleshooting</title>
+
+	<para id="x_262">The most common problems with configuring the <literal
+	    role="hg-ext">bugzilla</literal> hook relate to running
+	  Bugzilla's <filename>processmail</filename> script and
+	  mapping committer names to user names.
+	</para>
+
+	<para id="x_263">Recall from <xref
+	    linkend="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</filename>
+	  script.  The <filename>processmail</filename> 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.
+	</para>
+
+	<para id="x_264">You can cause <filename>processmail</filename> to be run
+	  with the suitable user's identity using the
+	  <command>sudo</command> command.  Here is an example entry
+	  for a <filename>sudoers</filename> file.
+	</para>
+	<programlisting>hg_user = (httpd_user)
+NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting>
+	<para id="x_265">This allows the <literal>hg_user</literal> user to run a
+	  <filename>processmail-wrapper</filename> program under the
+	  identity of <literal>httpd_user</literal>.
+	</para>
+
+	<para id="x_266">This indirection through a wrapper script is necessary,
+	  because <filename>processmail</filename> 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</filename> file.  The contents of the
+	  wrapper script are simple:
+	</para>
+	<programlisting>#!/bin/sh
+cd `dirname $0` &amp;&amp; ./processmail "$1" nobody@example.com</programlisting>
+	<para id="x_267">It doesn't seem to matter what email address you pass to
+	  <filename>processmail</filename>.
+	</para>
+
+	<para id="x_268">If your <literal role="rc-usermap">usermap</literal> is
+	  not set up correctly, users will see an error message from
+	  the <literal role="hg-ext">bugzilla</literal> hook when they
+	  push changes to the server.  The error message will look
+	  like this:
+	</para>
+	<programlisting>cannot find bugzilla user id for john.q.public@example.com</programlisting>
+	<para id="x_269">What this means is that the committer's address,
+	  <literal>john.q.public@example.com</literal>, is not a valid
+	  Bugzilla user name, nor does it have an entry in your
+	  <literal role="rc-usermap">usermap</literal> that maps it to
+	  a valid Bugzilla user name.
+	</para>
+
+      </sect3>    </sect2>
+
+    <sect2>
+      <title><literal role="hg-ext">notify</literal>&emdash;send email
+	notifications</title>
+
+      <para id="x_26a">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 <literal
+	  role="hg-ext">notify</literal> hook lets you send out
+	notifications to a set of email addresses whenever changesets
+	arrive that those subscribers are interested in.
+      </para>
+
+      <para id="x_26b">As with the <literal role="hg-ext">bugzilla</literal>
+	hook, the <literal role="hg-ext">notify</literal> hook is
+	template-driven, so you can customise the contents of the
+	notification messages that it sends.
+      </para>
+
+      <para id="x_26c">By default, the <literal role="hg-ext">notify</literal>
+	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.
+      </para>
+
+      <sect3>
+	<title>Configuring the <literal role="hg-ext">notify</literal>
+	  hook</title>
+
+	<para id="x_26d">You can set up the <literal
+	    role="hg-ext">notify</literal> 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).
+	</para>
+	<programlisting>[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</programlisting>
+
+	<para id="x_26e">Configuration information for this hook lives in the
+	  <literal role="rc-notify">notify</literal> section of a
+	  <filename role="special">~/.hgrc</filename> file.
+	</para>
+	<itemizedlist>
+	  <listitem><para id="x_26f"><envar role="rc-item-notify">test</envar>:
+	      By default, this hook does not send out email at all;
+	      instead, it prints the message that it
+	      <emphasis>would</emphasis> send.  Set this item to
+	      <literal>false</literal> 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 <quote>broken</quote>
+	      notifications while you debug your configuration.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_270"><envar role="rc-item-notify">config</envar>:
+	      The path to a configuration file that contains
+	      subscription information.  This is kept separate from
+	      the main <filename role="special">~/.hgrc</filename> 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.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_271"><envar role="rc-item-notify">strip</envar>:
+	      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 <filename
+		class="directory">/home/hg/repos</filename>, and
+	      <literal role="hg-ext">notify</literal> is considering a
+	      repository named <filename
+		class="directory">/home/hg/repos/shared/test</filename>, 
+	      setting <envar role="rc-item-notify">strip</envar> to
+	      <literal>4</literal> will cause <literal
+		role="hg-ext">notify</literal> to trim the path it
+	      considers down to <filename
+		class="directory">shared/test</filename>, and it will
+	      match subscribers against that.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_272"><envar
+		role="rc-item-notify">template</envar>: The template
+	      text to use when sending messages.  This specifies both
+	      the contents of the message header and its body.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_273"><envar
+		role="rc-item-notify">maxdiff</envar>: 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
+	      <literal>0</literal> to omit diffs from notification
+	      emails.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_274"><envar
+		role="rc-item-notify">sources</envar>: A list of
+	      sources of changesets to consider.  This lets you limit
+	      <literal role="hg-ext">notify</literal> to only sending
+	      out email about changes that remote users pushed into
+	      this repository via a server, for example.  See 
+	      <xref linkend="sec:hook:sources"/> for the sources you
+	      can specify here.
+	    </para>
+	  </listitem></itemizedlist>
+
+	<para id="x_275">If you set the <envar role="rc-item-web">baseurl</envar>
+	  item in the <literal role="rc-web">web</literal> section,
+	  you can use it in a template; it will be available as
+	  <literal>webroot</literal>.
+	</para>
+
+	<para id="x_276">Here is an example set of <literal
+	    role="hg-ext">notify</literal> configuration information.
+	</para>
+
+	&ch10-notify-config.lst;
+
+	<para id="x_277">This will produce a message that looks like the
+	  following:
+	</para>
+
+	&ch10-notify-config-mail.lst;
+
+      </sect3>
+      <sect3>
+	<title>Testing and troubleshooting</title>
+
+	<para id="x_278">Do not forget that by default, the <literal
+		role="hg-ext">notify</literal> extension <emphasis>will not
+	  send any mail</emphasis> until you explicitly configure it to do so,
+	  by setting <envar role="rc-item-notify">test</envar> to
+	  <literal>false</literal>.  Until you do that, it simply
+	  prints the message it <emphasis>would</emphasis> send.
+	</para>
+
+      </sect3>
+    </sect2>
+  </sect1>
+  <sect1 id="sec:hook:ref">
+    <title>Information for writers of hooks</title>
+
+    <sect2>
+      <title>In-process hook execution</title>
+
+      <para id="x_279">An in-process hook is called with arguments of the
+	following form:
+      </para>
+      <programlisting>def myhook(ui, repo, **kwargs): pass</programlisting>
+      <para id="x_27a">The <literal>ui</literal> parameter is a <literal
+	  role="py-mod-mercurial.ui">ui</literal> object. The
+	<literal>repo</literal> parameter is a <literal
+	  role="py-mod-mercurial.localrepo">localrepository</literal>
+	object.  The names and values of the
+	<literal>**kwargs</literal> parameters depend on the hook
+	being invoked, with the following common features:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_27b">If a parameter is named
+	    <literal>node</literal> or <literal>parentN</literal>, it
+	    will contain a hexadecimal changeset ID. The empty string
+	    is used to represent <quote>null changeset ID</quote>
+	    instead of a string of zeroes.
+	  </para>
+	</listitem>
+	<listitem><para id="x_27c">If a parameter is named
+	    <literal>url</literal>, it will contain the URL of a
+	    remote repository, if that can be determined.
+	  </para>
+	</listitem>
+	<listitem><para id="x_27d">Boolean-valued parameters are represented as
+	    Python <literal>bool</literal> objects.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_27e">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.
+      </para>
+
+      <para id="x_27f">If a hook returns a boolean <quote>false</quote> value, it
+	is considered to have succeeded.  If it returns a boolean
+	<quote>true</quote> value or raises an exception, it is
+	considered to have failed.  A useful way to think of the
+	calling convention is <quote>tell me if you fail</quote>.
+      </para>
+
+      <para id="x_280">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 <literal>bin</literal> function.
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>External hook execution</title>
+
+      <para id="x_281">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).
+      </para>
+
+      <para id="x_282">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
+	<quote><literal>HG_</literal></quote>.  For example, if the
+	name of a parameter is <quote><literal>node</literal></quote>,
+	the name of the environment variable representing that
+	parameter will be <quote><literal>HG_NODE</literal></quote>.
+      </para>
+
+      <para id="x_283">A boolean parameter is represented as the string
+	<quote><literal>1</literal></quote> for <quote>true</quote>,
+	<quote><literal>0</literal></quote> for <quote>false</quote>.
+	If an environment variable is named <envar>HG_NODE</envar>,
+	<envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it
+	contains a changeset ID represented as a hexadecimal string.
+	The empty string is used to represent <quote>null changeset
+	  ID</quote> instead of a string of zeroes.  If an environment
+	variable is named <envar>HG_URL</envar>, it will contain the
+	URL of a remote repository, if that can be determined.
+      </para>
+
+      <para id="x_284">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.
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>Finding out where changesets come from</title>
+
+      <para id="x_285">A hook that involves the transfer of changesets between a
+	local repository and another may be able to find out
+	information about the <quote>far side</quote>.  Mercurial
+	knows <emphasis>how</emphasis> changes are being transferred,
+	and in many cases <emphasis>where</emphasis> they are being
+	transferred to or from.
+      </para>
+
+      <sect3 id="sec:hook:sources">
+	<title>Sources of changesets</title>
+
+	<para id="x_286">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
+	  <literal>source</literal>, or an environment variable named
+	  <envar>HG_SOURCE</envar>.
+	</para>
+
+	<itemizedlist>
+	  <listitem><para id="x_287"><literal>serve</literal>: Changesets are
+	      transferred to or from a remote repository over http or
+	      ssh.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_288"><literal>pull</literal>: Changesets are
+	      being transferred via a pull from one repository into
+	      another.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_289"><literal>push</literal>: Changesets are
+	      being transferred via a push from one repository into
+	      another.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_28a"><literal>bundle</literal>: Changesets are
+	      being transferred to or from a bundle.
+	    </para>
+	  </listitem></itemizedlist>
+      </sect3>
+
+      <sect3 id="sec:hook:url">
+	<title>Where changes are going&emdash;remote repository
+	  URLs</title>
+
+	<para id="x_28b">When possible, Mercurial will tell a hook the location
+	  of the <quote>far side</quote> of an activity that transfers
+	  changeset data between repositories.  This is provided by
+	  Mercurial in a Python parameter named
+	  <literal>url</literal>, or an environment variable named
+	  <envar>HG_URL</envar>.
+	</para>
+
+	<para id="x_28c">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:
+	</para>
+	<itemizedlist>
+	  <listitem><para id="x_28d"><literal>remote:ssh:1.2.3.4</literal>&emdash;remote 
+	      ssh client, at the IP address
+	      <literal>1.2.3.4</literal>.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_28e"><literal>remote:http:1.2.3.4</literal>&emdash;remote 
+	      http client, at the IP address
+	      <literal>1.2.3.4</literal>.  If the client is using SSL,
+	      this will be of the form
+	      <literal>remote:https:1.2.3.4</literal>.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_28f">Empty&emdash;no information could be
+	      discovered about the remote client.
+	    </para>
+	  </listitem></itemizedlist>
+      </sect3>
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Hook reference</title>
+
+    <sect2 id="sec:hook:changegroup">
+      <title><literal role="hook">changegroup</literal>&emdash;after
+	remote changesets added</title>
+
+      <para id="x_290">This hook is run after a group of pre-existing changesets
+	has been added to the repository, for example via a <command
+	  role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg
+	  unbundle</command>.  This hook is run once per operation
+	that added one or more changesets.  This is in contrast to the
+	<literal role="hook">incoming</literal> hook, which is run
+	once per changeset, regardless of whether the changesets
+	arrive in a group.
+      </para>
+
+      <para id="x_291">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.
+      </para>
+
+      <para id="x_292">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_293"><literal>node</literal>: A changeset ID.  The
+	    changeset ID of the first changeset in the group that was
+	    added.  All changesets between this and
+	    <literal role="tag">tip</literal>, inclusive, were added by a single
+	    <command role="hg-cmd">hg pull</command>, <command
+	      role="hg-cmd">hg push</command> or <command
+	      role="hg-cmd">hg unbundle</command>.
+	  </para>
+	</listitem>
+	<listitem><para id="x_294"><literal>source</literal>: A
+	    string.  The source of these changes.  See <xref
+	      linkend="sec:hook:sources"/> for details.
+	  </para>
+	</listitem>
+	<listitem><para id="x_295"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_296">See also: <literal
+	  role="hook">incoming</literal> (<xref
+	  linkend="sec:hook:incoming"/>), <literal
+	  role="hook">prechangegroup</literal> (<xref
+	  linkend="sec:hook:prechangegroup"/>), <literal
+	  role="hook">pretxnchangegroup</literal> (<xref
+	  linkend="sec:hook:pretxnchangegroup"/>)
+      </para>
+    </sect2>
+
+    <sect2 id="sec:hook:commit">
+      <title><literal role="hook">commit</literal>&emdash;after a new
+	changeset is created</title>
+
+      <para id="x_297">This hook is run after a new changeset has been created.
+      </para>
+
+      <para id="x_298">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_299"><literal>node</literal>: A changeset ID.  The
+	    changeset ID of the newly committed changeset.
+	  </para>
+	</listitem>
+	<listitem><para id="x_29a"><literal>parent1</literal>: A changeset ID.
+	    The changeset ID of the first parent of the newly
+	    committed changeset.
+	  </para>
+	</listitem>
+	<listitem><para id="x_29b"><literal>parent2</literal>: A changeset ID.
+	    The changeset ID of the second parent of the newly
+	    committed changeset.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_29c">See also: <literal
+	  role="hook">precommit</literal> (<xref
+	  linkend="sec:hook:precommit"/>), <literal
+	  role="hook">pretxncommit</literal> (<xref
+	  linkend="sec:hook:pretxncommit"/>)
+      </para>
+    </sect2>
+
+    <sect2 id="sec:hook:incoming">
+      <title><literal role="hook">incoming</literal>&emdash;after one
+	remote changeset is added</title>
+
+      <para id="x_29d">This hook is run after a pre-existing changeset has been
+	added to the repository, for example via a <command
+	  role="hg-cmd">hg push</command>.  If a group of changesets
+	was added in a single operation, this hook is called once for
+	each added changeset.
+      </para>
+
+      <para id="x_29e">You can use this hook for the same purposes as
+	the <literal role="hook">changegroup</literal> hook (<xref
+	  linkend="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.
+      </para>
+
+      <para id="x_29f">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2a0"><literal>node</literal>: A changeset ID.  The
+	    ID of the newly added changeset.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2a1"><literal>source</literal>: A
+	    string.  The source of these changes.  See <xref
+	      linkend="sec:hook:sources"/> for details.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2a2"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2a3">See also: <literal
+	  role="hook">changegroup</literal> (<xref
+	  linkend="sec:hook:changegroup"/>) <literal
+	  role="hook">prechangegroup</literal> (<xref
+	  linkend="sec:hook:prechangegroup"/>), <literal
+	  role="hook">pretxnchangegroup</literal> (<xref
+	  linkend="sec:hook:pretxnchangegroup"/>)
+      </para>
+    </sect2>
+
+    <sect2 id="sec:hook:outgoing">
+      <title><literal role="hook">outgoing</literal>&emdash;after
+	changesets are propagated</title>
+
+      <para id="x_2a4">This hook is run after a group of changesets has been
+	propagated out of this repository, for example by a <command
+	  role="hg-cmd">hg push</command> or <command role="hg-cmd">hg
+	  bundle</command> command.
+      </para>
+
+      <para id="x_2a5">One possible use for this hook is to notify administrators
+	that changes have been pulled.
+      </para>
+
+      <para id="x_2a6">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2a7"><literal>node</literal>: A changeset ID.  The
+	    changeset ID of the first changeset of the group that was
+	    sent.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2a8"><literal>source</literal>: A string.  The
+	    source of the of the operation (see <xref
+	      linkend="sec:hook:sources"/>).  If a remote
+	    client pulled changes from this repository,
+	    <literal>source</literal> will be
+	    <literal>serve</literal>.  If the client that obtained
+	    changes from this repository was local,
+	    <literal>source</literal> will be
+	    <literal>bundle</literal>, <literal>pull</literal>, or
+	    <literal>push</literal>, depending on the operation the
+	    client performed.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2a9"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2aa">See also: <literal
+	  role="hook">preoutgoing</literal> (<xref
+	  linkend="sec:hook:preoutgoing"/>)
+      </para>
+    </sect2>
+
+    <sect2 id="sec:hook:prechangegroup">
+      <title><literal
+	  role="hook">prechangegroup</literal>&emdash;before starting
+	to add remote changesets</title>
+
+      <para id="x_2ab">This controlling hook is run before Mercurial begins to
+	add a group of changesets from another repository.
+      </para>
+
+      <para id="x_2ac">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.
+      </para>
+
+      <para id="x_2ad">One use for this hook is to prevent external changes from
+	being added to a repository.  For example, you could use this
+	to <quote>freeze</quote> a server-hosted branch temporarily or
+	permanently so that users cannot push to it, while still
+	allowing a local administrator to modify the repository.
+      </para>
+
+      <para id="x_2ae">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2af"><literal>source</literal>: A string.  The
+	    source of these changes.  See <xref
+	      linkend="sec:hook:sources"/> for details.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2b0"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2b1">See also: <literal
+	  role="hook">changegroup</literal> (<xref
+	  linkend="sec:hook:changegroup"/>), <literal
+	  role="hook">incoming</literal> (<xref
+	  linkend="sec:hook:incoming"/>), <literal
+	  role="hook">pretxnchangegroup</literal> (<xref
+	  linkend="sec:hook:pretxnchangegroup"/>)
+      </para>
+    </sect2>
+
+    <sect2 id="sec:hook:precommit">
+      <title><literal role="hook">precommit</literal>&emdash;before
+	starting to commit a changeset</title>
+
+      <para id="x_2b2">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.
+      </para>
+
+      <para id="x_2b3">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.
+      </para>
+
+      <para id="x_2b4">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2b5"><literal>parent1</literal>: A changeset ID.
+	    The changeset ID of the first parent of the working
+	    directory.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2b6"><literal>parent2</literal>: A changeset ID.
+	    The changeset ID of the second parent of the working
+	    directory.
+	  </para>
+	</listitem></itemizedlist>
+      <para id="x_2b7">If the commit proceeds, the parents of the working
+	directory will become the parents of the new changeset.
+      </para>
+
+      <para id="x_2b8">See also: <literal role="hook">commit</literal>
+	(<xref linkend="sec:hook:commit"/>), <literal
+	  role="hook">pretxncommit</literal> (<xref
+	  linkend="sec:hook:pretxncommit"/>)
+      </para>
+    </sect2>
+
+    <sect2 id="sec:hook:preoutgoing">
+      <title><literal role="hook">preoutgoing</literal>&emdash;before
+	starting to propagate changesets</title>
+
+      <para id="x_2b9">This hook is invoked before Mercurial knows the identities
+	of the changesets to be transmitted.
+      </para>
+
+      <para id="x_2ba">One use for this hook is to prevent changes from being
+	transmitted to another repository.
+      </para>
+
+      <para id="x_2bb">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2bc"><literal>source</literal>: A
+	    string.  The source of the operation that is attempting to
+	    obtain changes from this repository (see <xref
+	      linkend="sec:hook:sources"/>).  See the documentation
+	    for the <literal>source</literal> parameter to the
+	    <literal role="hook">outgoing</literal> hook, in
+	    <xref linkend="sec:hook:outgoing"/>, for possible values
+	    of this parameter.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2bd"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2be">See also: <literal
+	  role="hook">outgoing</literal> (<xref
+	  linkend="sec:hook:outgoing"/>)
+      </para>
+    </sect2>
+
+    <sect2 id="sec:hook:pretag">
+      <title><literal role="hook">pretag</literal>&emdash;before
+	tagging a changeset</title>
+
+      <para id="x_2bf">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.
+      </para>
+
+      <para id="x_2c0">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2c1"><literal>local</literal>: A boolean.  Whether
+	    the tag is local to this repository instance (i.e. stored
+	    in <filename role="special">.hg/localtags</filename>) or
+	    managed by Mercurial (stored in <filename
+	      role="special">.hgtags</filename>).
+	  </para>
+	</listitem>
+	<listitem><para id="x_2c2"><literal>node</literal>: A changeset ID.  The
+	    ID of the changeset to be tagged.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2c3"><literal>tag</literal>: A string.  The name of
+	    the tag to be created.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2c4">If the tag to be created is
+	revision-controlled, the <literal
+	  role="hook">precommit</literal> and <literal
+	  role="hook">pretxncommit</literal> hooks (<xref
+	  linkend="sec:hook:commit"/> and <xref
+	  linkend="sec:hook:pretxncommit"/>) will also be run.
+      </para>
+
+      <para id="x_2c5">See also: <literal role="hook">tag</literal>
+	(<xref linkend="sec:hook:tag"/>)
+      </para>
+    </sect2>
+
+    <sect2 id="sec:hook:pretxnchangegroup">
+      <title><literal
+	  role="hook">pretxnchangegroup</literal>&emdash;before
+	completing addition of remote changesets</title>
+
+      <para id="x_2c6">This controlling hook is run before a
+	transaction&emdash;that manages the addition of a group of new
+	changesets from outside the repository&emdash;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.
+      </para>
+
+      <para id="x_2c7">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.
+      </para>
+
+      <para id="x_2c8">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.
+      </para>
+
+      <para id="x_2c9">This hook can be used to automatically vet a group of
+	changesets.  If the hook fails, all of the changesets are
+	<quote>rejected</quote> when the transaction rolls back.
+      </para>
+
+      <para id="x_2ca">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2cb"><literal>node</literal>: A changeset ID.  The
+	    changeset ID of the first changeset in the group that was
+	    added.  All changesets between this and
+	    <literal role="tag">tip</literal>,
+	    inclusive, were added by a single <command
+	      role="hg-cmd">hg pull</command>, <command
+	      role="hg-cmd">hg push</command> or <command
+	      role="hg-cmd">hg unbundle</command>.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2cc"><literal>source</literal>: A
+	    string.  The source of these changes.  See <xref
+	      linkend="sec:hook:sources"/> for details.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2cd"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2ce">See also: <literal
+	  role="hook">changegroup</literal> (<xref
+	  linkend="sec:hook:changegroup"/>), <literal
+	  role="hook">incoming</literal> (<xref
+	  linkend="sec:hook:incoming"/>), <literal
+	  role="hook">prechangegroup</literal> (<xref
+	  linkend="sec:hook:prechangegroup"/>)
+      </para>
+    </sect2>
+
+    <sect2 id="sec:hook:pretxncommit">
+      <title><literal role="hook">pretxncommit</literal>&emdash;before
+	completing commit of new changeset</title>
+
+      <para id="x_2cf">This controlling hook is run before a
+	transaction&emdash;that manages a new commit&emdash;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.
+      </para>
+
+      <para id="x_2d0">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.
+      </para>
+
+      <para id="x_2d1">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.
+      </para>
+
+      <para id="x_2d2">Parameters to this hook:</para>
+
+      <itemizedlist>
+	<listitem><para id="x_2d3"><literal>node</literal>: A changeset ID.  The
+	    changeset ID of the newly committed changeset.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2d4"><literal>parent1</literal>: A changeset ID.
+	    The changeset ID of the first parent of the newly
+	    committed changeset.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2d5"><literal>parent2</literal>: A changeset ID.
+	    The changeset ID of the second parent of the newly
+	    committed changeset.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2d6">See also: <literal
+	  role="hook">precommit</literal> (<xref
+	  linkend="sec:hook:precommit"/>)
+      </para>
+    </sect2>
+
+    <sect2 id="sec:hook:preupdate">
+      <title><literal role="hook">preupdate</literal>&emdash;before
+	updating or merging working directory</title>
+
+      <para id="x_2d7">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.
+      </para>
+
+      <para id="x_2d8">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2d9"><literal>parent1</literal>: 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.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2da"><literal>parent2</literal>: 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.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2db">See also: <literal role="hook">update</literal>
+	(<xref linkend="sec:hook:update"/>)</para>
+    </sect2>
+
+    <sect2 id="sec:hook:tag">
+      <title><literal role="hook">tag</literal>&emdash;after tagging a
+	changeset</title>
+
+      <para id="x_2dc">This hook is run after a tag has been created.
+      </para>
+
+      <para id="x_2dd">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2de"><literal>local</literal>: A boolean.  Whether
+	    the new tag is local to this repository instance (i.e.
+	    stored in <filename
+	      role="special">.hg/localtags</filename>) or managed by
+	    Mercurial (stored in <filename
+	      role="special">.hgtags</filename>).
+	  </para>
+	</listitem>
+	<listitem><para id="x_2df"><literal>node</literal>: A changeset ID.  The
+	    ID of the changeset that was tagged.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2e0"><literal>tag</literal>: A string.  The name of
+	    the tag that was created.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2e1">If the created tag is revision-controlled, the <literal
+	  role="hook">commit</literal> hook (section <xref
+	  linkend="sec:hook:commit"/>) is run before this hook.
+      </para>
+
+      <para id="x_2e2">See also: <literal role="hook">pretag</literal>
+	(<xref linkend="sec:hook:pretag"/>)
+      </para>
+    </sect2>
+
+    <sect2 id="sec:hook:update">
+      <title><literal role="hook">update</literal>&emdash;after
+	updating or merging working directory</title>
+
+      <para id="x_2e3">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> command fails to resolve conflicts
+	in a file), this hook communicates whether the update or merge
+	completed cleanly.
+      </para>
+
+      <itemizedlist>
+	<listitem><para id="x_2e4"><literal>error</literal>: A boolean.
+	    Indicates whether the update or merge completed
+	    successfully.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2e5"><literal>parent1</literal>: 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.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2e6"><literal>parent2</literal>: A changeset ID.
+	    Only set if the working directory was merged.  The ID of
+	    the revision that the working directory was merged with.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2e7">See also: <literal role="hook">preupdate</literal>
+	(<xref linkend="sec:hook:preupdate"/>)
+      </para>
+
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- a/en/ch10-template.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,685 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:template">
-  <?dbhtml filename="customizing-the-output-of-mercurial.html"?>
-  <title>Customizing the output of Mercurial</title>
-
-  <para id="x_578">Mercurial provides a powerful mechanism to let you control how
-    it displays information.  The mechanism is based on templates.
-    You can use templates to generate specific output for a single
-    command, or to customize the entire appearance of the built-in web
-    interface.</para>
-
-  <sect1 id="sec:style">
-    <title>Using precanned output styles</title>
-
-    <para id="x_579">Packaged with Mercurial are some output styles that you can
-      use immediately.  A style is simply a precanned template that
-      someone wrote and installed somewhere that Mercurial can
-      find.</para>
-
-    <para id="x_57a">Before we take a look at Mercurial's bundled styles, let's
-      review its normal output.</para>
-
-    &interaction.template.simple.normal;
-
-    <para id="x_57b">This is somewhat informative, but it takes up a lot of
-      space&emdash;five lines of output per changeset.  The
-      <literal>compact</literal> style reduces this to three lines,
-      presented in a sparse manner.</para>
-
-    &interaction.template.simple.compact;
-
-    <para id="x_57c">The <literal>changelog</literal> style hints at the
-      expressive power of Mercurial's templating engine.  This style
-      attempts to follow the GNU Project's changelog
-      guidelines<citation>web:changelog</citation>.</para>
-
-    &interaction.template.simple.changelog;
-
-    <para id="x_57d">You will not be shocked to learn that Mercurial's default
-      output style is named <literal>default</literal>.</para>
-
-    <sect2>
-      <title>Setting a default style</title>
-
-      <para id="x_57e">You can modify the output style that Mercurial will use
-	for every command by editing your <filename
-	  role="special">~/.hgrc</filename> file, naming the style
-	you would prefer to use.</para>
-
-      <programlisting>[ui]
-style = compact</programlisting>
-
-      <para id="x_57f">If you write a style of your own, you can use it by either
-	providing the path to your style file, or copying your style
-	file into a location where Mercurial can find it (typically
-	the <literal>templates</literal> subdirectory of your
-	Mercurial install directory).</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>Commands that support styles and templates</title>
-
-    <para id="x_580">All of Mercurial's
-      <quote><literal>log</literal>-like</quote> commands let you use
-      styles and templates: <command role="hg-cmd">hg
-	incoming</command>, <command role="hg-cmd">hg log</command>,
-      <command role="hg-cmd">hg outgoing</command>, and <command
-	role="hg-cmd">hg tip</command>.</para>
-
-    <para id="x_581">As I write this manual, these are so far the only commands
-      that support styles and templates.  Since these are the most
-      important commands that need customizable output, there has been
-      little pressure from the Mercurial user community to add style
-      and template support to other commands.</para>
-  </sect1>
-
-  <sect1>
-    <title>The basics of templating</title>
-
-    <para id="x_582">At its simplest, a Mercurial template is a piece of text.
-      Some of the text never changes, while other parts are
-      <emphasis>expanded</emphasis>, or replaced with new text, when
-      necessary.</para>
-
-    <para id="x_583">Before we continue, let's look again at a simple example of
-      Mercurial's normal output.</para>
-
-    &interaction.template.simple.normal;
-
-    <para id="x_584">Now, let's run the same command, but using a template to
-      change its output.</para>
-
-    &interaction.template.simple.simplest;
-
-    <para id="x_585">The example above illustrates the simplest possible
-      template; it's just a piece of static text, printed once for
-      each changeset.  The <option
-	role="hg-opt-log">--template</option> option to the <command
-	role="hg-cmd">hg log</command> command tells Mercurial to use
-      the given text as the template when printing each
-      changeset.</para>
-
-    <para id="x_586">Notice that the template string above ends with the text
-      <quote><literal>\n</literal></quote>.  This is an
-      <emphasis>escape sequence</emphasis>, telling Mercurial to print
-      a newline at the end of each template item.  If you omit this
-      newline, Mercurial will run each piece of output together.  See
-      <xref linkend="sec:template:escape"/> for more details
-      of escape sequences.</para>
-
-    <para id="x_587">A template that prints a fixed string of text all the time
-      isn't very useful; let's try something a bit more
-      complex.</para>
-
-    &interaction.template.simple.simplesub;
-
-    <para id="x_588">As you can see, the string
-      <quote><literal>{desc}</literal></quote> in the template has
-      been replaced in the output with the description of each
-      changeset.  Every time Mercurial finds text enclosed in curly
-      braces (<quote><literal>{</literal></quote> and
-      <quote><literal>}</literal></quote>), it will try to replace the
-      braces and text with the expansion of whatever is inside.  To
-      print a literal curly brace, you must escape it, as described in
-      <xref linkend="sec:template:escape"/>.</para>
-  </sect1>
-
-  <sect1 id="sec:template:keyword">
-    <title>Common template keywords</title>
-
-    <para id="x_589">You can start writing simple templates immediately using the
-      keywords below.</para>
-
-    <itemizedlist>
-      <listitem><para id="x_58a"><literal
-	    role="template-keyword">author</literal>: String.  The
-	  unmodified author of the changeset.</para>
-      </listitem>
-      <listitem><para id="x_58b"><literal
-	    role="template-keyword">branches</literal>: String.  The
-	  name of the branch on which the changeset was committed.
-	  Will be empty if the branch name was
-	  <literal>default</literal>.</para>
-      </listitem>
-      <listitem><para id="x_58c"><literal role="template-keyword">date</literal>:
-	  Date information.  The date when the changeset was
-	  committed.  This is <emphasis>not</emphasis> human-readable;
-	  you must pass it through a filter that will render it
-	  appropriately.  See <xref
-	    linkend="sec:template:filter"/> for more information
-	  on filters. The date is expressed as a pair of numbers.  The
-	  first number is a Unix UTC timestamp (seconds since January
-	  1, 1970); the second is the offset of the committer's
-	  timezone from UTC, in seconds.</para>
-      </listitem>
-      <listitem><para id="x_58d"><literal role="template-keyword">desc</literal>:
-	  String.  The text of the changeset description.</para>
-      </listitem>
-      <listitem><para id="x_58e"><literal
-	    role="template-keyword">files</literal>: List of strings.
-	  All files modified, added, or removed by this
-	  changeset.</para>
-      </listitem>
-      <listitem><para id="x_58f"><literal
-	    role="template-keyword">file_adds</literal>: List of
-	  strings.  Files added by this changeset.</para>
-      </listitem>
-      <listitem><para id="x_590"><literal
-	    role="template-keyword">file_dels</literal>: List of
-	  strings.  Files removed by this changeset.</para>
-      </listitem>
-      <listitem><para id="x_591"><literal role="template-keyword">node</literal>:
-	  String.  The changeset identification hash, as a
-	  40-character hexadecimal string.</para>
-      </listitem>
-      <listitem><para id="x_592"><literal
-	    role="template-keyword">parents</literal>: List of
-	  strings.  The parents of the changeset.</para>
-      </listitem>
-      <listitem><para id="x_593"><literal role="template-keyword">rev</literal>:
-	  Integer.  The repository-local changeset revision
-	  number.</para>
-      </listitem>
-      <listitem><para id="x_594"><literal role="template-keyword">tags</literal>:
-	  List of strings.  Any tags associated with the
-	  changeset.</para>
-      </listitem>
-    </itemizedlist>
-
-    <para id="x_595">A few simple experiments will show us what to expect when we
-      use these keywords; you can see the results below.</para>
-
-    &interaction.template.simple.keywords;
-
-    <para id="x_596">As we noted above, the date keyword does not produce
-      human-readable output, so we must treat it specially.  This
-      involves using a <emphasis>filter</emphasis>, about which more
-      in <xref linkend="sec:template:filter"/>.</para>
-
-    &interaction.template.simple.datekeyword;
-  </sect1>
-
-  <sect1 id="sec:template:escape">
-    <title>Escape sequences</title>
-
-    <para id="x_597">Mercurial's templating engine recognises the most commonly
-      used escape sequences in strings.  When it sees a backslash
-      (<quote><literal>\</literal></quote>) character, it looks at the
-      following character and substitutes the two characters with a
-      single replacement, as described below.</para>
-
-    <itemizedlist>
-      <listitem><para id="x_598"><literal>\</literal>:
-	  Backslash, <quote><literal>\</literal></quote>, ASCII
-	  134.</para>
-      </listitem>
-      <listitem><para id="x_599"><literal>\n</literal>: Newline,
-	  ASCII 12.</para>
-      </listitem>
-      <listitem><para id="x_59a"><literal>\r</literal>: Carriage
-	  return, ASCII 15.</para>
-      </listitem>
-      <listitem><para id="x_59b"><literal>\t</literal>: Tab, ASCII
-	  11.</para>
-      </listitem>
-      <listitem><para id="x_59c"><literal>\v</literal>: Vertical
-	  tab, ASCII 13.</para>
-      </listitem>
-      <listitem><para id="x_59d"><literal>\{</literal>: Open curly
-	  brace, <quote><literal>{</literal></quote>, ASCII
-	  173.</para>
-      </listitem>
-      <listitem><para id="x_59e"><literal>\}</literal>: Close curly
-	  brace, <quote><literal>}</literal></quote>, ASCII
-	  175.</para>
-      </listitem></itemizedlist>
-
-    <para id="x_59f">As indicated above, if you want the expansion of a template
-      to contain a literal <quote><literal>\</literal></quote>,
-      <quote><literal>{</literal></quote>, or
-      <quote><literal>{</literal></quote> character, you must escape
-      it.</para>
-  </sect1>
-
-  <sect1 id="sec:template:filter">
-    <title>Filtering keywords to change their results</title>
-
-    <para id="x_5a0">Some of the results of template expansion are not
-      immediately easy to use.  Mercurial lets you specify an optional
-      chain of <emphasis>filters</emphasis> to modify the result of
-      expanding a keyword.  You have already seen a common filter,
-      <literal role="template-kw-filt-date">isodate</literal>, in
-      action above, to make a date readable.</para>
-
-    <para id="x_5a1">Below is a list of the most commonly used filters that
-      Mercurial supports.  While some filters can be applied to any
-      text, others can only be used in specific circumstances.  The
-      name of each filter is followed first by an indication of where
-      it can be used, then a description of its effect.</para>
-
-    <itemizedlist>
-      <listitem><para id="x_5a2"><literal
-	    role="template-filter">addbreaks</literal>: Any text. Add
-	  an XHTML <quote><literal>&lt;br/&gt;</literal></quote> tag
-	  before the end of every line except the last.  For example,
-	  <quote><literal>foo\nbar</literal></quote> becomes
-	  <quote><literal>foo&lt;br/&gt;\nbar</literal></quote>.</para>
-      </listitem>
-      <listitem><para id="x_5a3"><literal
-	    role="template-kw-filt-date">age</literal>: <literal
-	    role="template-keyword">date</literal> keyword.  Render
-	  the age of the date, relative to the current time.  Yields a
-	  string like <quote><literal>10
-	      minutes</literal></quote>.</para>
-      </listitem>
-      <listitem><para id="x_5a4"><literal
-	    role="template-filter">basename</literal>: Any text, but
-	  most useful for the <literal
-	    role="template-keyword">files</literal> keyword and its
-	  relatives.  Treat the text as a path, and return the
-	  basename. For example,
-	  <quote><literal>foo/bar/baz</literal></quote> becomes
-	  <quote><literal>baz</literal></quote>.</para>
-      </listitem>
-      <listitem><para id="x_5a5"><literal
-	    role="template-kw-filt-date">date</literal>: <literal
-	    role="template-keyword">date</literal> keyword.  Render a
-	  date in a similar format to the Unix <literal
-	    role="template-keyword">date</literal> command, but with
-	  timezone included.  Yields a string like <quote><literal>Mon
-	      Sep 04 15:13:13 2006 -0700</literal></quote>.</para>
-      </listitem>
-      <listitem><para id="x_5a6"><literal
-	    role="template-kw-filt-author">domain</literal>: Any text,
-	  but most useful for the <literal
-	    role="template-keyword">author</literal> keyword.  Finds
-	  the first string that looks like an email address, and
-	  extract just the domain component.  For example,
-	  <quote><literal>Bryan O'Sullivan
-	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
-	  <quote><literal>serpentine.com</literal></quote>.</para>
-      </listitem>
-      <listitem><para id="x_5a7"><literal
-	    role="template-kw-filt-author">email</literal>: Any text,
-	  but most useful for the <literal
-	    role="template-keyword">author</literal> keyword.  Extract
-	  the first string that looks like an email address.  For
-	  example, <quote><literal>Bryan O'Sullivan
-	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
-	  <quote><literal>bos@serpentine.com</literal></quote>.</para>
-      </listitem>
-      <listitem><para id="x_5a8"><literal
-	    role="template-filter">escape</literal>: Any text.
-	  Replace the special XML/XHTML characters
-	  <quote><literal>&amp;</literal></quote>,
-	  <quote><literal>&lt;</literal></quote> and
-	  <quote><literal>&gt;</literal></quote> with XML
-	  entities.</para>
-      </listitem>
-      <listitem><para id="x_5a9"><literal
-	    role="template-filter">fill68</literal>: Any text.  Wrap
-	  the text to fit in 68 columns.  This is useful before you
-	  pass text through the <literal
-	    role="template-filter">tabindent</literal> filter, and
-	  still want it to fit in an 80-column fixed-font
-	  window.</para>
-      </listitem>
-      <listitem><para id="x_5aa"><literal
-	    role="template-filter">fill76</literal>: Any text.  Wrap
-	  the text to fit in 76 columns.</para>
-      </listitem>
-      <listitem><para id="x_5ab"><literal
-	    role="template-filter">firstline</literal>: Any text.
-	  Yield the first line of text, without any trailing
-	  newlines.</para>
-      </listitem>
-      <listitem><para id="x_5ac"><literal
-	    role="template-kw-filt-date">hgdate</literal>: <literal
-	    role="template-keyword">date</literal> keyword.  Render
-	  the date as a pair of readable numbers.  Yields a string
-	  like <quote><literal>1157407993
-	      25200</literal></quote>.</para>
-      </listitem>
-      <listitem><para id="x_5ad"><literal
-	    role="template-kw-filt-date">isodate</literal>: <literal
-	    role="template-keyword">date</literal> keyword.  Render
-	  the date as a text string in ISO 8601 format.  Yields a
-	  string like <quote><literal>2006-09-04 15:13:13
-	      -0700</literal></quote>.</para>
-      </listitem>
-      <listitem><para id="x_5ae"><literal
-	    role="template-filter">obfuscate</literal>: Any text, but
-	  most useful for the <literal
-	    role="template-keyword">author</literal> keyword.  Yield
-	  the input text rendered as a sequence of XML entities.  This
-	  helps to defeat some particularly stupid screen-scraping
-	  email harvesting spambots.</para>
-      </listitem>
-      <listitem><para id="x_5af"><literal
-	    role="template-kw-filt-author">person</literal>: Any text,
-	  but most useful for the <literal
-	    role="template-keyword">author</literal> keyword.  Yield
-	  the text before an email address. For example,
-	  <quote><literal>Bryan O'Sullivan
-	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
-	  <quote><literal>Bryan O'Sullivan</literal></quote>.</para>
-      </listitem>
-      <listitem><para id="x_5b0"><literal
-	    role="template-kw-filt-date">rfc822date</literal>:
-	  <literal role="template-keyword">date</literal> keyword.
-	  Render a date using the same format used in email headers.
-	  Yields a string like <quote><literal>Mon, 04 Sep 2006
-	      15:13:13 -0700</literal></quote>.</para>
-      </listitem>
-      <listitem><para id="x_5b1"><literal
-	    role="template-kw-filt-node">short</literal>: Changeset
-	  hash.  Yield the short form of a changeset hash, i.e. a
-	  12-character hexadecimal string.</para>
-      </listitem>
-      <listitem><para id="x_5b2"><literal
-	    role="template-kw-filt-date">shortdate</literal>: <literal
-	    role="template-keyword">date</literal> keyword.  Render
-	  the year, month, and day of the date.  Yields a string like
-	  <quote><literal>2006-09-04</literal></quote>.</para>
-      </listitem>
-      <listitem><para id="x_5b3"><literal role="template-filter">strip</literal>:
-	  Any text.  Strip all leading and trailing whitespace from
-	  the string.</para>
-      </listitem>
-      <listitem><para id="x_5b4"><literal
-	    role="template-filter">tabindent</literal>: Any text.
-	  Yield the text, with every line except the first starting
-	  with a tab character.</para>
-      </listitem>
-      <listitem><para id="x_5b5"><literal
-	    role="template-filter">urlescape</literal>: Any text.
-	  Escape all characters that are considered
-	  <quote>special</quote> by URL parsers.  For example,
-	  <literal>foo bar</literal> becomes
-	  <literal>foo%20bar</literal>.</para>
-      </listitem>
-      <listitem><para id="x_5b6"><literal
-	    role="template-kw-filt-author">user</literal>: Any text,
-	  but most useful for the <literal
-	    role="template-keyword">author</literal> keyword.  Return
-	  the <quote>user</quote> portion of an email address.  For
-	  example, <quote><literal>Bryan O'Sullivan
-	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
-	  <quote><literal>bos</literal></quote>.</para>
-      </listitem>
-    </itemizedlist>
-
-    &interaction.template.simple.manyfilters;
-
-    <note>
-      <para id="x_5b7">  If you try to apply a filter to a piece of data that it
-	cannot process, Mercurial will fail and print a Python
-	exception.  For example, trying to run the output of the
-	<literal role="template-keyword">desc</literal> keyword into
-	the <literal role="template-kw-filt-date">isodate</literal>
-	filter is not a good idea.</para>
-    </note>
-
-    <sect2>
-      <title>Combining filters</title>
-
-      <para id="x_5b8">It is easy to combine filters to yield output in the form
-	you would like.  The following chain of filters tidies up a
-	description, then makes sure that it fits cleanly into 68
-	columns, then indents it by a further 8 characters (at least
-	on Unix-like systems, where a tab is conventionally 8
-	characters wide).</para>
-
-      &interaction.template.simple.combine;
-
-      <para id="x_5b9">Note the use of <quote><literal>\t</literal></quote> (a
-	tab character) in the template to force the first line to be
-	indented; this is necessary since <literal
-	  role="template-keyword">tabindent</literal> indents all
-	lines <emphasis>except</emphasis> the first.</para>
-
-      <para id="x_5ba">Keep in mind that the order of filters in a chain is
-	significant.  The first filter is applied to the result of the
-	keyword; the second to the result of the first filter; and so
-	on.  For example, using <literal>fill68|tabindent</literal>
-	gives very different results from
-	<literal>tabindent|fill68</literal>.</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>From templates to styles</title>
-
-    <para id="x_5bb">A command line template provides a quick and simple way to
-      format some output.  Templates can become verbose, though, and
-      it's useful to be able to give a template a name.  A style file
-      is a template with a name, stored in a file.</para>
-
-    <para id="x_5bc">More than that, using a style file unlocks the power of
-      Mercurial's templating engine in ways that are not possible
-      using the command line <option
-	role="hg-opt-log">--template</option> option.</para>
-
-    <sect2>
-      <title>The simplest of style files</title>
-
-      <para id="x_5bd">Our simple style file contains just one line:</para>
-
-      &interaction.template.simple.rev;
-
-      <para id="x_5be">This tells Mercurial, <quote>if you're printing a
-	  changeset, use the text on the right as the
-	  template</quote>.</para>
-    </sect2>
-
-    <sect2>
-      <title>Style file syntax</title>
-
-      <para id="x_5bf">The syntax rules for a style file are simple.</para>
-
-      <itemizedlist>
-	<listitem><para id="x_5c0">The file is processed one line at a
-	    time.</para>
-	</listitem>
-	<listitem><para id="x_5c1">Leading and trailing white space are
-	    ignored.</para>
-	</listitem>
-	<listitem><para id="x_5c2">Empty lines are skipped.</para>
-	</listitem>
-	<listitem><para id="x_5c3">If a line starts with either of the characters
-	    <quote><literal>#</literal></quote> or
-	    <quote><literal>;</literal></quote>, the entire line is
-	    treated as a comment, and skipped as if empty.</para>
-	</listitem>
-	<listitem><para id="x_5c4">A line starts with a keyword.  This must start
-	    with an alphabetic character or underscore, and can
-	    subsequently contain any alphanumeric character or
-	    underscore.  (In regexp notation, a keyword must match
-	    <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)</para>
-	</listitem>
-	<listitem><para id="x_5c5">The next element must be an
-	    <quote><literal>=</literal></quote> character, which can
-	    be preceded or followed by an arbitrary amount of white
-	    space.</para>
-	</listitem>
-	<listitem><para id="x_5c6">If the rest of the line starts and ends with
-	    matching quote characters (either single or double quote),
-	    it is treated as a template body.</para>
-	</listitem>
-	<listitem><para id="x_5c7">If the rest of the line <emphasis>does
-	      not</emphasis> start with a quote character, it is
-	    treated as the name of a file; the contents of this file
-	    will be read and used as a template body.</para>
-	</listitem></itemizedlist>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>Style files by example</title>
-
-    <para id="x_5c8">To illustrate how to write a style file, we will construct a
-      few by example.  Rather than provide a complete style file and
-      walk through it, we'll mirror the usual process of developing a
-      style file by starting with something very simple, and walking
-      through a series of successively more complete examples.</para>
-
-    <sect2>
-      <title>Identifying mistakes in style files</title>
-
-      <para id="x_5c9">If Mercurial encounters a problem in a style file you are
-	working on, it prints a terse error message that, once you
-	figure out what it means, is actually quite useful.</para>
-
-&interaction.template.svnstyle.syntax.input;
-
-      <para id="x_5ca">Notice that <filename>broken.style</filename> attempts to
-	define a <literal>changeset</literal> keyword, but forgets to
-	give any content for it. When instructed to use this style
-	file, Mercurial promptly complains.</para>
-
-      &interaction.template.svnstyle.syntax.error;
-
-      <para id="x_5cb">This error message looks intimidating, but it is not too
-	hard to follow.</para>
-
-      <itemizedlist>
-	<listitem><para id="x_5cc">The first component is simply Mercurial's way
-	    of saying <quote>I am giving up</quote>.</para>
-	  <programlisting>___abort___: broken.style:1: parse error</programlisting>
-	</listitem>
-	<listitem><para id="x_5cd">Next comes the name of the style file that
-	    contains the error.</para>
-	  <programlisting>abort: ___broken.style___:1: parse error</programlisting>
-	</listitem>
-	<listitem><para id="x_5ce">Following the file name is the line number
-	    where the error was encountered.</para>
-	  <programlisting>abort: broken.style:___1___: parse error</programlisting>
-	</listitem>
-	<listitem><para id="x_5cf">Finally, a description of what went
-	    wrong.</para>
-	  <programlisting>abort: broken.style:1: ___parse error___</programlisting>
-	</listitem>
-	<listitem><para id="x_5d0">The description of the problem is not always
-	    clear (as in this case), but even when it is cryptic, it
-	    is almost always trivial to visually inspect the offending
-	    line in the style file and see what is wrong.</para>
-	</listitem>
-      </itemizedlist>
-    </sect2>
-
-    <sect2>
-      <title>Uniquely identifying a repository</title>
-
-      <para id="x_5d1">If you would like to be able to identify a Mercurial
-	repository <quote>fairly uniquely</quote> using a short string
-	as an identifier, you can use the first revision in the
-	repository.</para>
-
-      &interaction.template.svnstyle.id;
-
-      <para id="x_5d2">This is likely to be unique, and so it is
-	useful in many cases.  There are a few caveats.</para>
-      <itemizedlist>
-	<listitem><para id="x_5d3">It will not work in a completely empty
-	    repository, because such a repository does not have a
-	    revision zero.</para>
-	</listitem>
-	<listitem><para id="x_5d4">Neither will it work in the (extremely rare)
-	    case where a repository is a merge of two or more formerly
-	    independent repositories, and you still have those
-	    repositories around.</para>
-	</listitem></itemizedlist>
-      <para id="x_5d5">Here are some uses to which you could put this
-	identifier:</para>
-      <itemizedlist>
-	<listitem><para id="x_5d6">As a key into a table for a database that
-	    manages repositories on a server.</para>
-	</listitem>
-	<listitem><para id="x_5d7">As half of a {<emphasis>repository
-	      ID</emphasis>, <emphasis>revision ID</emphasis>} tuple.
-	    Save this information away when you run an automated build
-	    or other activity, so that you can <quote>replay</quote>
-	    the build later if necessary.</para>
-	</listitem>
-      </itemizedlist>
-    </sect2>
-
-    <sect2>
-      <title>Listing files on multiple lines</title>
-
-      <para id="x_714">Suppose we want to list the files changed by a changeset,
-	one per line, with a little indentation before each file
-	name.</para>
-
-      &interaction.ch10-multiline.go;
-    </sect2>
-
-    <sect2>
-      <title>Mimicking Subversion's output</title>
-
-      <para id="x_5d8">Let's try to emulate the default output format used by
-	another revision control tool, Subversion.</para>
-
-      &interaction.template.svnstyle.short;
-
-      <para id="x_5d9">Since Subversion's output style is fairly simple, it is
-	easy to copy-and-paste a hunk of its output into a file, and
-	replace the text produced above by Subversion with the
-	template values we'd like to see expanded.</para>
-
-      &interaction.template.svnstyle.template;
-
-      <para id="x_5da">There are a few small ways in which this template deviates
-	from the output produced by Subversion.</para>
-      <itemizedlist>
-	<listitem><para id="x_5db">Subversion prints a <quote>readable</quote>
-	    date (the <quote><literal>Wed, 27 Sep 2006</literal></quote> in the
-	    example output above) in parentheses.  Mercurial's
-	    templating engine does not provide a way to display a date
-	    in this format without also printing the time and time
-	    zone.</para>
-	</listitem>
-	<listitem><para id="x_5dc">We emulate Subversion's printing of
-	    <quote>separator</quote> lines full of
-	    <quote><literal>-</literal></quote> characters by ending
-	    the template with such a line. We use the templating
-	    engine's <literal role="template-keyword">header</literal>
-	    keyword to print a separator line as the first line of
-	    output (see below), thus achieving similar output to
-	    Subversion.</para>
-	</listitem>
-	<listitem><para id="x_5dd">Subversion's output includes a count in the
-	    header of the number of lines in the commit message.  We
-	    cannot replicate this in Mercurial; the templating engine
-	    does not currently provide a filter that counts the number
-	    of lines the template generates.</para>
-	</listitem></itemizedlist>
-      <para id="x_5de">It took me no more than a minute or two of work to replace
-	literal text from an example of Subversion's output with some
-	keywords and filters to give the template above.  The style
-	file simply refers to the template.</para>
-
-      &interaction.template.svnstyle.style;
-
-      <para id="x_5df">We could have included the text of the template file
-	directly in the style file by enclosing it in quotes and
-	replacing the newlines with
-	<quote><literal>\n</literal></quote> sequences, but it would
-	have made the style file too difficult to read.  Readability
-	is a good guide when you're trying to decide whether some text
-	belongs in a style file, or in a template file that the style
-	file points to.  If the style file will look too big or
-	cluttered if you insert a literal piece of text, drop it into
-	a template instead.</para>
-    </sect2>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- a/en/ch11-mq.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1368 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:mq">
-  <?dbhtml filename="managing-change-with-mercurial-queues.html"?>
-  <title>Managing change with Mercurial Queues</title>
-
-  <sect1 id="sec:mq:patch-mgmt">
-    <title>The patch management problem</title>
-
-    <para id="x_3ac">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.</para>
-
-    <para id="x_3ad">This is a simple case of the <quote>patch management</quote>
-      problem.  You have an <quote>upstream</quote> 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.</para>
-
-    <para id="x_3ae">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.</para>
-
-    <para id="x_3af">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.</para>
-
-    <para id="x_3b0">When you have few changes to maintain, it is easy to manage
-      a single patch using the standard <command>diff</command> and
-      <command>patch</command> programs (see <xref
-	linkend="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 <quote>chunks of
-	work,</quote> so that for example a single patch will contain
-      only one bug fix (the patch might modify several files, but it's
-      doing <quote>only one thing</quote>), 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.</para>
-
-    <para id="x_3b1">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.</para>
-
-    <para id="x_3b2">Fortunately, Mercurial includes a powerful extension,
-      Mercurial Queues (or simply <quote>MQ</quote>), that massively
-      simplifies the patch management problem.</para>
-
-  </sect1>
-  <sect1 id="sec:mq:history">
-    <title>The prehistory of Mercurial Queues</title>
-
-    <para id="x_3b3">During the late 1990s, several Linux kernel developers
-      started to maintain <quote>patch series</quote> that modified
-      the behavior of the Linux kernel.  Some of these series were
-      focused on stability, some on feature coverage, and others were
-      more speculative.</para>
-
-    <para id="x_3b4">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.</para>
-
-    <sect2 id="sec:mq:quilt">
-      <title>A patchwork quilt</title>
-
-      <para id="x_3b5">In early 2003, Andreas Gruenbacher and Martin Quinson
-	borrowed the approach of Andrew's scripts and published a tool
-	called <quote>patchwork quilt</quote>
-	<citation>web:quilt</citation>, or simply <quote>quilt</quote>
-	(see <citation>gruenbacher:2005</citation> for a paper
-	describing it).  Because quilt substantially automated patch
-	management, it rapidly gained a large following among open
-	source software developers.</para>
-
-      <para id="x_3b6">Quilt manages a <emphasis>stack of patches</emphasis> 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 <quote>refresh</quote> the
-	patch.</para>
-
-      <para id="x_3b7">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 <quote>tree
-	  with one patch applied</quote> to <quote>tree with two
-	  patches applied</quote>.</para>
-
-      <para id="x_3b8">You can <emphasis>change</emphasis> which patches are
-	applied to the tree.  If you <quote>pop</quote> 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 <quote>push</quote> a popped patch again, and the
-	directory tree will be restored to contain the modifications
-	in the patch.  Most importantly, you can run the
-	<quote>refresh</quote> 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.</para>
-
-      <para id="x_3b9">Quilt knows nothing about revision control tools, so it
-	works equally well on top of an unpacked tarball or a
-	Subversion working copy.</para>
-    </sect2>
-
-    <sect2 id="sec:mq:quilt-mq">
-      <title>From patchwork quilt to Mercurial Queues</title>
-
-      <para id="x_3ba">In mid-2005, Chris Mason took the features of quilt and
-	wrote an extension that he called Mercurial Queues, which
-	added quilt-like behavior to Mercurial.</para>
-
-      <para id="x_3bb">The key difference between quilt and MQ is that quilt
-	knows nothing about revision control systems, while MQ is
-	<emphasis>integrated</emphasis> into Mercurial.  Each patch
-	that you push is represented as a Mercurial changeset.  Pop a
-	patch, and the changeset goes away.</para>
-
-      <para id="x_3bc">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.</para>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>The huge advantage of MQ</title>
-
-    <para id="x_3bd">I cannot overstate the value that MQ offers through the
-      unification of patches and revision control.</para>
-
-    <para id="x_3be">A major reason that patches have persisted in the free
-      software and open source world&emdash;in spite of the
-      availability of increasingly capable revision control tools over
-      the years&emdash;is the <emphasis>agility</emphasis> they
-      offer.</para>
-
-    <para id="x_3bf">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&emdash;or worse,
-      misleading or destabilising&emdash;traces of your missteps and
-      errors in the permanent revision record.</para>
-
-    <para id="x_3c0">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&emdash;as many times as you need to, until you
-      have refined it into the form you desire.</para>
-
-    <para id="x_3c1">As an example, the integration of patches with revision
-      control makes understanding patches and debugging their
-      effects&emdash;and their interplay with the code they're based
-      on&emdash;<emphasis>enormously</emphasis> easier. Since every
-      applied patch has an associated changeset, you can give <command
-	role="hg-cmd">hg log</command> a file name to see which
-      changesets and patches affected the file.  You can use the
-      <command role="hg-cmd">hg bisect</command> command to
-      binary-search through all changesets and applied patches to see
-      where a bug got introduced or fixed.  You can use the <command
-	role="hg-cmd">hg annotate</command> command to see which
-      changeset or patch modified a particular line of a source file.
-      And so on.</para>
-  </sect1>
-
-  <sect1 id="sec:mq:patch">
-    <title>Understanding patches</title>
-
-    <para id="x_3c2">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.</para>
-
-    <para id="x_3c3">The traditional Unix <command>diff</command> command
-      compares two files, and prints a list of differences between
-      them. The <command>patch</command> command understands these
-      differences as <emphasis>modifications</emphasis> to make to a
-      file.  Take a look below for a simple example of these commands
-      in action.</para>
-
-      &interaction.mq.dodiff.diff;
-
-    <para id="x_3c4">The type of file that <command>diff</command> generates (and
-      <command>patch</command> takes as input) is called a
-      <quote>patch</quote> or a <quote>diff</quote>; there is no
-      difference between a patch and a diff.  (We'll use the term
-      <quote>patch</quote>, since it's more commonly used.)</para>
-
-    <para id="x_3c5">A patch file can start with arbitrary text; the
-      <command>patch</command> 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</command>
-      searches for the first line that starts with the string
-      <quote><literal>diff -</literal></quote>.</para>
-
-    <para id="x_3c6">MQ works with <emphasis>unified</emphasis> diffs
-      (<command>patch</command> can accept several other diff formats,
-      but MQ doesn't).  A unified diff contains two kinds of header.
-      The <emphasis>file header</emphasis> describes the file being
-      modified; it contains the name of the file to modify.  When
-      <command>patch</command> sees a new file header, it looks for a
-      file with that name to start modifying.</para>
-
-    <para id="x_3c7">After the file header comes a series of
-      <emphasis>hunks</emphasis>.  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
-      <emphasis>context</emphasis> for the hunk.  If there's only a
-      small amount of context between successive hunks,
-      <command>diff</command> doesn't print a new hunk header; it just
-      runs the hunks together, with a few lines of context between
-      modifications.</para>
-
-    <para id="x_3c8">Each line of context begins with a space character.  Within
-      the hunk, a line that begins with
-      <quote><literal>-</literal></quote> means <quote>remove this
-	line,</quote> while a line that begins with
-      <quote><literal>+</literal></quote> means <quote>insert this
-	line.</quote>  For example, a line that is modified is
-      represented by one deletion and one insertion.</para>
-
-    <para id="x_3c9">We will return to some of the more subtle aspects of patches
-      later (in <xref linkend="sec:mq:adv-patch"/>), but you
-      should have
-      enough information now to use MQ.</para>
-  </sect1>
-
-  <sect1 id="sec:mq:start">
-    <title>Getting started with Mercurial Queues</title>
-
-    <para id="x_3ca">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 <filename
-	role="home">~/.hgrc</filename> file, and add the lines
-      below.</para>
-
-    <programlisting>[extensions]
-hgext.mq =</programlisting>
-
-    <para id="x_3cb">Once the extension is enabled, it will make a number of new
-      commands available.  To verify that the extension is working,
-      you can use <command role="hg-cmd">hg help</command> to see if
-      the <command role="hg-ext-mq">qinit</command> command is now
-      available.</para>
-
-    &interaction.mq.qinit-help.help;
-
-    <para id="x_3cc">You can use MQ with <emphasis>any</emphasis> Mercurial
-      repository, and its commands only operate within that
-      repository.  To get started, simply prepare the repository using
-      the <command role="hg-ext-mq">qinit</command> command.</para>
-
-    &interaction.mq.tutorial.qinit;
-
-    <para id="x_3cd">This command creates an empty directory called <filename
-	role="special" class="directory">.hg/patches</filename>, where
-      MQ will keep its metadata.  As with many Mercurial commands, the
-      <command role="hg-ext-mq">qinit</command> command prints nothing
-      if it succeeds.</para>
-
-    <sect2>
-      <title>Creating a new patch</title>
-
-      <para id="x_3ce">To begin work on a new patch, use the <command
-	  role="hg-ext-mq">qnew</command> command.  This command takes
-	one argument, the name of the patch to create.</para>
-
-      <para id="x_3cf">MQ will use this as the name of an actual file in the
-	<filename role="special"
-	  class="directory">.hg/patches</filename> directory, as you
-	can see below.</para>
-
-      &interaction.mq.tutorial.qnew;
-
-      <para id="x_3d0">Also newly present in the <filename role="special"
-	  class="directory">.hg/patches</filename> directory are two
-	other files, <filename role="special">series</filename> and
-	<filename role="special">status</filename>.  The <filename
-	  role="special">series</filename> file lists all of the
-	patches that MQ knows about for this repository, with one
-	patch per line.  Mercurial uses the <filename
-	  role="special">status</filename> file for internal
-	book-keeping; it tracks all of the patches that MQ has
-	<emphasis>applied</emphasis> in this repository.</para>
-
-      <note>
-	<para id="x_3d1">  You may sometimes want to edit the <filename
-	    role="special">series</filename> file by hand; for
-	  example, to change the sequence in which some patches are
-	  applied.  However, manually editing the <filename
-	    role="special">status</filename> file is almost always a
-	  bad idea, as it's easy to corrupt MQ's idea of what is
-	  happening.</para>
-      </note>
-
-      <para id="x_3d2">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 <command role="hg-cmd">hg
-	  diff</command> and <command role="hg-cmd">hg
-	  annotate</command>, work exactly as they did before.</para>
-    </sect2>
-
-    <sect2>
-      <title>Refreshing a patch</title>
-
-      <para id="x_3d3">When you reach a point where you want to save your work,
-	use the <command role="hg-ext-mq">qrefresh</command> command
-	to update the patch you are working on.</para>
-
-      &interaction.mq.tutorial.qrefresh;
-
-      <para id="x_3d4">This command folds the changes you have made in the
-	working directory into your patch, and updates its
-	corresponding changeset to contain those changes.</para>
-
-      <para id="x_3d5">You can run <command role="hg-ext-mq">qrefresh</command>
-	as often as you like, so it's a good way to
-	<quote>checkpoint</quote> your work.  Refresh your patch at an
-	opportune time; try an experiment; and if the experiment
-	doesn't work out, <command role="hg-cmd">hg revert</command>
-	your modifications back to the last time you refreshed.</para>
-
-      &interaction.mq.tutorial.qrefresh2;
-    </sect2>
-
-    <sect2>
-      <title>Stacking and tracking patches</title>
-
-      <para id="x_3d6">Once you have finished working on a patch, or need to work
-	on another, you can use the <command
-	  role="hg-ext-mq">qnew</command> command again to create a
-	new patch. Mercurial will apply this patch on top of your
-	existing patch.</para>
-
-      &interaction.mq.tutorial.qnew2;
-
-      <para id="x_3d7">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 <command role="hg-cmd">hg
-	  annotate</command>).</para>
-
-      <para id="x_3d8">So far, with the exception of <command
-	  role="hg-ext-mq">qnew</command> and <command
-	  role="hg-ext-mq">qrefresh</command>, 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 below.</para>
-
-      &interaction.mq.tutorial.qseries;
-
-      <itemizedlist>
-	<listitem><para id="x_3d9">The <command
-	      role="hg-ext-mq">qseries</command> command lists every
-	    patch that MQ knows about in this repository, from oldest
-	    to newest (most recently
-	    <emphasis>created</emphasis>).</para>
-	</listitem>
-	<listitem><para id="x_3da">The <command
-	      role="hg-ext-mq">qapplied</command> command lists every
-	    patch that MQ has <emphasis>applied</emphasis> in this
-	    repository, again from oldest to newest (most recently
-	    applied).</para>
-	</listitem></itemizedlist>
-    </sect2>
-
-    <sect2>
-      <title>Manipulating the patch stack</title>
-
-      <para id="x_3db">The previous discussion implied that there must be a
-	difference between <quote>known</quote> and
-	<quote>applied</quote> patches, and there is.  MQ can manage a
-	patch without it being applied in the repository.</para>
-
-      <para id="x_3dc">An <emphasis>applied</emphasis> 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 <command
-	  role="hg-ext-mq">qpop</command> command.  MQ still
-	<emphasis>knows about</emphasis>, 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.  <xref
-	  linkend="fig:mq:stack"/> illustrates
-	the difference between applied and tracked patches.</para>
-
-      <figure id="fig:mq:stack">
-	<title>Applied and unapplied patches in the MQ patch
-	  stack</title>
-	<mediaobject>
-	  <imageobject><imagedata fileref="figs/mq-stack.png"/></imageobject>
-	  <textobject><phrase>XXX add text</phrase></textobject>
-	</mediaobject>
-      </figure>
-
-      <para id="x_3de">You can reapply an unapplied, or popped, patch using the
-	<command role="hg-ext-mq">qpush</command> 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 below for examples of <command
-	  role="hg-ext-mq">qpop</command> and <command
-	  role="hg-ext-mq">qpush</command> in action.</para>
-
-      &interaction.mq.tutorial.qpop;
-
-      <para id="x_3df">Notice that once we have popped a patch or two patches,
-	the output of <command role="hg-ext-mq">qseries</command>
-	remains the same, while that of <command
-	  role="hg-ext-mq">qapplied</command> has changed.</para>
-
-    </sect2>
-
-    <sect2>
-      <title>Pushing and popping many patches</title>
-
-      <para id="x_3e0">While <command role="hg-ext-mq">qpush</command> and
-	<command role="hg-ext-mq">qpop</command> each operate on a
-	single patch at a time by default, you can push and pop many
-	patches in one go.  The <option
-	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to
-	<command role="hg-ext-mq">qpush</command> causes it to push
-	all unapplied patches, while the <option
-	  role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command
-	  role="hg-ext-mq">qpop</command> causes it to pop all applied
-	patches.  (For some more ways to push and pop many patches,
-	see <xref linkend="sec:mq:perf"/> below.)</para>
-
-      &interaction.mq.tutorial.qpush-a;
-    </sect2>
-
-    <sect2>
-      <title>Safety checks, and overriding them</title>
-
-      <para id="x_3e1">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.  The
-	example below illustrates this; the <command
-	  role="hg-ext-mq">qnew</command> command will not create a
-	new patch if there are outstanding changes, caused in this
-	case by the <command role="hg-cmd">hg add</command> of
-	<filename>file3</filename>.</para>
-
-      &interaction.mq.tutorial.add;
-
-      <para id="x_3e2">Commands that check the working directory all take an
-	<quote>I know what I'm doing</quote> option, which is always
-	named <option>-f</option>.  The exact meaning of
-	<option>-f</option> depends on the command.  For example,
-	<command role="hg-cmd">hg qnew <option
-	    role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command>
-	will incorporate any outstanding changes into the new patch it
-	creates, but <command role="hg-cmd">hg qpop <option
-	    role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command>
-	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> option before you use it!</para>
-    </sect2>
-
-    <sect2>
-      <title>Working on several patches at once</title>
-
-      <para id="x_3e3">The <command role="hg-ext-mq">qrefresh</command> command
-	always refreshes the <emphasis>topmost</emphasis> 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 <emphasis>that</emphasis> patch for a
-	while.</para>
-
-      <para id="x_3e4">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&emdash;layered on top of the
-	first&emdash;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 <command role="hg-ext-mq">qrefresh</command> the UI
-	patch to save your in-progress changes, and <command
-	  role="hg-ext-mq">qpop</command> down to the core patch.  Fix
-	the core bug, <command role="hg-ext-mq">qrefresh</command> the
-	core patch, and <command role="hg-ext-mq">qpush</command> back
-	to the UI patch to continue where you left off.</para>
-    </sect2>
-  </sect1>
-
-  <sect1 id="sec:mq:adv-patch">
-    <title>More about patches</title>
-
-    <para id="x_3e5">MQ uses the GNU <command>patch</command> command to apply
-      patches, so it's helpful to know a few more detailed aspects of
-      how <command>patch</command> works, and about patches
-      themselves.</para>
-
-    <sect2>
-      <title>The strip count</title>
-
-      <para id="x_3e6">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).</para>
-
-      <para id="x_3e7">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 <option
-	  role="cmd-opt-diff">-r</option> and <option
-	  role="cmd-opt-diff">-N</option> options to
-	<command>diff</command> 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.</para>
-
-      <para id="x_3e8">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>
-	command has a <option role="cmd-opt-patch">-p</option> option
-	that indicates the number of leading path name components to
-	strip when trying to apply a patch.  This number is called the
-	<emphasis>strip count</emphasis>.</para>
-
-      <para id="x_3e9">An option of <quote><literal>-p1</literal></quote> means
-	<quote>use a strip count of one</quote>.  If
-	<command>patch</command> sees a file name
-	<filename>foo/bar/baz</filename> in a file header, it will
-	strip <filename>foo</filename> and try to patch a file named
-	<filename>bar/baz</filename>.  (Strictly speaking, the strip
-	count refers to the number of <emphasis>path
-	  separators</emphasis> (and the components that go with them
-	) to strip.  A strip count of one will turn
-	<filename>foo/bar</filename> into <filename>bar</filename>,
-	but <filename>/foo/bar</filename> (notice the extra leading
-	slash) into <filename>foo/bar</filename>.)</para>
-
-      <para id="x_3ea">The <quote>standard</quote> strip count for patches is
-	one; almost all patches contain one leading path name
-	component that needs to be stripped. Mercurial's <command
-	  role="hg-cmd">hg diff</command> command generates path names
-	in this form, and the <command role="hg-cmd">hg
-	  import</command> command and MQ expect patches to have a
-	strip count of one.</para>
-
-      <para id="x_3eb">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 <command
-	  role="hg-ext-mq">qimport</command> the patch, because
-	<command role="hg-ext-mq">qimport</command> does not yet have
-	a <literal>-p</literal> option (see <ulink role="hg-bug"
-	  url="http://www.selenic.com/mercurial/bts/issue311">issue
-	  311</ulink>).  Your best bet is to <command
-	  role="hg-ext-mq">qnew</command> a patch of your own, then
-	use <command>patch -pN</command> to apply their patch,
-	followed by <command role="hg-cmd">hg addremove</command> to
-	pick up any files added or removed by the patch, followed by
-	<command role="hg-ext-mq">hg qrefresh</command>. This
-	complexity may become unnecessary; see <ulink role="hg-bug"
-	  url="http://www.selenic.com/mercurial/bts/issue311">issue
-	  311</ulink> for details.
-      </para>
-    </sect2>
-
-    <sect2>
-      <title>Strategies for applying a patch</title>
-
-      <para id="x_3ec">When <command>patch</command> 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.</para>
-
-      <para id="x_3ed">First, <command>patch</command> 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 <emphasis>offset</emphasis> from the
-	original line number.</para>
-
-      <para id="x_3ee">If a context-only match fails, <command>patch</command>
-	removes the first and last lines of the context, and tries a
-	<emphasis>reduced</emphasis> context-only match.  If the hunk
-	with reduced context succeeds, it prints a message saying that
-	it applied the hunk with a <emphasis>fuzz factor</emphasis>
-	(the number after the fuzz factor indicates how many lines of
-	context <command>patch</command> had to trim before the patch
-	applied).</para>
-
-      <para id="x_3ef">When neither of these techniques works,
-	<command>patch</command> prints a message saying that the hunk
-	in question was rejected.  It saves rejected hunks (also
-	simply called <quote>rejects</quote>) to a file with the same
-	name, and an added <filename role="special">.rej</filename>
-	extension.  It also saves an unmodified copy of the file with
-	a <filename role="special">.orig</filename> extension; the
-	copy of the file without any extensions will contain any
-	changes made by hunks that <emphasis>did</emphasis> apply
-	cleanly.  If you have a patch that modifies
-	<filename>foo</filename> with six hunks, and one of them fails
-	to apply, you will have: an unmodified
-	<filename>foo.orig</filename>, a <filename>foo.rej</filename>
-	containing one hunk, and <filename>foo</filename>, containing
-	the changes made by the five successful hunks.</para>
-    </sect2>
-
-    <sect2>
-      <title>Some quirks of patch representation</title>
-
-      <para id="x_3f0">There are a few useful things to know about how
-	<command>patch</command> works with files.</para>
-      <itemizedlist>
-	<listitem><para id="x_3f1">This should already be obvious, but
-	    <command>patch</command> cannot handle binary
-	    files.</para>
-	</listitem>
-	<listitem><para id="x_3f2">Neither does it care about the executable bit;
-	    it creates new files as readable, but not
-	    executable.</para>
-	</listitem>
-	<listitem><para id="x_3f3"><command>patch</command> treats the removal of
-	    a file as a diff between the file to be removed and the
-	    empty file.  So your idea of <quote>I deleted this
-	      file</quote> looks like <quote>every line of this file
-	      was deleted</quote> in a patch.</para>
-	</listitem>
-	<listitem><para id="x_3f4">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 <quote>I added this file</quote> looks
-	    like <quote>every line of this file was
-	      added</quote>.</para>
-	</listitem>
-	<listitem><para id="x_3f5">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.)</para>
-	</listitem>
-	<listitem><para id="x_3f6"><command>patch</command> cannot represent
-	    empty files, so you cannot use a patch to represent the
-	    notion <quote>I added this empty file to the
-	      tree</quote>.</para>
-	</listitem></itemizedlist>
-    </sect2>
-
-    <sect2>
-      <title>Beware the fuzz</title>
-
-      <para id="x_3f7">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</command> or <command
-	  role="hg-ext-mq">qpush</command> ever mentions an offset or
-	fuzz factor, you should make sure that the modified files are
-	correct afterwards.</para>
-
-      <para id="x_3f8">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 <quote>often,</quote> not <quote>always,</quote> 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.</para>
-    </sect2>
-
-    <sect2>
-      <title>Handling rejection</title>
-
-      <para id="x_3f9">If <command role="hg-ext-mq">qpush</command> fails to
-	apply a patch, it will print an error message and exit.  If it
-	has left <filename role="special">.rej</filename> files
-	behind, it is usually best to fix up the rejected hunks before
-	you push more patches or do any further work.</para>
-
-      <para id="x_3fa">If your patch <emphasis>used to</emphasis> apply cleanly,
-	and no longer does because you've changed the underlying code
-	that your patches are based on, Mercurial Queues can help; see
-	<xref linkend="sec:mq:merge"/> for details.</para>
-
-      <para id="x_3fb">Unfortunately, there aren't any great techniques for
-	dealing with rejected hunks.  Most often, you'll need to view
-	the <filename role="special">.rej</filename> file and edit the
-	target file, applying the rejected hunks by hand.</para>
-
-      <para id="x_3fd">A Linux kernel hacker, Chris Mason (the author
-	of Mercurial Queues), wrote a tool called
-	<command>mpatch</command> (<ulink
-	  url="http://oss.oracle.com/~mason/mpatch/">http://oss.oracle.com/~mason/mpatch/</ulink>), 
-	which takes a simple approach to automating the application of
-	hunks rejected by <command>patch</command>.  The
-	<command>mpatch</command> command can help with four common
-	reasons that a hunk may be rejected:</para>
-
-      <itemizedlist>
-	<listitem><para id="x_3fe">The context in the middle of a hunk has
-	    changed.</para>
-	</listitem>
-	<listitem><para id="x_3ff">A hunk is missing some context at the
-	    beginning or end.</para>
-	</listitem>
-	<listitem><para id="x_400">A large hunk might apply better&emdash;either
-	    entirely or in part&emdash;if it was broken up into
-	    smaller hunks.</para>
-	</listitem>
-	<listitem><para id="x_401">A hunk removes lines with slightly different
-	    content than those currently present in the file.</para>
-	</listitem></itemizedlist>
-
-      <para id="x_402">If you use <command>mpatch</command>, you
-	should be doubly careful to check your results when you're
-	done.  In fact, <command>mpatch</command> 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.</para>
-    </sect2>
-  </sect1>
-
-  <sect1>
-    <title>More on patch management</title>
-
-    <para id="x_6db">As you grow familiar with MQ, you will find yourself wanting
-      to perform other kinds of patch management operations.</para>
-
-    <sect2>
-      <title>Deleting unwanted patches</title>
-
-      <para id="x_6dc">If you want to get rid of a patch, use the <command
-	  role="hg-ext-mq">hg qdelete</command> command to delete the
-	patch file and remove its entry from the patch series.  If you
-	try to delete a patch that is still applied, <command
-	  role="hg-ext-mq">hg qdelete</command> will refuse.</para>
-
-      &interaction.ch11-qdelete.go;
-    </sect2>
-
-    <sect2>
-      <title>Converting to and from permanent revisions</title>
-
-      <para id="x_6dd">Once you're done working on a patch and want to
-      turn it into a permanent changeset, use the <command
-      role="hg-ext-mq">hg qfinish</command> command. Pass a revision
-      to the command to identify the patch that you want to turn into
-      a regular changeset; this patch must already be applied.</para>
-
-      &interaction.ch11-qdelete.convert;
-
-      <para id="x_6e0">The <command role="hg-ext-mq">hg qfinish</command> command
-        accepts an <option>--all</option> or <option>-a</option>
-        option, which turns all applied patches into regular
-        changesets.</para>
-
-      <para id="x_6de">It is also possible to turn an existing changeset into a
-	patch, by passing the <option>-r</option> option to <command
-	  role="hg-ext-mq">hg qimport</command>.</para>
-
-      &interaction.ch11-qdelete.import;
-
-      <para id="x_6df">Note that it only makes sense to convert a changeset into
-	a patch if you have not propagated that changeset into any
-	other repositories.  The imported changeset's ID will change
-	every time you refresh the patch, which will make Mercurial
-	treat it as unrelated to the original changeset if you have
-	pushed it somewhere else.</para>
-    </sect2>
-  </sect1>
-
-  <sect1 id="sec:mq:perf">
-    <title>Getting the best performance out of MQ</title>
-
-    <para id="x_403">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 (on modern
-      hardware, you should expect better performance than you'll see
-      below).  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.</para>
-
-    <para id="x_404">On my old, slow laptop, I was able to <command
-	role="hg-cmd">hg qpush <option
-	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all
-      1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop
-	<option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command>
-      them all in 30 seconds.  (On a newer laptop, the time to push
-      all patches dropped to two minutes.)  I could <command
-	role="hg-ext-mq">qrefresh</command> one of the biggest patches
-      (which made 22,779 lines of changes to 287 files) in 6.6
-      seconds.</para>
-
-    <para id="x_405">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.</para>
-
-    <para id="x_406">First of all, try to <quote>batch</quote> operations
-      together.  Every time you run <command
-	role="hg-ext-mq">qpush</command> or <command
-	role="hg-ext-mq">qpop</command>, these commands scan the
-      working directory once to make sure you haven't made some
-      changes and then forgotten to run <command
-	role="hg-ext-mq">qrefresh</command>.  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.</para>
-
-    <para id="x_407">The <command role="hg-ext-mq">qpush</command> and <command
-	role="hg-ext-mq">qpop</command> commands allow you to push and
-      pop multiple patches at a time.  You can identify the
-      <quote>destination patch</quote> that you want to end up at.
-      When you <command role="hg-ext-mq">qpush</command> with a
-      destination specified, it will push patches until that patch is
-      at the top of the applied stack.  When you <command
-	role="hg-ext-mq">qpop</command> to a destination, MQ will pop
-      patches until the destination patch is at the top.</para>
-
-    <para id="x_408">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.</para>
-  </sect1>
-
-  <sect1 id="sec:mq:merge">
-    <title>Updating your patches when the underlying code
-      changes</title>
-
-    <para id="x_409">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 <emphasis>rebasing</emphasis> your patch
-      series.</para>
-
-    <para id="x_40a">The simplest way to do this is to <command role="hg-cmd">hg
-	qpop <option role="hg-ext-mq-cmd-qpop-opt">hg
-	  -a</option></command> your patches, then <command
-	role="hg-cmd">hg pull</command> changes into the underlying
-      repository, and finally <command role="hg-cmd">hg qpush <option
-	  role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> 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, <command role="hg-ext-mq">qrefresh</command> the
-      affected patch, and continue pushing until you have fixed your
-      entire stack.</para>
-
-    <para id="x_40b">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.</para>
-
-    <para id="x_40c">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.</para>
-
-    <para id="x_40d">The process is a little involved.</para>
-    <orderedlist>
-      <listitem><para id="x_40e">To begin, <command role="hg-cmd">hg qpush
-	    -a</command> all of your patches on top of the revision
-	  where you know that they apply cleanly.</para>
-      </listitem>
-      <listitem><para id="x_40f">Save a backup copy of your patch directory using
-	  <command role="hg-cmd">hg qsave <option
-	      role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option
-	      role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>.
-	  This prints the name of the directory that it has saved the
-	  patches in.  It will save the patches to a directory called
-	  <filename role="special"
-	    class="directory">.hg/patches.N</filename>, where
-	  <literal>N</literal> is a small integer.  It also commits a
-	  <quote>save changeset</quote> on top of your applied
-	  patches; this is for internal book-keeping, and records the
-	  states of the <filename role="special">series</filename> and
-	  <filename role="special">status</filename> files.</para>
-      </listitem>
-      <listitem><para id="x_410">Use <command role="hg-cmd">hg pull</command> to
-	  bring new changes into the underlying repository.  (Don't
-	  run <command role="hg-cmd">hg pull -u</command>; see below
-	  for why.)</para>
-      </listitem>
-      <listitem><para id="x_411">Update to the new tip revision, using <command
-	    role="hg-cmd">hg update <option
-	      role="hg-opt-update">-C</option></command> to override
-	  the patches you have pushed.</para>
-      </listitem>
-      <listitem><para id="x_412">Merge all patches using <command>hg qpush -m
-	    -a</command>.  The <option
-	    role="hg-ext-mq-cmd-qpush-opt">-m</option> option to
-	  <command role="hg-ext-mq">qpush</command> tells MQ to
-	  perform a three-way merge if the patch fails to
-	  apply.</para>
-      </listitem></orderedlist>
-
-    <para id="x_413">During the <command role="hg-cmd">hg qpush <option
-	  role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>,
-      each patch in the <filename role="special">series</filename>
-      file is applied normally.  If a patch applies with fuzz or
-      rejects, MQ looks at the queue you <command
-	role="hg-ext-mq">qsave</command>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.</para>
-
-    <para id="x_414">When you finish resolving the effects of a patch, MQ
-      refreshes your patch based on the result of the merge.</para>
-
-    <para id="x_415">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 <filename role="special"
-	class="directory">.hg/patches.N</filename>. You can remove the
-      extra head using <command role="hg-cmd">hg qpop -a -n
-	patches.N</command> or <command role="hg-cmd">hg
-	strip</command>.  You can delete <filename role="special"
-	class="directory">.hg/patches.N</filename> once you are sure
-      that you no longer need it as a backup.</para>
-  </sect1>
-
-  <sect1>
-    <title>Identifying patches</title>
-
-    <para id="x_416">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</filename> to <command
-	role="hg-ext-mq">qpush</command>, for example, and it will
-      push patches until <filename>foo.patch</filename> is
-      applied.</para>
-
-    <para id="x_417">As a shortcut, you can refer to a patch using both a name
-      and a numeric offset; <literal>foo.patch-2</literal> means
-      <quote>two patches before <literal>foo.patch</literal></quote>,
-      while <literal>bar.patch+4</literal> means <quote>four patches
-	after <literal>bar.patch</literal></quote>.</para>
-
-    <para id="x_418">Referring to a patch by index isn't much different.  The
-      first patch printed in the output of <command
-	role="hg-ext-mq">qseries</command> is patch zero (yes, it's
-      one of those start-at-zero counting systems); the second is
-      patch one; and so on.</para>
-
-    <para id="x_419">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
-      <literal role="tag">qbase</literal> and
-      <literal role="tag">qtip</literal> identify
-      the <quote>bottom-most</quote> and topmost applied patches,
-      respectively.</para>
-
-    <para id="x_41a">These additions to Mercurial's normal tagging capabilities
-      make dealing with patches even more of a breeze.</para>
-    <itemizedlist>
-      <listitem><para id="x_41b">Want to patchbomb a mailing list with your
-	  latest series of changes?</para>
-	<programlisting>hg email qbase:qtip</programlisting>
-	<para id="x_41c">  (Don't know what <quote>patchbombing</quote> is?  See
-	  <xref linkend="sec:hgext:patchbomb"/>.)</para>
-      </listitem>
-      <listitem><para id="x_41d">Need to see all of the patches since
-	  <literal>foo.patch</literal> that have touched files in a
-	  subdirectory of your tree?</para>
-	<programlisting>hg log -r foo.patch:qtip subdir</programlisting>
-      </listitem>
-    </itemizedlist>
-
-    <para id="x_41e">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.</para>
-
-    <para id="x_41f">Another nice consequence of representing patch names as tags
-      is that when you run the <command role="hg-cmd">hg log</command>
-      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
-      <quote>normal</quote> revisions.  The following example shows a
-      few normal Mercurial commands in use with applied
-      patches.</para>
-
-    &interaction.mq.id.output;
-  </sect1>
-
-  <sect1>
-    <title>Useful things to know about</title>
-
-    <para id="x_420">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.</para>
-
-    <itemizedlist>
-      <listitem><para id="x_421">Normally, when you <command
-	    role="hg-ext-mq">qpop</command> a patch and <command
-	    role="hg-ext-mq">qpush</command> it again, the changeset
-	  that represents the patch after the pop/push will have a
-	  <emphasis>different identity</emphasis> than the changeset
-	  that represented the hash beforehand.  See <xref
-	    linkend="sec:mqref:cmd:qpush"/> for
-	  information as to why this is.</para>
-      </listitem>
-      <listitem><para id="x_422">It's not a good idea to <command
-	    role="hg-cmd">hg merge</command> changes from another
-	  branch with a patch changeset, at least if you want to
-	  maintain the <quote>patchiness</quote> 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.</para>
-      </listitem></itemizedlist>
-  </sect1>
-
-  <sect1 id="sec:mq:repo">
-    <title>Managing patches in a repository</title>
-
-    <para id="x_423">Because MQ's <filename role="special"
-	class="directory">.hg/patches</filename> directory resides
-      outside a Mercurial repository's working directory, the
-      <quote>underlying</quote> Mercurial repository knows nothing
-      about the management or presence of patches.</para>
-
-    <para id="x_424">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, <command
-	role="hg-ext-mq">qrefresh</command> it, then <command
-	role="hg-cmd">hg commit</command> the current state of the
-      patch.  This lets you <quote>roll back</quote> to that version
-      of the patch later on.</para>
-
-    <para id="x_425">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.</para>
-
-    <para id="x_426">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.</para>
-
-    <sect2>
-      <title>MQ support for patch repositories</title>
-
-      <para id="x_427">MQ helps you to work with the <filename role="special"
-	  class="directory">.hg/patches</filename> directory as a
-	repository; when you prepare a repository for working with
-	patches using <command role="hg-ext-mq">qinit</command>, you
-	can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg
-	  -c</option> option to create the <filename role="special"
-	  class="directory">.hg/patches</filename> directory as a
-	Mercurial repository.</para>
-
-      <note>
-	<para id="x_428">  If you forget to use the <option
-	    role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you
-	  can simply go into the <filename role="special"
-	    class="directory">.hg/patches</filename> directory at any
-	  time and run <command role="hg-cmd">hg init</command>.
-	  Don't forget to add an entry for the <filename
-	    role="special">status</filename> file to the <filename
-	    role="special">.hgignore</filename> file, though</para>
-
-	<para id="x_429">  (<command role="hg-cmd">hg qinit <option
-	      role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command>
-	  does this for you automatically); you
-	  <emphasis>really</emphasis> don't want to manage the
-	  <filename role="special">status</filename> file.</para>
-      </note>
-
-      <para id="x_42a">As a convenience, if MQ notices that the <filename
-	  class="directory">.hg/patches</filename> directory is a
-	repository, it will automatically <command role="hg-cmd">hg
-	  add</command> every patch that you create and import.</para>
-
-      <para id="x_42b">MQ provides a shortcut command, <command
-	  role="hg-ext-mq">qcommit</command>, that runs <command
-	  role="hg-cmd">hg commit</command> in the <filename
-	  role="special" class="directory">.hg/patches</filename>
-	directory.  This saves some bothersome typing.</para>
-
-      <para id="x_42c">Finally, as a convenience to manage the patch directory,
-	you can define the alias <command>mq</command> on Unix
-	systems. For example, on Linux systems using the
-	<command>bash</command> shell, you can include the following
-	snippet in your <filename
-	  role="home">~/.bashrc</filename>.</para>
-
-      <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting>
-
-      <para id="x_42d">You can then issue commands of the form <command>mq
-	  pull</command> from the main repository.</para>
-    </sect2>
-
-    <sect2>
-      <title>A few things to watch out for</title>
-
-      <para id="x_42e">MQ's support for working with a repository full of patches
-	is limited in a few small respects.</para>
-
-      <para id="x_42f">MQ cannot automatically detect changes that you make to
-	the patch directory.  If you <command role="hg-cmd">hg
-	  pull</command>, manually edit, or <command role="hg-cmd">hg
-	  update</command> changes to patches or the <filename
-	  role="special">series</filename> file, you will have to
-	<command role="hg-cmd">hg qpop <option
-	    role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and
-	then <command role="hg-cmd">hg qpush <option
-	    role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> 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.</para>
-
-    </sect2>
-  </sect1>
-  <sect1 id="sec:mq:tools">
-    <title>Third party tools for working with patches</title>
-
-    <para id="x_430">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.</para>
-
-    <para id="x_431">The <command>diffstat</command> command
-      <citation>web:diffstat</citation> generates a histogram of the
-      modifications made to each file in a patch.  It provides a good
-      way to <quote>get a sense of</quote> a patch&emdash;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</command>'s <option
-	role="cmd-opt-diffstat">-p</option> 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.)</para>
-
-&interaction.mq.tools.tools;
-
-    <para id="x_432">The <literal role="package">patchutils</literal> package
-      <citation>web:patchutils</citation> is invaluable. It provides a
-      set of small utilities that follow the <quote>Unix
-	philosophy;</quote> each does one useful thing with a patch.
-      The <literal role="package">patchutils</literal> command I use
-      most is <command>filterdiff</command>, 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</command> can generate a
-      smaller patch that only touches files whose names match a
-      particular glob pattern.  See <xref
-	linkend="mq-collab:tips:interdiff"/> for another
-      example.</para>
-
-  </sect1>
-  <sect1>
-    <title>Good ways to work with patches</title>
-
-    <para id="x_433">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
-      organized.</para>
-
-    <para id="x_434">Give your patches descriptive names.  A good name for a
-      patch might be <filename>rework-device-alloc.patch</filename>,
-      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 <emphasis>will</emphasis> be
-      running commands like <command
-	role="hg-ext-mq">qapplied</command> and <command
-	role="hg-ext-mq">qtop</command> 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.</para>
-
-    <para id="x_435">Be aware of what patch you're working on.  Use the <command
-	role="hg-ext-mq">qtop</command> command and skim over the text
-      of your patches frequently&emdash;for example, using <command
-	role="hg-cmd">hg tip <option
-	  role="hg-opt-tip">-p</option></command>)&emdash;to be sure
-      of where you stand.  I have several times worked on and <command
-	role="hg-ext-mq">qrefresh</command>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.</para>
-
-    <para id="x_436">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 <xref linkend="sec:mq:tools"/>,
-      particularly
-      <command>diffstat</command> and <command>filterdiff</command>.
-      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.</para>
-
-  </sect1>
-  <sect1>
-    <title>MQ cookbook</title>
-
-    <sect2>
-      <title>Manage <quote>trivial</quote> patches</title>
-
-      <para id="x_437">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.</para>
-
-      <para id="x_438">Begin by downloading and unpacking the source tarball, and
-	turning it into a Mercurial repository.</para>
-
-      &interaction.mq.tarball.download;
-
-      <para id="x_439">Continue by creating a patch stack and making your
-	changes.</para>
-
-      &interaction.mq.tarball.qinit;
-
-      <para id="x_43a">Let's say a few weeks or months pass, and your package
-	author releases a new version.  First, bring their changes
-	into the repository.</para>
-
-      &interaction.mq.tarball.newsource;
-
-      <para id="x_43b">The pipeline starting with <command role="hg-cmd">hg
-	  locate</command> above deletes all files in the working
-	directory, so that <command role="hg-cmd">hg
-	  commit</command>'s <option
-	  role="hg-opt-commit">--addremove</option> option can
-	actually tell which files have really been removed in the
-	newer version of the source.</para>
-
-      <para id="x_43c">Finally, you can apply your patches on top of the new
-	tree.</para>
-
-      &interaction.mq.tarball.repush;
-    </sect2>
-
-    <sect2 id="sec:mq:combine">
-      <title>Combining entire patches</title>
-
-      <para id="x_43d">MQ provides a command, <command
-	  role="hg-ext-mq">qfold</command> that lets you combine
-	entire patches.  This <quote>folds</quote> 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.</para>
-
-      <para id="x_43e">The order in which you fold patches matters.  If your
-	topmost applied patch is <literal>foo</literal>, and you
-	<command role="hg-ext-mq">qfold</command>
-	<literal>bar</literal> and <literal>quux</literal> into it,
-	you will end up with a patch that has the same effect as if
-	you applied first <literal>foo</literal>, then
-	<literal>bar</literal>, followed by
-	<literal>quux</literal>.</para>
-    </sect2>
-
-    <sect2>
-      <title>Merging part of one patch into another</title>
-
-      <para id="x_43f">Merging <emphasis>part</emphasis> of one patch into
-	another is more difficult than combining entire
-	patches.</para>
-
-      <para id="x_440">If you want to move changes to entire files, you can use
-	<command>filterdiff</command>'s <option
-	  role="cmd-opt-filterdiff">-i</option> and <option
-	  role="cmd-opt-filterdiff">-x</option> 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 <command role="hg-ext-mq">qpush</command> it (from
-	the hunks you moved into the other patch), and you can simply
-	<command role="hg-ext-mq">qrefresh</command> the patch to drop
-	the duplicate hunks.</para>
-
-      <para id="x_441">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
-	<command>lsdiff -nvv</command> to print some metadata about
-	the patch.</para>
-
-      &interaction.mq.tools.lsdiff;
-
-      <para id="x_442">This command prints three different kinds of
-	number:</para>
-      <itemizedlist>
-	<listitem><para id="x_443">(in the first column) a <emphasis>file
-	      number</emphasis> to identify each file modified in the
-	    patch;</para>
-	</listitem>
-	<listitem><para id="x_444">(on the next line, indented) the line number
-	    within a modified file where a hunk starts; and</para>
-	</listitem>
-	<listitem><para id="x_445">(on the same line) a <emphasis>hunk
-	      number</emphasis> to identify that hunk.</para>
-	</listitem></itemizedlist>
-
-      <para id="x_446">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</command>'s <option
-	  role="cmd-opt-filterdiff">--files</option> and <option
-	  role="cmd-opt-filterdiff">--hunks</option> options, to
-	select exactly the file and hunk you want to extract.</para>
-
-      <para id="x_447">Once you have this hunk, you can concatenate it onto the
-	end of your destination patch and continue with the remainder
-	of <xref linkend="sec:mq:combine"/>.</para>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Differences between quilt and MQ</title>
-
-    <para id="x_448">If you are already familiar with quilt, MQ provides a
-      similar command set.  There are a few differences in the way
-      that it works.</para>
-
-    <para id="x_449">You will already have noticed that most quilt commands have
-      MQ counterparts that simply begin with a
-      <quote><literal>q</literal></quote>.  The exceptions are quilt's
-      <literal>add</literal> and <literal>remove</literal> commands,
-      the counterparts for which are the normal Mercurial <command
-	role="hg-cmd">hg add</command> and <command role="hg-cmd">hg
-	remove</command> commands.  There is no MQ equivalent of the
-      quilt <literal>edit</literal> command.</para>
-
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch11-template.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,685 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:template">
+  <?dbhtml filename="customizing-the-output-of-mercurial.html"?>
+  <title>Customizing the output of Mercurial</title>
+
+  <para id="x_578">Mercurial provides a powerful mechanism to let you control how
+    it displays information.  The mechanism is based on templates.
+    You can use templates to generate specific output for a single
+    command, or to customize the entire appearance of the built-in web
+    interface.</para>
+
+  <sect1 id="sec:style">
+    <title>Using precanned output styles</title>
+
+    <para id="x_579">Packaged with Mercurial are some output styles that you can
+      use immediately.  A style is simply a precanned template that
+      someone wrote and installed somewhere that Mercurial can
+      find.</para>
+
+    <para id="x_57a">Before we take a look at Mercurial's bundled styles, let's
+      review its normal output.</para>
+
+    &interaction.template.simple.normal;
+
+    <para id="x_57b">This is somewhat informative, but it takes up a lot of
+      space&emdash;five lines of output per changeset.  The
+      <literal>compact</literal> style reduces this to three lines,
+      presented in a sparse manner.</para>
+
+    &interaction.template.simple.compact;
+
+    <para id="x_57c">The <literal>changelog</literal> style hints at the
+      expressive power of Mercurial's templating engine.  This style
+      attempts to follow the GNU Project's changelog
+      guidelines<citation>web:changelog</citation>.</para>
+
+    &interaction.template.simple.changelog;
+
+    <para id="x_57d">You will not be shocked to learn that Mercurial's default
+      output style is named <literal>default</literal>.</para>
+
+    <sect2>
+      <title>Setting a default style</title>
+
+      <para id="x_57e">You can modify the output style that Mercurial will use
+	for every command by editing your <filename
+	  role="special">~/.hgrc</filename> file, naming the style
+	you would prefer to use.</para>
+
+      <programlisting>[ui]
+style = compact</programlisting>
+
+      <para id="x_57f">If you write a style of your own, you can use it by either
+	providing the path to your style file, or copying your style
+	file into a location where Mercurial can find it (typically
+	the <literal>templates</literal> subdirectory of your
+	Mercurial install directory).</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Commands that support styles and templates</title>
+
+    <para id="x_580">All of Mercurial's
+      <quote><literal>log</literal>-like</quote> commands let you use
+      styles and templates: <command role="hg-cmd">hg
+	incoming</command>, <command role="hg-cmd">hg log</command>,
+      <command role="hg-cmd">hg outgoing</command>, and <command
+	role="hg-cmd">hg tip</command>.</para>
+
+    <para id="x_581">As I write this manual, these are so far the only commands
+      that support styles and templates.  Since these are the most
+      important commands that need customizable output, there has been
+      little pressure from the Mercurial user community to add style
+      and template support to other commands.</para>
+  </sect1>
+
+  <sect1>
+    <title>The basics of templating</title>
+
+    <para id="x_582">At its simplest, a Mercurial template is a piece of text.
+      Some of the text never changes, while other parts are
+      <emphasis>expanded</emphasis>, or replaced with new text, when
+      necessary.</para>
+
+    <para id="x_583">Before we continue, let's look again at a simple example of
+      Mercurial's normal output.</para>
+
+    &interaction.template.simple.normal;
+
+    <para id="x_584">Now, let's run the same command, but using a template to
+      change its output.</para>
+
+    &interaction.template.simple.simplest;
+
+    <para id="x_585">The example above illustrates the simplest possible
+      template; it's just a piece of static text, printed once for
+      each changeset.  The <option
+	role="hg-opt-log">--template</option> option to the <command
+	role="hg-cmd">hg log</command> command tells Mercurial to use
+      the given text as the template when printing each
+      changeset.</para>
+
+    <para id="x_586">Notice that the template string above ends with the text
+      <quote><literal>\n</literal></quote>.  This is an
+      <emphasis>escape sequence</emphasis>, telling Mercurial to print
+      a newline at the end of each template item.  If you omit this
+      newline, Mercurial will run each piece of output together.  See
+      <xref linkend="sec:template:escape"/> for more details
+      of escape sequences.</para>
+
+    <para id="x_587">A template that prints a fixed string of text all the time
+      isn't very useful; let's try something a bit more
+      complex.</para>
+
+    &interaction.template.simple.simplesub;
+
+    <para id="x_588">As you can see, the string
+      <quote><literal>{desc}</literal></quote> in the template has
+      been replaced in the output with the description of each
+      changeset.  Every time Mercurial finds text enclosed in curly
+      braces (<quote><literal>{</literal></quote> and
+      <quote><literal>}</literal></quote>), it will try to replace the
+      braces and text with the expansion of whatever is inside.  To
+      print a literal curly brace, you must escape it, as described in
+      <xref linkend="sec:template:escape"/>.</para>
+  </sect1>
+
+  <sect1 id="sec:template:keyword">
+    <title>Common template keywords</title>
+
+    <para id="x_589">You can start writing simple templates immediately using the
+      keywords below.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_58a"><literal
+	    role="template-keyword">author</literal>: String.  The
+	  unmodified author of the changeset.</para>
+      </listitem>
+      <listitem><para id="x_58b"><literal
+	    role="template-keyword">branches</literal>: String.  The
+	  name of the branch on which the changeset was committed.
+	  Will be empty if the branch name was
+	  <literal>default</literal>.</para>
+      </listitem>
+      <listitem><para id="x_58c"><literal role="template-keyword">date</literal>:
+	  Date information.  The date when the changeset was
+	  committed.  This is <emphasis>not</emphasis> human-readable;
+	  you must pass it through a filter that will render it
+	  appropriately.  See <xref
+	    linkend="sec:template:filter"/> for more information
+	  on filters. The date is expressed as a pair of numbers.  The
+	  first number is a Unix UTC timestamp (seconds since January
+	  1, 1970); the second is the offset of the committer's
+	  timezone from UTC, in seconds.</para>
+      </listitem>
+      <listitem><para id="x_58d"><literal role="template-keyword">desc</literal>:
+	  String.  The text of the changeset description.</para>
+      </listitem>
+      <listitem><para id="x_58e"><literal
+	    role="template-keyword">files</literal>: List of strings.
+	  All files modified, added, or removed by this
+	  changeset.</para>
+      </listitem>
+      <listitem><para id="x_58f"><literal
+	    role="template-keyword">file_adds</literal>: List of
+	  strings.  Files added by this changeset.</para>
+      </listitem>
+      <listitem><para id="x_590"><literal
+	    role="template-keyword">file_dels</literal>: List of
+	  strings.  Files removed by this changeset.</para>
+      </listitem>
+      <listitem><para id="x_591"><literal role="template-keyword">node</literal>:
+	  String.  The changeset identification hash, as a
+	  40-character hexadecimal string.</para>
+      </listitem>
+      <listitem><para id="x_592"><literal
+	    role="template-keyword">parents</literal>: List of
+	  strings.  The parents of the changeset.</para>
+      </listitem>
+      <listitem><para id="x_593"><literal role="template-keyword">rev</literal>:
+	  Integer.  The repository-local changeset revision
+	  number.</para>
+      </listitem>
+      <listitem><para id="x_594"><literal role="template-keyword">tags</literal>:
+	  List of strings.  Any tags associated with the
+	  changeset.</para>
+      </listitem>
+    </itemizedlist>
+
+    <para id="x_595">A few simple experiments will show us what to expect when we
+      use these keywords; you can see the results below.</para>
+
+    &interaction.template.simple.keywords;
+
+    <para id="x_596">As we noted above, the date keyword does not produce
+      human-readable output, so we must treat it specially.  This
+      involves using a <emphasis>filter</emphasis>, about which more
+      in <xref linkend="sec:template:filter"/>.</para>
+
+    &interaction.template.simple.datekeyword;
+  </sect1>
+
+  <sect1 id="sec:template:escape">
+    <title>Escape sequences</title>
+
+    <para id="x_597">Mercurial's templating engine recognises the most commonly
+      used escape sequences in strings.  When it sees a backslash
+      (<quote><literal>\</literal></quote>) character, it looks at the
+      following character and substitutes the two characters with a
+      single replacement, as described below.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_598"><literal>\</literal>:
+	  Backslash, <quote><literal>\</literal></quote>, ASCII
+	  134.</para>
+      </listitem>
+      <listitem><para id="x_599"><literal>\n</literal>: Newline,
+	  ASCII 12.</para>
+      </listitem>
+      <listitem><para id="x_59a"><literal>\r</literal>: Carriage
+	  return, ASCII 15.</para>
+      </listitem>
+      <listitem><para id="x_59b"><literal>\t</literal>: Tab, ASCII
+	  11.</para>
+      </listitem>
+      <listitem><para id="x_59c"><literal>\v</literal>: Vertical
+	  tab, ASCII 13.</para>
+      </listitem>
+      <listitem><para id="x_59d"><literal>\{</literal>: Open curly
+	  brace, <quote><literal>{</literal></quote>, ASCII
+	  173.</para>
+      </listitem>
+      <listitem><para id="x_59e"><literal>\}</literal>: Close curly
+	  brace, <quote><literal>}</literal></quote>, ASCII
+	  175.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_59f">As indicated above, if you want the expansion of a template
+      to contain a literal <quote><literal>\</literal></quote>,
+      <quote><literal>{</literal></quote>, or
+      <quote><literal>{</literal></quote> character, you must escape
+      it.</para>
+  </sect1>
+
+  <sect1 id="sec:template:filter">
+    <title>Filtering keywords to change their results</title>
+
+    <para id="x_5a0">Some of the results of template expansion are not
+      immediately easy to use.  Mercurial lets you specify an optional
+      chain of <emphasis>filters</emphasis> to modify the result of
+      expanding a keyword.  You have already seen a common filter,
+      <literal role="template-kw-filt-date">isodate</literal>, in
+      action above, to make a date readable.</para>
+
+    <para id="x_5a1">Below is a list of the most commonly used filters that
+      Mercurial supports.  While some filters can be applied to any
+      text, others can only be used in specific circumstances.  The
+      name of each filter is followed first by an indication of where
+      it can be used, then a description of its effect.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_5a2"><literal
+	    role="template-filter">addbreaks</literal>: Any text. Add
+	  an XHTML <quote><literal>&lt;br/&gt;</literal></quote> tag
+	  before the end of every line except the last.  For example,
+	  <quote><literal>foo\nbar</literal></quote> becomes
+	  <quote><literal>foo&lt;br/&gt;\nbar</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a3"><literal
+	    role="template-kw-filt-date">age</literal>: <literal
+	    role="template-keyword">date</literal> keyword.  Render
+	  the age of the date, relative to the current time.  Yields a
+	  string like <quote><literal>10
+	      minutes</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a4"><literal
+	    role="template-filter">basename</literal>: Any text, but
+	  most useful for the <literal
+	    role="template-keyword">files</literal> keyword and its
+	  relatives.  Treat the text as a path, and return the
+	  basename. For example,
+	  <quote><literal>foo/bar/baz</literal></quote> becomes
+	  <quote><literal>baz</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a5"><literal
+	    role="template-kw-filt-date">date</literal>: <literal
+	    role="template-keyword">date</literal> keyword.  Render a
+	  date in a similar format to the Unix <literal
+	    role="template-keyword">date</literal> command, but with
+	  timezone included.  Yields a string like <quote><literal>Mon
+	      Sep 04 15:13:13 2006 -0700</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a6"><literal
+	    role="template-kw-filt-author">domain</literal>: Any text,
+	  but most useful for the <literal
+	    role="template-keyword">author</literal> keyword.  Finds
+	  the first string that looks like an email address, and
+	  extract just the domain component.  For example,
+	  <quote><literal>Bryan O'Sullivan
+	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
+	  <quote><literal>serpentine.com</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a7"><literal
+	    role="template-kw-filt-author">email</literal>: Any text,
+	  but most useful for the <literal
+	    role="template-keyword">author</literal> keyword.  Extract
+	  the first string that looks like an email address.  For
+	  example, <quote><literal>Bryan O'Sullivan
+	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
+	  <quote><literal>bos@serpentine.com</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a8"><literal
+	    role="template-filter">escape</literal>: Any text.
+	  Replace the special XML/XHTML characters
+	  <quote><literal>&amp;</literal></quote>,
+	  <quote><literal>&lt;</literal></quote> and
+	  <quote><literal>&gt;</literal></quote> with XML
+	  entities.</para>
+      </listitem>
+      <listitem><para id="x_5a9"><literal
+	    role="template-filter">fill68</literal>: Any text.  Wrap
+	  the text to fit in 68 columns.  This is useful before you
+	  pass text through the <literal
+	    role="template-filter">tabindent</literal> filter, and
+	  still want it to fit in an 80-column fixed-font
+	  window.</para>
+      </listitem>
+      <listitem><para id="x_5aa"><literal
+	    role="template-filter">fill76</literal>: Any text.  Wrap
+	  the text to fit in 76 columns.</para>
+      </listitem>
+      <listitem><para id="x_5ab"><literal
+	    role="template-filter">firstline</literal>: Any text.
+	  Yield the first line of text, without any trailing
+	  newlines.</para>
+      </listitem>
+      <listitem><para id="x_5ac"><literal
+	    role="template-kw-filt-date">hgdate</literal>: <literal
+	    role="template-keyword">date</literal> keyword.  Render
+	  the date as a pair of readable numbers.  Yields a string
+	  like <quote><literal>1157407993
+	      25200</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5ad"><literal
+	    role="template-kw-filt-date">isodate</literal>: <literal
+	    role="template-keyword">date</literal> keyword.  Render
+	  the date as a text string in ISO 8601 format.  Yields a
+	  string like <quote><literal>2006-09-04 15:13:13
+	      -0700</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5ae"><literal
+	    role="template-filter">obfuscate</literal>: Any text, but
+	  most useful for the <literal
+	    role="template-keyword">author</literal> keyword.  Yield
+	  the input text rendered as a sequence of XML entities.  This
+	  helps to defeat some particularly stupid screen-scraping
+	  email harvesting spambots.</para>
+      </listitem>
+      <listitem><para id="x_5af"><literal
+	    role="template-kw-filt-author">person</literal>: Any text,
+	  but most useful for the <literal
+	    role="template-keyword">author</literal> keyword.  Yield
+	  the text before an email address. For example,
+	  <quote><literal>Bryan O'Sullivan
+	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
+	  <quote><literal>Bryan O'Sullivan</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5b0"><literal
+	    role="template-kw-filt-date">rfc822date</literal>:
+	  <literal role="template-keyword">date</literal> keyword.
+	  Render a date using the same format used in email headers.
+	  Yields a string like <quote><literal>Mon, 04 Sep 2006
+	      15:13:13 -0700</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5b1"><literal
+	    role="template-kw-filt-node">short</literal>: Changeset
+	  hash.  Yield the short form of a changeset hash, i.e. a
+	  12-character hexadecimal string.</para>
+      </listitem>
+      <listitem><para id="x_5b2"><literal
+	    role="template-kw-filt-date">shortdate</literal>: <literal
+	    role="template-keyword">date</literal> keyword.  Render
+	  the year, month, and day of the date.  Yields a string like
+	  <quote><literal>2006-09-04</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5b3"><literal role="template-filter">strip</literal>:
+	  Any text.  Strip all leading and trailing whitespace from
+	  the string.</para>
+      </listitem>
+      <listitem><para id="x_5b4"><literal
+	    role="template-filter">tabindent</literal>: Any text.
+	  Yield the text, with every line except the first starting
+	  with a tab character.</para>
+      </listitem>
+      <listitem><para id="x_5b5"><literal
+	    role="template-filter">urlescape</literal>: Any text.
+	  Escape all characters that are considered
+	  <quote>special</quote> by URL parsers.  For example,
+	  <literal>foo bar</literal> becomes
+	  <literal>foo%20bar</literal>.</para>
+      </listitem>
+      <listitem><para id="x_5b6"><literal
+	    role="template-kw-filt-author">user</literal>: Any text,
+	  but most useful for the <literal
+	    role="template-keyword">author</literal> keyword.  Return
+	  the <quote>user</quote> portion of an email address.  For
+	  example, <quote><literal>Bryan O'Sullivan
+	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
+	  <quote><literal>bos</literal></quote>.</para>
+      </listitem>
+    </itemizedlist>
+
+    &interaction.template.simple.manyfilters;
+
+    <note>
+      <para id="x_5b7">  If you try to apply a filter to a piece of data that it
+	cannot process, Mercurial will fail and print a Python
+	exception.  For example, trying to run the output of the
+	<literal role="template-keyword">desc</literal> keyword into
+	the <literal role="template-kw-filt-date">isodate</literal>
+	filter is not a good idea.</para>
+    </note>
+
+    <sect2>
+      <title>Combining filters</title>
+
+      <para id="x_5b8">It is easy to combine filters to yield output in the form
+	you would like.  The following chain of filters tidies up a
+	description, then makes sure that it fits cleanly into 68
+	columns, then indents it by a further 8 characters (at least
+	on Unix-like systems, where a tab is conventionally 8
+	characters wide).</para>
+
+      &interaction.template.simple.combine;
+
+      <para id="x_5b9">Note the use of <quote><literal>\t</literal></quote> (a
+	tab character) in the template to force the first line to be
+	indented; this is necessary since <literal
+	  role="template-keyword">tabindent</literal> indents all
+	lines <emphasis>except</emphasis> the first.</para>
+
+      <para id="x_5ba">Keep in mind that the order of filters in a chain is
+	significant.  The first filter is applied to the result of the
+	keyword; the second to the result of the first filter; and so
+	on.  For example, using <literal>fill68|tabindent</literal>
+	gives very different results from
+	<literal>tabindent|fill68</literal>.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>From templates to styles</title>
+
+    <para id="x_5bb">A command line template provides a quick and simple way to
+      format some output.  Templates can become verbose, though, and
+      it's useful to be able to give a template a name.  A style file
+      is a template with a name, stored in a file.</para>
+
+    <para id="x_5bc">More than that, using a style file unlocks the power of
+      Mercurial's templating engine in ways that are not possible
+      using the command line <option
+	role="hg-opt-log">--template</option> option.</para>
+
+    <sect2>
+      <title>The simplest of style files</title>
+
+      <para id="x_5bd">Our simple style file contains just one line:</para>
+
+      &interaction.template.simple.rev;
+
+      <para id="x_5be">This tells Mercurial, <quote>if you're printing a
+	  changeset, use the text on the right as the
+	  template</quote>.</para>
+    </sect2>
+
+    <sect2>
+      <title>Style file syntax</title>
+
+      <para id="x_5bf">The syntax rules for a style file are simple.</para>
+
+      <itemizedlist>
+	<listitem><para id="x_5c0">The file is processed one line at a
+	    time.</para>
+	</listitem>
+	<listitem><para id="x_5c1">Leading and trailing white space are
+	    ignored.</para>
+	</listitem>
+	<listitem><para id="x_5c2">Empty lines are skipped.</para>
+	</listitem>
+	<listitem><para id="x_5c3">If a line starts with either of the characters
+	    <quote><literal>#</literal></quote> or
+	    <quote><literal>;</literal></quote>, the entire line is
+	    treated as a comment, and skipped as if empty.</para>
+	</listitem>
+	<listitem><para id="x_5c4">A line starts with a keyword.  This must start
+	    with an alphabetic character or underscore, and can
+	    subsequently contain any alphanumeric character or
+	    underscore.  (In regexp notation, a keyword must match
+	    <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)</para>
+	</listitem>
+	<listitem><para id="x_5c5">The next element must be an
+	    <quote><literal>=</literal></quote> character, which can
+	    be preceded or followed by an arbitrary amount of white
+	    space.</para>
+	</listitem>
+	<listitem><para id="x_5c6">If the rest of the line starts and ends with
+	    matching quote characters (either single or double quote),
+	    it is treated as a template body.</para>
+	</listitem>
+	<listitem><para id="x_5c7">If the rest of the line <emphasis>does
+	      not</emphasis> start with a quote character, it is
+	    treated as the name of a file; the contents of this file
+	    will be read and used as a template body.</para>
+	</listitem></itemizedlist>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Style files by example</title>
+
+    <para id="x_5c8">To illustrate how to write a style file, we will construct a
+      few by example.  Rather than provide a complete style file and
+      walk through it, we'll mirror the usual process of developing a
+      style file by starting with something very simple, and walking
+      through a series of successively more complete examples.</para>
+
+    <sect2>
+      <title>Identifying mistakes in style files</title>
+
+      <para id="x_5c9">If Mercurial encounters a problem in a style file you are
+	working on, it prints a terse error message that, once you
+	figure out what it means, is actually quite useful.</para>
+
+&interaction.template.svnstyle.syntax.input;
+
+      <para id="x_5ca">Notice that <filename>broken.style</filename> attempts to
+	define a <literal>changeset</literal> keyword, but forgets to
+	give any content for it. When instructed to use this style
+	file, Mercurial promptly complains.</para>
+
+      &interaction.template.svnstyle.syntax.error;
+
+      <para id="x_5cb">This error message looks intimidating, but it is not too
+	hard to follow.</para>
+
+      <itemizedlist>
+	<listitem><para id="x_5cc">The first component is simply Mercurial's way
+	    of saying <quote>I am giving up</quote>.</para>
+	  <programlisting>___abort___: broken.style:1: parse error</programlisting>
+	</listitem>
+	<listitem><para id="x_5cd">Next comes the name of the style file that
+	    contains the error.</para>
+	  <programlisting>abort: ___broken.style___:1: parse error</programlisting>
+	</listitem>
+	<listitem><para id="x_5ce">Following the file name is the line number
+	    where the error was encountered.</para>
+	  <programlisting>abort: broken.style:___1___: parse error</programlisting>
+	</listitem>
+	<listitem><para id="x_5cf">Finally, a description of what went
+	    wrong.</para>
+	  <programlisting>abort: broken.style:1: ___parse error___</programlisting>
+	</listitem>
+	<listitem><para id="x_5d0">The description of the problem is not always
+	    clear (as in this case), but even when it is cryptic, it
+	    is almost always trivial to visually inspect the offending
+	    line in the style file and see what is wrong.</para>
+	</listitem>
+      </itemizedlist>
+    </sect2>
+
+    <sect2>
+      <title>Uniquely identifying a repository</title>
+
+      <para id="x_5d1">If you would like to be able to identify a Mercurial
+	repository <quote>fairly uniquely</quote> using a short string
+	as an identifier, you can use the first revision in the
+	repository.</para>
+
+      &interaction.template.svnstyle.id;
+
+      <para id="x_5d2">This is likely to be unique, and so it is
+	useful in many cases.  There are a few caveats.</para>
+      <itemizedlist>
+	<listitem><para id="x_5d3">It will not work in a completely empty
+	    repository, because such a repository does not have a
+	    revision zero.</para>
+	</listitem>
+	<listitem><para id="x_5d4">Neither will it work in the (extremely rare)
+	    case where a repository is a merge of two or more formerly
+	    independent repositories, and you still have those
+	    repositories around.</para>
+	</listitem></itemizedlist>
+      <para id="x_5d5">Here are some uses to which you could put this
+	identifier:</para>
+      <itemizedlist>
+	<listitem><para id="x_5d6">As a key into a table for a database that
+	    manages repositories on a server.</para>
+	</listitem>
+	<listitem><para id="x_5d7">As half of a {<emphasis>repository
+	      ID</emphasis>, <emphasis>revision ID</emphasis>} tuple.
+	    Save this information away when you run an automated build
+	    or other activity, so that you can <quote>replay</quote>
+	    the build later if necessary.</para>
+	</listitem>
+      </itemizedlist>
+    </sect2>
+
+    <sect2>
+      <title>Listing files on multiple lines</title>
+
+      <para id="x_714">Suppose we want to list the files changed by a changeset,
+	one per line, with a little indentation before each file
+	name.</para>
+
+      &interaction.ch10-multiline.go;
+    </sect2>
+
+    <sect2>
+      <title>Mimicking Subversion's output</title>
+
+      <para id="x_5d8">Let's try to emulate the default output format used by
+	another revision control tool, Subversion.</para>
+
+      &interaction.template.svnstyle.short;
+
+      <para id="x_5d9">Since Subversion's output style is fairly simple, it is
+	easy to copy-and-paste a hunk of its output into a file, and
+	replace the text produced above by Subversion with the
+	template values we'd like to see expanded.</para>
+
+      &interaction.template.svnstyle.template;
+
+      <para id="x_5da">There are a few small ways in which this template deviates
+	from the output produced by Subversion.</para>
+      <itemizedlist>
+	<listitem><para id="x_5db">Subversion prints a <quote>readable</quote>
+	    date (the <quote><literal>Wed, 27 Sep 2006</literal></quote> in the
+	    example output above) in parentheses.  Mercurial's
+	    templating engine does not provide a way to display a date
+	    in this format without also printing the time and time
+	    zone.</para>
+	</listitem>
+	<listitem><para id="x_5dc">We emulate Subversion's printing of
+	    <quote>separator</quote> lines full of
+	    <quote><literal>-</literal></quote> characters by ending
+	    the template with such a line. We use the templating
+	    engine's <literal role="template-keyword">header</literal>
+	    keyword to print a separator line as the first line of
+	    output (see below), thus achieving similar output to
+	    Subversion.</para>
+	</listitem>
+	<listitem><para id="x_5dd">Subversion's output includes a count in the
+	    header of the number of lines in the commit message.  We
+	    cannot replicate this in Mercurial; the templating engine
+	    does not currently provide a filter that counts the number
+	    of lines the template generates.</para>
+	</listitem></itemizedlist>
+      <para id="x_5de">It took me no more than a minute or two of work to replace
+	literal text from an example of Subversion's output with some
+	keywords and filters to give the template above.  The style
+	file simply refers to the template.</para>
+
+      &interaction.template.svnstyle.style;
+
+      <para id="x_5df">We could have included the text of the template file
+	directly in the style file by enclosing it in quotes and
+	replacing the newlines with
+	<quote><literal>\n</literal></quote> sequences, but it would
+	have made the style file too difficult to read.  Readability
+	is a good guide when you're trying to decide whether some text
+	belongs in a style file, or in a template file that the style
+	file points to.  If the style file will look too big or
+	cluttered if you insert a literal piece of text, drop it into
+	a template instead.</para>
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- a/en/ch12-mq-collab.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,518 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:mq-collab">
-  <?dbhtml filename="advanced-uses-of-mercurial-queues.html"?>
-  <title>Advanced uses of Mercurial Queues</title>
-
-  <para id="x_15d">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.</para>
-
-  <para id="x_15e">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.</para>
-
-  <para id="x_15f">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.</para>
-
-  <sect1>
-    <title>The problem of many targets</title>
-
-    <para id="x_160">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 <emphasis>compile</emphasis> correctly against,
-      typically, any other version.</para>
-
-    <para id="x_161">To maintain a driver, we have to keep a number of distinct
-      versions of Linux in mind.</para>
-    <itemizedlist>
-      <listitem><para id="x_162">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
-	  <quote>drive-by</quote> modifications to the driver as they
-	  develop and refine kernel subsystems.</para>
-      </listitem>
-      <listitem><para id="x_163">We also maintain a number of
-	  <quote>backports</quote> 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 <emphasis>backport</emphasis> 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.)</para>
-      </listitem>
-      <listitem><para id="x_164">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.</para>
-      </listitem></itemizedlist>
-
-    <sect2>
-      <title>Tempting approaches that don't work well</title>
-
-      <para id="x_165">There are two <quote>standard</quote> ways to maintain a
-	piece of software that has to target many different
-	environments.</para>
-
-      <para id="x_166">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 <quote>pristine</quote> 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.</para>
-
-      <para id="x_167">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
-	<quote>ifdefs</quote> 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.</para>
-
-      <para id="x_168">Neither of these approaches is well suited to a situation
-	where you don't <quote>own</quote> 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 <quote>my</quote> 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.</para>
-
-      <para id="x_169">These approaches have the added weakness of making it
-	difficult to generate well-formed patches to submit
-	upstream.</para>
-
-      <para id="x_16a">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.</para>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Conditionally applying patches with guards</title>
-
-    <para id="x_16b">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 <quote>guards</quote>
-      (which originates with quilt's <literal>guards</literal>
-      command) that does just this.  To start off, let's create a
-      simple repository for experimenting in.</para>
-
-    &interaction.mq.guards.init;
-
-    <para id="x_16c">This gives us a tiny repository that contains two patches
-      that don't have any dependencies on each other, because they
-      touch different files.</para>
-
-    <para id="x_16d">The idea behind conditional application is that you can
-      <quote>tag</quote> a patch with a <emphasis>guard</emphasis>,
-      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.</para>
-
-    <para id="x_16e">A patch can have an arbitrary number of guards; each one is
-      <emphasis>positive</emphasis> (<quote>apply this patch if this
-	guard is selected</quote>) or <emphasis>negative</emphasis>
-      (<quote>skip this patch if this guard is selected</quote>).  A
-      patch with no guards is always applied.</para>
-
-  </sect1>
-  <sect1>
-    <title>Controlling the guards on a patch</title>
-
-    <para id="x_16f">The <command role="hg-ext-mq">qguard</command> 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.</para>
-
-      &interaction.mq.guards.qguard;
-
-    <para id="x_170">To set a positive guard on a patch, prefix the name of the
-      guard with a <quote><literal>+</literal></quote>.</para>
-
-      &interaction.mq.guards.qguard.pos;
-
-    <para id="x_171">To set a negative guard
-      on a patch, prefix the name of the guard with a
-      <quote><literal>-</literal></quote>.</para>
-
-    &interaction.mq.guards.qguard.neg;
-
-    <note>
-      <para id="x_172">  The <command role="hg-ext-mq">qguard</command> command
-	<emphasis>sets</emphasis> the guards on a patch; it doesn't
-	<emphasis>modify</emphasis> them.  What this means is that if
-	you run <command role="hg-cmd">hg qguard +a +b</command> on a
-	patch, then <command role="hg-cmd">hg qguard +c</command> on
-	the same patch, the <emphasis>only</emphasis> guard that will
-	be set on it afterwards is <literal>+c</literal>.</para>
-    </note>
-
-    <para id="x_173">Mercurial stores guards in the <filename
-	role="special">series</filename> 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 <command
-	role="hg-ext-mq">qguard</command> command if you don't want
-      to; it's okay to simply edit the <filename
-	role="special">series</filename> file.)</para>
-
-    &interaction.mq.guards.series;
-
-  </sect1>
-  <sect1>
-    <title>Selecting the guards to use</title>
-
-    <para id="x_174">The <command role="hg-ext-mq">qselect</command> 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 <command role="hg-ext-mq">qpush</command>.  It has
-      no other effect; in particular, it doesn't do anything to
-      patches that are already applied.</para>
-
-    <para id="x_175">With no arguments, the <command
-	role="hg-ext-mq">qselect</command> command lists the guards
-      currently in effect, one per line of output.  Each argument is
-      treated as the name of a guard to apply.</para>
-
-      &interaction.mq.guards.qselect.foo;
-
-    <para id="x_176">In case you're interested, the currently selected guards are
-      stored in the <filename role="special">guards</filename> file.</para>
-
-    &interaction.mq.guards.qselect.cat;
-
-    <para id="x_177">We can see the effect the selected guards have when we run
-      <command role="hg-ext-mq">qpush</command>.</para>
-
-    &interaction.mq.guards.qselect.qpush;
-
-    <para id="x_178">A guard cannot start with a
-      <quote><literal>+</literal></quote> or
-      <quote><literal>-</literal></quote> 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:</para>
-
-    &interaction.mq.guards.qselect.error;
-      
-    <para id="x_179">Changing the selected guards changes the patches that are
-      applied.</para>
-
-    &interaction.mq.guards.qselect.quux;
-
-    <para id="x_17a">You can see in the example below that negative guards take
-      precedence over positive guards.</para>
-
-    &interaction.mq.guards.qselect.foobar;
-
-  </sect1>
-  <sect1>
-    <title>MQ's rules for applying patches</title>
-
-    <para id="x_17b">The rules that MQ uses when deciding whether to apply a
-      patch are as follows.</para>
-    <itemizedlist>
-      <listitem><para id="x_17c">A patch that has no guards is always
-	  applied.</para>
-      </listitem>
-      <listitem><para id="x_17d">If the patch has any negative guard that matches
-	  any currently selected guard, the patch is skipped.</para>
-      </listitem>
-      <listitem><para id="x_17e">If the patch has any positive guard that matches
-	  any currently selected guard, the patch is applied.</para>
-      </listitem>
-      <listitem><para id="x_17f">If the patch has positive or negative guards,
-	  but none matches any currently selected guard, the patch is
-	  skipped.</para>
-      </listitem></itemizedlist>
-
-  </sect1>
-  <sect1>
-    <title>Trimming the work environment</title>
-
-    <para id="x_180">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.</para>
-
-    <para id="x_181">I then choose a <quote>base</quote> 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
-      <quote>shape</quote> 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.</para>
-
-    <para id="x_182">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.</para>
-
-  </sect1>
-  <sect1>
-    <title>Dividing up the <filename role="special">series</filename>
-      file</title>
-
-    <para id="x_183">I categorise the patches in the <filename
-	role="special">series</filename> 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.</para>
-
-    <para id="x_184">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.</para>
-    <itemizedlist>
-      <listitem><para id="x_185">The <quote>accepted</quote> 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 <quote>read only</quote> patches,
-	  present only to transform the tree into a similar state as
-	  it is in the upstream maintainer's repository.</para>
-      </listitem>
-      <listitem><para id="x_186">The <quote>rework</quote> group.  Patches that I
-	  have submitted, but that the upstream maintainer has
-	  requested modifications to before he will accept
-	  them.</para>
-      </listitem>
-      <listitem><para id="x_187">The <quote>pending</quote> group.  Patches that
-	  I have not yet submitted to the upstream maintainer, but
-	  which we have finished working on. These will be <quote>read
-	    only</quote> for a while.  If the upstream maintainer
-	  accepts them upon submission, I'll move them to the end of
-	  the <quote>accepted</quote> group.  If he requests that I
-	  modify any, I'll move them to the beginning of the
-	  <quote>rework</quote> group.</para>
-      </listitem>
-      <listitem><para id="x_188">The <quote>in progress</quote> group.  Patches
-	  that are actively being developed, and should not be
-	  submitted anywhere yet.</para>
-      </listitem>
-      <listitem><para id="x_189">The <quote>backport</quote> group.  Patches that
-	  adapt the source tree to older versions of the kernel
-	  tree.</para>
-      </listitem>
-      <listitem><para id="x_18a">The <quote>do not ship</quote> 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.</para>
-      </listitem></itemizedlist>
-
-    <para id="x_18b">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 <filename
-	role="special">series</filename> file serves this
-      purpose.</para>
-
-    <para id="x_18c">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.</para>
-
-    <para id="x_18d">The <quote>backport</quote> and <quote>do not ship</quote>
-      patches float at the end of the <filename
-	role="special">series</filename> file.  The backport patches
-      must be applied on top of all other patches, and the <quote>do
-	not ship</quote> patches might as well stay out of harm's
-      way.</para>
-
-  </sect1>
-  <sect1>
-    <title>Maintaining the patch series</title>
-
-    <para id="x_18e">In my work, I use a number of guards to control which
-      patches are to be applied.</para>
-
-    <itemizedlist>
-      <listitem><para id="x_18f"><quote>Accepted</quote> patches are guarded with
-	  <literal>accepted</literal>.  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.</para>
-      </listitem>
-      <listitem><para id="x_190">Patches that are <quote>finished</quote>, 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.</para>
-      </listitem>
-      <listitem><para id="x_191">Those patches that need reworking before being
-	  resubmitted are guarded with
-	  <literal>rework</literal>.</para>
-      </listitem>
-      <listitem><para id="x_192">For those patches that are still under
-	  development, I use <literal>devel</literal>.</para>
-      </listitem>
-      <listitem><para id="x_193">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 <literal>2.6.9</literal> guard.</para>
-      </listitem></itemizedlist>
-    <para id="x_194">This variety of guards gives me considerable flexibility in
-      determining 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.</para>
-
-    <sect2>
-      <title>The art of writing backport patches</title>
-
-      <para id="x_195">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.</para>
-
-      <para id="x_196">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
-	<quote>rat's nest</quote> effect of lots of
-	<literal>#ifdef</literal>s (hunks of source code that are only
-	used conditionally) in your code, don't introduce
-	version-dependent <literal>#ifdef</literal>s into the patches.
-	Instead, write several patches, each of which makes
-	unconditional changes, and control their application using
-	guards.</para>
-
-      <para id="x_197">There are two reasons to divide backport patches into a
-	distinct group, away from the <quote>regular</quote> patches
-	whose effects they modify. The first is that intermingling the
-	two makes it more difficult to use a tool like the <literal
-	  role="hg-ext">patchbomb</literal> 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
-	<emphasis>without</emphasis> the earlier backport patch
-	already being applied.</para>
-
-    </sect2>
-  </sect1>
-  <sect1>
-    <title>Useful tips for developing with MQ</title>
-
-    <sect2>
-      <title>Organising patches in directories</title>
-
-      <para id="x_198">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.</para>
-
-      <para id="x_199">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.</para>
-
-    </sect2>
-    <sect2 id="mq-collab:tips:interdiff">
-      <title>Viewing the history of a patch</title>
-
-      <para id="x_19a">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 <xref linkend="sec:mq:repo"/>.  If you do
-	so, you'll quickly
-	discover that using the <command role="hg-cmd">hg
-	  diff</command> 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.</para>
-
-      <para id="x_19b">However, you can use the <literal
-	  role="hg-ext">extdiff</literal> 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 <literal role="package">patchutils</literal>
-	<citation>web:patchutils</citation>.  This provides a command
-	named <command>interdiff</command>, 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.</para>
-
-      <para id="x_19c">You can enable the <literal
-	  role="hg-ext">extdiff</literal> extension in the usual way,
-	by adding a line to the <literal
-	  role="rc-extensions">extensions</literal> section of your
-	<filename role="special">~/.hgrc</filename>.</para>
-      <programlisting>[extensions]
-extdiff =</programlisting>
-      <para id="x_19d">The <command>interdiff</command> command expects to be
-	passed the names of two files, but the <literal
-	  role="hg-ext">extdiff</literal> 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</command> on each pair of files in
-	these two directories.  This program is available as <filename
-	  role="special">hg-interdiff</filename> in the <filename
-	  class="directory">examples</filename> directory of the
-	source code repository that accompanies this book. <!--
-	&example.hg-interdiff; --></para>
-
-      <para id="x_19e">With the <filename role="special">hg-interdiff</filename>
-	program in your shell's search path, you can run it as
-	follows, from inside an MQ patch directory:</para>
-      <programlisting>hg extdiff -p hg-interdiff -r A:B my-change.patch</programlisting>
-      <para id="x_19f">Since you'll probably want to use this long-winded command
-	a lot, you can get <literal role="hg-ext">hgext</literal> to
-	make it available as a normal Mercurial command, again by
-	editing your <filename
-	  role="special">~/.hgrc</filename>.</para>
-      <programlisting>[extdiff]
-cmd.interdiff = hg-interdiff</programlisting>
-      <para id="x_1a0">This directs <literal role="hg-ext">hgext</literal> to
-	make an <literal>interdiff</literal> command available, so you
-	can now shorten the previous invocation of <command
-	  role="hg-ext-extdiff">extdiff</command> to something a
-	little more wieldy.</para>
-      <programlisting>hg interdiff -r A:B my-change.patch</programlisting>
-
-      <note>
-	<para id="x_1a1">  The <command>interdiff</command> 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</command> may not produce useful
-	  output.</para>
-      </note>
-
-      <para id="x_1a2">The <literal role="hg-ext">extdiff</literal> extension is
-	useful for more than merely improving the presentation of MQ
-	patches.  To read more about it, go to <xref
-	  linkend="sec:hgext:extdiff"/>.</para>
-
-    </sect2>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch12-mq.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,1368 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:mq">
+  <?dbhtml filename="managing-change-with-mercurial-queues.html"?>
+  <title>Managing change with Mercurial Queues</title>
+
+  <sect1 id="sec:mq:patch-mgmt">
+    <title>The patch management problem</title>
+
+    <para id="x_3ac">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.</para>
+
+    <para id="x_3ad">This is a simple case of the <quote>patch management</quote>
+      problem.  You have an <quote>upstream</quote> 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.</para>
+
+    <para id="x_3ae">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.</para>
+
+    <para id="x_3af">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.</para>
+
+    <para id="x_3b0">When you have few changes to maintain, it is easy to manage
+      a single patch using the standard <command>diff</command> and
+      <command>patch</command> programs (see <xref
+	linkend="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 <quote>chunks of
+	work,</quote> so that for example a single patch will contain
+      only one bug fix (the patch might modify several files, but it's
+      doing <quote>only one thing</quote>), 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.</para>
+
+    <para id="x_3b1">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.</para>
+
+    <para id="x_3b2">Fortunately, Mercurial includes a powerful extension,
+      Mercurial Queues (or simply <quote>MQ</quote>), that massively
+      simplifies the patch management problem.</para>
+
+  </sect1>
+  <sect1 id="sec:mq:history">
+    <title>The prehistory of Mercurial Queues</title>
+
+    <para id="x_3b3">During the late 1990s, several Linux kernel developers
+      started to maintain <quote>patch series</quote> that modified
+      the behavior of the Linux kernel.  Some of these series were
+      focused on stability, some on feature coverage, and others were
+      more speculative.</para>
+
+    <para id="x_3b4">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.</para>
+
+    <sect2 id="sec:mq:quilt">
+      <title>A patchwork quilt</title>
+
+      <para id="x_3b5">In early 2003, Andreas Gruenbacher and Martin Quinson
+	borrowed the approach of Andrew's scripts and published a tool
+	called <quote>patchwork quilt</quote>
+	<citation>web:quilt</citation>, or simply <quote>quilt</quote>
+	(see <citation>gruenbacher:2005</citation> for a paper
+	describing it).  Because quilt substantially automated patch
+	management, it rapidly gained a large following among open
+	source software developers.</para>
+
+      <para id="x_3b6">Quilt manages a <emphasis>stack of patches</emphasis> 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 <quote>refresh</quote> the
+	patch.</para>
+
+      <para id="x_3b7">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 <quote>tree
+	  with one patch applied</quote> to <quote>tree with two
+	  patches applied</quote>.</para>
+
+      <para id="x_3b8">You can <emphasis>change</emphasis> which patches are
+	applied to the tree.  If you <quote>pop</quote> 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 <quote>push</quote> a popped patch again, and the
+	directory tree will be restored to contain the modifications
+	in the patch.  Most importantly, you can run the
+	<quote>refresh</quote> 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.</para>
+
+      <para id="x_3b9">Quilt knows nothing about revision control tools, so it
+	works equally well on top of an unpacked tarball or a
+	Subversion working copy.</para>
+    </sect2>
+
+    <sect2 id="sec:mq:quilt-mq">
+      <title>From patchwork quilt to Mercurial Queues</title>
+
+      <para id="x_3ba">In mid-2005, Chris Mason took the features of quilt and
+	wrote an extension that he called Mercurial Queues, which
+	added quilt-like behavior to Mercurial.</para>
+
+      <para id="x_3bb">The key difference between quilt and MQ is that quilt
+	knows nothing about revision control systems, while MQ is
+	<emphasis>integrated</emphasis> into Mercurial.  Each patch
+	that you push is represented as a Mercurial changeset.  Pop a
+	patch, and the changeset goes away.</para>
+
+      <para id="x_3bc">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.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>The huge advantage of MQ</title>
+
+    <para id="x_3bd">I cannot overstate the value that MQ offers through the
+      unification of patches and revision control.</para>
+
+    <para id="x_3be">A major reason that patches have persisted in the free
+      software and open source world&emdash;in spite of the
+      availability of increasingly capable revision control tools over
+      the years&emdash;is the <emphasis>agility</emphasis> they
+      offer.</para>
+
+    <para id="x_3bf">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&emdash;or worse,
+      misleading or destabilising&emdash;traces of your missteps and
+      errors in the permanent revision record.</para>
+
+    <para id="x_3c0">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&emdash;as many times as you need to, until you
+      have refined it into the form you desire.</para>
+
+    <para id="x_3c1">As an example, the integration of patches with revision
+      control makes understanding patches and debugging their
+      effects&emdash;and their interplay with the code they're based
+      on&emdash;<emphasis>enormously</emphasis> easier. Since every
+      applied patch has an associated changeset, you can give <command
+	role="hg-cmd">hg log</command> a file name to see which
+      changesets and patches affected the file.  You can use the
+      <command role="hg-cmd">hg bisect</command> command to
+      binary-search through all changesets and applied patches to see
+      where a bug got introduced or fixed.  You can use the <command
+	role="hg-cmd">hg annotate</command> command to see which
+      changeset or patch modified a particular line of a source file.
+      And so on.</para>
+  </sect1>
+
+  <sect1 id="sec:mq:patch">
+    <title>Understanding patches</title>
+
+    <para id="x_3c2">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.</para>
+
+    <para id="x_3c3">The traditional Unix <command>diff</command> command
+      compares two files, and prints a list of differences between
+      them. The <command>patch</command> command understands these
+      differences as <emphasis>modifications</emphasis> to make to a
+      file.  Take a look below for a simple example of these commands
+      in action.</para>
+
+      &interaction.mq.dodiff.diff;
+
+    <para id="x_3c4">The type of file that <command>diff</command> generates (and
+      <command>patch</command> takes as input) is called a
+      <quote>patch</quote> or a <quote>diff</quote>; there is no
+      difference between a patch and a diff.  (We'll use the term
+      <quote>patch</quote>, since it's more commonly used.)</para>
+
+    <para id="x_3c5">A patch file can start with arbitrary text; the
+      <command>patch</command> 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</command>
+      searches for the first line that starts with the string
+      <quote><literal>diff -</literal></quote>.</para>
+
+    <para id="x_3c6">MQ works with <emphasis>unified</emphasis> diffs
+      (<command>patch</command> can accept several other diff formats,
+      but MQ doesn't).  A unified diff contains two kinds of header.
+      The <emphasis>file header</emphasis> describes the file being
+      modified; it contains the name of the file to modify.  When
+      <command>patch</command> sees a new file header, it looks for a
+      file with that name to start modifying.</para>
+
+    <para id="x_3c7">After the file header comes a series of
+      <emphasis>hunks</emphasis>.  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
+      <emphasis>context</emphasis> for the hunk.  If there's only a
+      small amount of context between successive hunks,
+      <command>diff</command> doesn't print a new hunk header; it just
+      runs the hunks together, with a few lines of context between
+      modifications.</para>
+
+    <para id="x_3c8">Each line of context begins with a space character.  Within
+      the hunk, a line that begins with
+      <quote><literal>-</literal></quote> means <quote>remove this
+	line,</quote> while a line that begins with
+      <quote><literal>+</literal></quote> means <quote>insert this
+	line.</quote>  For example, a line that is modified is
+      represented by one deletion and one insertion.</para>
+
+    <para id="x_3c9">We will return to some of the more subtle aspects of patches
+      later (in <xref linkend="sec:mq:adv-patch"/>), but you
+      should have
+      enough information now to use MQ.</para>
+  </sect1>
+
+  <sect1 id="sec:mq:start">
+    <title>Getting started with Mercurial Queues</title>
+
+    <para id="x_3ca">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 <filename
+	role="home">~/.hgrc</filename> file, and add the lines
+      below.</para>
+
+    <programlisting>[extensions]
+hgext.mq =</programlisting>
+
+    <para id="x_3cb">Once the extension is enabled, it will make a number of new
+      commands available.  To verify that the extension is working,
+      you can use <command role="hg-cmd">hg help</command> to see if
+      the <command role="hg-ext-mq">qinit</command> command is now
+      available.</para>
+
+    &interaction.mq.qinit-help.help;
+
+    <para id="x_3cc">You can use MQ with <emphasis>any</emphasis> Mercurial
+      repository, and its commands only operate within that
+      repository.  To get started, simply prepare the repository using
+      the <command role="hg-ext-mq">qinit</command> command.</para>
+
+    &interaction.mq.tutorial.qinit;
+
+    <para id="x_3cd">This command creates an empty directory called <filename
+	role="special" class="directory">.hg/patches</filename>, where
+      MQ will keep its metadata.  As with many Mercurial commands, the
+      <command role="hg-ext-mq">qinit</command> command prints nothing
+      if it succeeds.</para>
+
+    <sect2>
+      <title>Creating a new patch</title>
+
+      <para id="x_3ce">To begin work on a new patch, use the <command
+	  role="hg-ext-mq">qnew</command> command.  This command takes
+	one argument, the name of the patch to create.</para>
+
+      <para id="x_3cf">MQ will use this as the name of an actual file in the
+	<filename role="special"
+	  class="directory">.hg/patches</filename> directory, as you
+	can see below.</para>
+
+      &interaction.mq.tutorial.qnew;
+
+      <para id="x_3d0">Also newly present in the <filename role="special"
+	  class="directory">.hg/patches</filename> directory are two
+	other files, <filename role="special">series</filename> and
+	<filename role="special">status</filename>.  The <filename
+	  role="special">series</filename> file lists all of the
+	patches that MQ knows about for this repository, with one
+	patch per line.  Mercurial uses the <filename
+	  role="special">status</filename> file for internal
+	book-keeping; it tracks all of the patches that MQ has
+	<emphasis>applied</emphasis> in this repository.</para>
+
+      <note>
+	<para id="x_3d1">  You may sometimes want to edit the <filename
+	    role="special">series</filename> file by hand; for
+	  example, to change the sequence in which some patches are
+	  applied.  However, manually editing the <filename
+	    role="special">status</filename> file is almost always a
+	  bad idea, as it's easy to corrupt MQ's idea of what is
+	  happening.</para>
+      </note>
+
+      <para id="x_3d2">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 <command role="hg-cmd">hg
+	  diff</command> and <command role="hg-cmd">hg
+	  annotate</command>, work exactly as they did before.</para>
+    </sect2>
+
+    <sect2>
+      <title>Refreshing a patch</title>
+
+      <para id="x_3d3">When you reach a point where you want to save your work,
+	use the <command role="hg-ext-mq">qrefresh</command> command
+	to update the patch you are working on.</para>
+
+      &interaction.mq.tutorial.qrefresh;
+
+      <para id="x_3d4">This command folds the changes you have made in the
+	working directory into your patch, and updates its
+	corresponding changeset to contain those changes.</para>
+
+      <para id="x_3d5">You can run <command role="hg-ext-mq">qrefresh</command>
+	as often as you like, so it's a good way to
+	<quote>checkpoint</quote> your work.  Refresh your patch at an
+	opportune time; try an experiment; and if the experiment
+	doesn't work out, <command role="hg-cmd">hg revert</command>
+	your modifications back to the last time you refreshed.</para>
+
+      &interaction.mq.tutorial.qrefresh2;
+    </sect2>
+
+    <sect2>
+      <title>Stacking and tracking patches</title>
+
+      <para id="x_3d6">Once you have finished working on a patch, or need to work
+	on another, you can use the <command
+	  role="hg-ext-mq">qnew</command> command again to create a
+	new patch. Mercurial will apply this patch on top of your
+	existing patch.</para>
+
+      &interaction.mq.tutorial.qnew2;
+
+      <para id="x_3d7">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 <command role="hg-cmd">hg
+	  annotate</command>).</para>
+
+      <para id="x_3d8">So far, with the exception of <command
+	  role="hg-ext-mq">qnew</command> and <command
+	  role="hg-ext-mq">qrefresh</command>, 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 below.</para>
+
+      &interaction.mq.tutorial.qseries;
+
+      <itemizedlist>
+	<listitem><para id="x_3d9">The <command
+	      role="hg-ext-mq">qseries</command> command lists every
+	    patch that MQ knows about in this repository, from oldest
+	    to newest (most recently
+	    <emphasis>created</emphasis>).</para>
+	</listitem>
+	<listitem><para id="x_3da">The <command
+	      role="hg-ext-mq">qapplied</command> command lists every
+	    patch that MQ has <emphasis>applied</emphasis> in this
+	    repository, again from oldest to newest (most recently
+	    applied).</para>
+	</listitem></itemizedlist>
+    </sect2>
+
+    <sect2>
+      <title>Manipulating the patch stack</title>
+
+      <para id="x_3db">The previous discussion implied that there must be a
+	difference between <quote>known</quote> and
+	<quote>applied</quote> patches, and there is.  MQ can manage a
+	patch without it being applied in the repository.</para>
+
+      <para id="x_3dc">An <emphasis>applied</emphasis> 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 <command
+	  role="hg-ext-mq">qpop</command> command.  MQ still
+	<emphasis>knows about</emphasis>, 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.  <xref
+	  linkend="fig:mq:stack"/> illustrates
+	the difference between applied and tracked patches.</para>
+
+      <figure id="fig:mq:stack">
+	<title>Applied and unapplied patches in the MQ patch
+	  stack</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/mq-stack.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_3de">You can reapply an unapplied, or popped, patch using the
+	<command role="hg-ext-mq">qpush</command> 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 below for examples of <command
+	  role="hg-ext-mq">qpop</command> and <command
+	  role="hg-ext-mq">qpush</command> in action.</para>
+
+      &interaction.mq.tutorial.qpop;
+
+      <para id="x_3df">Notice that once we have popped a patch or two patches,
+	the output of <command role="hg-ext-mq">qseries</command>
+	remains the same, while that of <command
+	  role="hg-ext-mq">qapplied</command> has changed.</para>
+
+    </sect2>
+
+    <sect2>
+      <title>Pushing and popping many patches</title>
+
+      <para id="x_3e0">While <command role="hg-ext-mq">qpush</command> and
+	<command role="hg-ext-mq">qpop</command> each operate on a
+	single patch at a time by default, you can push and pop many
+	patches in one go.  The <option
+	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to
+	<command role="hg-ext-mq">qpush</command> causes it to push
+	all unapplied patches, while the <option
+	  role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command
+	  role="hg-ext-mq">qpop</command> causes it to pop all applied
+	patches.  (For some more ways to push and pop many patches,
+	see <xref linkend="sec:mq:perf"/> below.)</para>
+
+      &interaction.mq.tutorial.qpush-a;
+    </sect2>
+
+    <sect2>
+      <title>Safety checks, and overriding them</title>
+
+      <para id="x_3e1">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.  The
+	example below illustrates this; the <command
+	  role="hg-ext-mq">qnew</command> command will not create a
+	new patch if there are outstanding changes, caused in this
+	case by the <command role="hg-cmd">hg add</command> of
+	<filename>file3</filename>.</para>
+
+      &interaction.mq.tutorial.add;
+
+      <para id="x_3e2">Commands that check the working directory all take an
+	<quote>I know what I'm doing</quote> option, which is always
+	named <option>-f</option>.  The exact meaning of
+	<option>-f</option> depends on the command.  For example,
+	<command role="hg-cmd">hg qnew <option
+	    role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command>
+	will incorporate any outstanding changes into the new patch it
+	creates, but <command role="hg-cmd">hg qpop <option
+	    role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command>
+	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> option before you use it!</para>
+    </sect2>
+
+    <sect2>
+      <title>Working on several patches at once</title>
+
+      <para id="x_3e3">The <command role="hg-ext-mq">qrefresh</command> command
+	always refreshes the <emphasis>topmost</emphasis> 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 <emphasis>that</emphasis> patch for a
+	while.</para>
+
+      <para id="x_3e4">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&emdash;layered on top of the
+	first&emdash;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 <command role="hg-ext-mq">qrefresh</command> the UI
+	patch to save your in-progress changes, and <command
+	  role="hg-ext-mq">qpop</command> down to the core patch.  Fix
+	the core bug, <command role="hg-ext-mq">qrefresh</command> the
+	core patch, and <command role="hg-ext-mq">qpush</command> back
+	to the UI patch to continue where you left off.</para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="sec:mq:adv-patch">
+    <title>More about patches</title>
+
+    <para id="x_3e5">MQ uses the GNU <command>patch</command> command to apply
+      patches, so it's helpful to know a few more detailed aspects of
+      how <command>patch</command> works, and about patches
+      themselves.</para>
+
+    <sect2>
+      <title>The strip count</title>
+
+      <para id="x_3e6">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).</para>
+
+      <para id="x_3e7">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 <option
+	  role="cmd-opt-diff">-r</option> and <option
+	  role="cmd-opt-diff">-N</option> options to
+	<command>diff</command> 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.</para>
+
+      <para id="x_3e8">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>
+	command has a <option role="cmd-opt-patch">-p</option> option
+	that indicates the number of leading path name components to
+	strip when trying to apply a patch.  This number is called the
+	<emphasis>strip count</emphasis>.</para>
+
+      <para id="x_3e9">An option of <quote><literal>-p1</literal></quote> means
+	<quote>use a strip count of one</quote>.  If
+	<command>patch</command> sees a file name
+	<filename>foo/bar/baz</filename> in a file header, it will
+	strip <filename>foo</filename> and try to patch a file named
+	<filename>bar/baz</filename>.  (Strictly speaking, the strip
+	count refers to the number of <emphasis>path
+	  separators</emphasis> (and the components that go with them
+	) to strip.  A strip count of one will turn
+	<filename>foo/bar</filename> into <filename>bar</filename>,
+	but <filename>/foo/bar</filename> (notice the extra leading
+	slash) into <filename>foo/bar</filename>.)</para>
+
+      <para id="x_3ea">The <quote>standard</quote> strip count for patches is
+	one; almost all patches contain one leading path name
+	component that needs to be stripped. Mercurial's <command
+	  role="hg-cmd">hg diff</command> command generates path names
+	in this form, and the <command role="hg-cmd">hg
+	  import</command> command and MQ expect patches to have a
+	strip count of one.</para>
+
+      <para id="x_3eb">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 <command
+	  role="hg-ext-mq">qimport</command> the patch, because
+	<command role="hg-ext-mq">qimport</command> does not yet have
+	a <literal>-p</literal> option (see <ulink role="hg-bug"
+	  url="http://www.selenic.com/mercurial/bts/issue311">issue
+	  311</ulink>).  Your best bet is to <command
+	  role="hg-ext-mq">qnew</command> a patch of your own, then
+	use <command>patch -pN</command> to apply their patch,
+	followed by <command role="hg-cmd">hg addremove</command> to
+	pick up any files added or removed by the patch, followed by
+	<command role="hg-ext-mq">hg qrefresh</command>. This
+	complexity may become unnecessary; see <ulink role="hg-bug"
+	  url="http://www.selenic.com/mercurial/bts/issue311">issue
+	  311</ulink> for details.
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>Strategies for applying a patch</title>
+
+      <para id="x_3ec">When <command>patch</command> 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.</para>
+
+      <para id="x_3ed">First, <command>patch</command> 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 <emphasis>offset</emphasis> from the
+	original line number.</para>
+
+      <para id="x_3ee">If a context-only match fails, <command>patch</command>
+	removes the first and last lines of the context, and tries a
+	<emphasis>reduced</emphasis> context-only match.  If the hunk
+	with reduced context succeeds, it prints a message saying that
+	it applied the hunk with a <emphasis>fuzz factor</emphasis>
+	(the number after the fuzz factor indicates how many lines of
+	context <command>patch</command> had to trim before the patch
+	applied).</para>
+
+      <para id="x_3ef">When neither of these techniques works,
+	<command>patch</command> prints a message saying that the hunk
+	in question was rejected.  It saves rejected hunks (also
+	simply called <quote>rejects</quote>) to a file with the same
+	name, and an added <filename role="special">.rej</filename>
+	extension.  It also saves an unmodified copy of the file with
+	a <filename role="special">.orig</filename> extension; the
+	copy of the file without any extensions will contain any
+	changes made by hunks that <emphasis>did</emphasis> apply
+	cleanly.  If you have a patch that modifies
+	<filename>foo</filename> with six hunks, and one of them fails
+	to apply, you will have: an unmodified
+	<filename>foo.orig</filename>, a <filename>foo.rej</filename>
+	containing one hunk, and <filename>foo</filename>, containing
+	the changes made by the five successful hunks.</para>
+    </sect2>
+
+    <sect2>
+      <title>Some quirks of patch representation</title>
+
+      <para id="x_3f0">There are a few useful things to know about how
+	<command>patch</command> works with files.</para>
+      <itemizedlist>
+	<listitem><para id="x_3f1">This should already be obvious, but
+	    <command>patch</command> cannot handle binary
+	    files.</para>
+	</listitem>
+	<listitem><para id="x_3f2">Neither does it care about the executable bit;
+	    it creates new files as readable, but not
+	    executable.</para>
+	</listitem>
+	<listitem><para id="x_3f3"><command>patch</command> treats the removal of
+	    a file as a diff between the file to be removed and the
+	    empty file.  So your idea of <quote>I deleted this
+	      file</quote> looks like <quote>every line of this file
+	      was deleted</quote> in a patch.</para>
+	</listitem>
+	<listitem><para id="x_3f4">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 <quote>I added this file</quote> looks
+	    like <quote>every line of this file was
+	      added</quote>.</para>
+	</listitem>
+	<listitem><para id="x_3f5">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.)</para>
+	</listitem>
+	<listitem><para id="x_3f6"><command>patch</command> cannot represent
+	    empty files, so you cannot use a patch to represent the
+	    notion <quote>I added this empty file to the
+	      tree</quote>.</para>
+	</listitem></itemizedlist>
+    </sect2>
+
+    <sect2>
+      <title>Beware the fuzz</title>
+
+      <para id="x_3f7">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</command> or <command
+	  role="hg-ext-mq">qpush</command> ever mentions an offset or
+	fuzz factor, you should make sure that the modified files are
+	correct afterwards.</para>
+
+      <para id="x_3f8">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 <quote>often,</quote> not <quote>always,</quote> 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.</para>
+    </sect2>
+
+    <sect2>
+      <title>Handling rejection</title>
+
+      <para id="x_3f9">If <command role="hg-ext-mq">qpush</command> fails to
+	apply a patch, it will print an error message and exit.  If it
+	has left <filename role="special">.rej</filename> files
+	behind, it is usually best to fix up the rejected hunks before
+	you push more patches or do any further work.</para>
+
+      <para id="x_3fa">If your patch <emphasis>used to</emphasis> apply cleanly,
+	and no longer does because you've changed the underlying code
+	that your patches are based on, Mercurial Queues can help; see
+	<xref linkend="sec:mq:merge"/> for details.</para>
+
+      <para id="x_3fb">Unfortunately, there aren't any great techniques for
+	dealing with rejected hunks.  Most often, you'll need to view
+	the <filename role="special">.rej</filename> file and edit the
+	target file, applying the rejected hunks by hand.</para>
+
+      <para id="x_3fd">A Linux kernel hacker, Chris Mason (the author
+	of Mercurial Queues), wrote a tool called
+	<command>mpatch</command> (<ulink
+	  url="http://oss.oracle.com/~mason/mpatch/">http://oss.oracle.com/~mason/mpatch/</ulink>), 
+	which takes a simple approach to automating the application of
+	hunks rejected by <command>patch</command>.  The
+	<command>mpatch</command> command can help with four common
+	reasons that a hunk may be rejected:</para>
+
+      <itemizedlist>
+	<listitem><para id="x_3fe">The context in the middle of a hunk has
+	    changed.</para>
+	</listitem>
+	<listitem><para id="x_3ff">A hunk is missing some context at the
+	    beginning or end.</para>
+	</listitem>
+	<listitem><para id="x_400">A large hunk might apply better&emdash;either
+	    entirely or in part&emdash;if it was broken up into
+	    smaller hunks.</para>
+	</listitem>
+	<listitem><para id="x_401">A hunk removes lines with slightly different
+	    content than those currently present in the file.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_402">If you use <command>mpatch</command>, you
+	should be doubly careful to check your results when you're
+	done.  In fact, <command>mpatch</command> 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.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>More on patch management</title>
+
+    <para id="x_6db">As you grow familiar with MQ, you will find yourself wanting
+      to perform other kinds of patch management operations.</para>
+
+    <sect2>
+      <title>Deleting unwanted patches</title>
+
+      <para id="x_6dc">If you want to get rid of a patch, use the <command
+	  role="hg-ext-mq">hg qdelete</command> command to delete the
+	patch file and remove its entry from the patch series.  If you
+	try to delete a patch that is still applied, <command
+	  role="hg-ext-mq">hg qdelete</command> will refuse.</para>
+
+      &interaction.ch11-qdelete.go;
+    </sect2>
+
+    <sect2>
+      <title>Converting to and from permanent revisions</title>
+
+      <para id="x_6dd">Once you're done working on a patch and want to
+      turn it into a permanent changeset, use the <command
+      role="hg-ext-mq">hg qfinish</command> command. Pass a revision
+      to the command to identify the patch that you want to turn into
+      a regular changeset; this patch must already be applied.</para>
+
+      &interaction.ch11-qdelete.convert;
+
+      <para id="x_6e0">The <command role="hg-ext-mq">hg qfinish</command> command
+        accepts an <option>--all</option> or <option>-a</option>
+        option, which turns all applied patches into regular
+        changesets.</para>
+
+      <para id="x_6de">It is also possible to turn an existing changeset into a
+	patch, by passing the <option>-r</option> option to <command
+	  role="hg-ext-mq">hg qimport</command>.</para>
+
+      &interaction.ch11-qdelete.import;
+
+      <para id="x_6df">Note that it only makes sense to convert a changeset into
+	a patch if you have not propagated that changeset into any
+	other repositories.  The imported changeset's ID will change
+	every time you refresh the patch, which will make Mercurial
+	treat it as unrelated to the original changeset if you have
+	pushed it somewhere else.</para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="sec:mq:perf">
+    <title>Getting the best performance out of MQ</title>
+
+    <para id="x_403">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 (on modern
+      hardware, you should expect better performance than you'll see
+      below).  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.</para>
+
+    <para id="x_404">On my old, slow laptop, I was able to <command
+	role="hg-cmd">hg qpush <option
+	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all
+      1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop
+	<option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command>
+      them all in 30 seconds.  (On a newer laptop, the time to push
+      all patches dropped to two minutes.)  I could <command
+	role="hg-ext-mq">qrefresh</command> one of the biggest patches
+      (which made 22,779 lines of changes to 287 files) in 6.6
+      seconds.</para>
+
+    <para id="x_405">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.</para>
+
+    <para id="x_406">First of all, try to <quote>batch</quote> operations
+      together.  Every time you run <command
+	role="hg-ext-mq">qpush</command> or <command
+	role="hg-ext-mq">qpop</command>, these commands scan the
+      working directory once to make sure you haven't made some
+      changes and then forgotten to run <command
+	role="hg-ext-mq">qrefresh</command>.  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.</para>
+
+    <para id="x_407">The <command role="hg-ext-mq">qpush</command> and <command
+	role="hg-ext-mq">qpop</command> commands allow you to push and
+      pop multiple patches at a time.  You can identify the
+      <quote>destination patch</quote> that you want to end up at.
+      When you <command role="hg-ext-mq">qpush</command> with a
+      destination specified, it will push patches until that patch is
+      at the top of the applied stack.  When you <command
+	role="hg-ext-mq">qpop</command> to a destination, MQ will pop
+      patches until the destination patch is at the top.</para>
+
+    <para id="x_408">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.</para>
+  </sect1>
+
+  <sect1 id="sec:mq:merge">
+    <title>Updating your patches when the underlying code
+      changes</title>
+
+    <para id="x_409">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 <emphasis>rebasing</emphasis> your patch
+      series.</para>
+
+    <para id="x_40a">The simplest way to do this is to <command role="hg-cmd">hg
+	qpop <option role="hg-ext-mq-cmd-qpop-opt">hg
+	  -a</option></command> your patches, then <command
+	role="hg-cmd">hg pull</command> changes into the underlying
+      repository, and finally <command role="hg-cmd">hg qpush <option
+	  role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> 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, <command role="hg-ext-mq">qrefresh</command> the
+      affected patch, and continue pushing until you have fixed your
+      entire stack.</para>
+
+    <para id="x_40b">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.</para>
+
+    <para id="x_40c">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.</para>
+
+    <para id="x_40d">The process is a little involved.</para>
+    <orderedlist>
+      <listitem><para id="x_40e">To begin, <command role="hg-cmd">hg qpush
+	    -a</command> all of your patches on top of the revision
+	  where you know that they apply cleanly.</para>
+      </listitem>
+      <listitem><para id="x_40f">Save a backup copy of your patch directory using
+	  <command role="hg-cmd">hg qsave <option
+	      role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option
+	      role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>.
+	  This prints the name of the directory that it has saved the
+	  patches in.  It will save the patches to a directory called
+	  <filename role="special"
+	    class="directory">.hg/patches.N</filename>, where
+	  <literal>N</literal> is a small integer.  It also commits a
+	  <quote>save changeset</quote> on top of your applied
+	  patches; this is for internal book-keeping, and records the
+	  states of the <filename role="special">series</filename> and
+	  <filename role="special">status</filename> files.</para>
+      </listitem>
+      <listitem><para id="x_410">Use <command role="hg-cmd">hg pull</command> to
+	  bring new changes into the underlying repository.  (Don't
+	  run <command role="hg-cmd">hg pull -u</command>; see below
+	  for why.)</para>
+      </listitem>
+      <listitem><para id="x_411">Update to the new tip revision, using <command
+	    role="hg-cmd">hg update <option
+	      role="hg-opt-update">-C</option></command> to override
+	  the patches you have pushed.</para>
+      </listitem>
+      <listitem><para id="x_412">Merge all patches using <command>hg qpush -m
+	    -a</command>.  The <option
+	    role="hg-ext-mq-cmd-qpush-opt">-m</option> option to
+	  <command role="hg-ext-mq">qpush</command> tells MQ to
+	  perform a three-way merge if the patch fails to
+	  apply.</para>
+      </listitem></orderedlist>
+
+    <para id="x_413">During the <command role="hg-cmd">hg qpush <option
+	  role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>,
+      each patch in the <filename role="special">series</filename>
+      file is applied normally.  If a patch applies with fuzz or
+      rejects, MQ looks at the queue you <command
+	role="hg-ext-mq">qsave</command>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.</para>
+
+    <para id="x_414">When you finish resolving the effects of a patch, MQ
+      refreshes your patch based on the result of the merge.</para>
+
+    <para id="x_415">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 <filename role="special"
+	class="directory">.hg/patches.N</filename>. You can remove the
+      extra head using <command role="hg-cmd">hg qpop -a -n
+	patches.N</command> or <command role="hg-cmd">hg
+	strip</command>.  You can delete <filename role="special"
+	class="directory">.hg/patches.N</filename> once you are sure
+      that you no longer need it as a backup.</para>
+  </sect1>
+
+  <sect1>
+    <title>Identifying patches</title>
+
+    <para id="x_416">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</filename> to <command
+	role="hg-ext-mq">qpush</command>, for example, and it will
+      push patches until <filename>foo.patch</filename> is
+      applied.</para>
+
+    <para id="x_417">As a shortcut, you can refer to a patch using both a name
+      and a numeric offset; <literal>foo.patch-2</literal> means
+      <quote>two patches before <literal>foo.patch</literal></quote>,
+      while <literal>bar.patch+4</literal> means <quote>four patches
+	after <literal>bar.patch</literal></quote>.</para>
+
+    <para id="x_418">Referring to a patch by index isn't much different.  The
+      first patch printed in the output of <command
+	role="hg-ext-mq">qseries</command> is patch zero (yes, it's
+      one of those start-at-zero counting systems); the second is
+      patch one; and so on.</para>
+
+    <para id="x_419">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
+      <literal role="tag">qbase</literal> and
+      <literal role="tag">qtip</literal> identify
+      the <quote>bottom-most</quote> and topmost applied patches,
+      respectively.</para>
+
+    <para id="x_41a">These additions to Mercurial's normal tagging capabilities
+      make dealing with patches even more of a breeze.</para>
+    <itemizedlist>
+      <listitem><para id="x_41b">Want to patchbomb a mailing list with your
+	  latest series of changes?</para>
+	<programlisting>hg email qbase:qtip</programlisting>
+	<para id="x_41c">  (Don't know what <quote>patchbombing</quote> is?  See
+	  <xref linkend="sec:hgext:patchbomb"/>.)</para>
+      </listitem>
+      <listitem><para id="x_41d">Need to see all of the patches since
+	  <literal>foo.patch</literal> that have touched files in a
+	  subdirectory of your tree?</para>
+	<programlisting>hg log -r foo.patch:qtip subdir</programlisting>
+      </listitem>
+    </itemizedlist>
+
+    <para id="x_41e">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.</para>
+
+    <para id="x_41f">Another nice consequence of representing patch names as tags
+      is that when you run the <command role="hg-cmd">hg log</command>
+      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
+      <quote>normal</quote> revisions.  The following example shows a
+      few normal Mercurial commands in use with applied
+      patches.</para>
+
+    &interaction.mq.id.output;
+  </sect1>
+
+  <sect1>
+    <title>Useful things to know about</title>
+
+    <para id="x_420">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.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_421">Normally, when you <command
+	    role="hg-ext-mq">qpop</command> a patch and <command
+	    role="hg-ext-mq">qpush</command> it again, the changeset
+	  that represents the patch after the pop/push will have a
+	  <emphasis>different identity</emphasis> than the changeset
+	  that represented the hash beforehand.  See <xref
+	    linkend="sec:mqref:cmd:qpush"/> for
+	  information as to why this is.</para>
+      </listitem>
+      <listitem><para id="x_422">It's not a good idea to <command
+	    role="hg-cmd">hg merge</command> changes from another
+	  branch with a patch changeset, at least if you want to
+	  maintain the <quote>patchiness</quote> 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.</para>
+      </listitem></itemizedlist>
+  </sect1>
+
+  <sect1 id="sec:mq:repo">
+    <title>Managing patches in a repository</title>
+
+    <para id="x_423">Because MQ's <filename role="special"
+	class="directory">.hg/patches</filename> directory resides
+      outside a Mercurial repository's working directory, the
+      <quote>underlying</quote> Mercurial repository knows nothing
+      about the management or presence of patches.</para>
+
+    <para id="x_424">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, <command
+	role="hg-ext-mq">qrefresh</command> it, then <command
+	role="hg-cmd">hg commit</command> the current state of the
+      patch.  This lets you <quote>roll back</quote> to that version
+      of the patch later on.</para>
+
+    <para id="x_425">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.</para>
+
+    <para id="x_426">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.</para>
+
+    <sect2>
+      <title>MQ support for patch repositories</title>
+
+      <para id="x_427">MQ helps you to work with the <filename role="special"
+	  class="directory">.hg/patches</filename> directory as a
+	repository; when you prepare a repository for working with
+	patches using <command role="hg-ext-mq">qinit</command>, you
+	can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg
+	  -c</option> option to create the <filename role="special"
+	  class="directory">.hg/patches</filename> directory as a
+	Mercurial repository.</para>
+
+      <note>
+	<para id="x_428">  If you forget to use the <option
+	    role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you
+	  can simply go into the <filename role="special"
+	    class="directory">.hg/patches</filename> directory at any
+	  time and run <command role="hg-cmd">hg init</command>.
+	  Don't forget to add an entry for the <filename
+	    role="special">status</filename> file to the <filename
+	    role="special">.hgignore</filename> file, though</para>
+
+	<para id="x_429">  (<command role="hg-cmd">hg qinit <option
+	      role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command>
+	  does this for you automatically); you
+	  <emphasis>really</emphasis> don't want to manage the
+	  <filename role="special">status</filename> file.</para>
+      </note>
+
+      <para id="x_42a">As a convenience, if MQ notices that the <filename
+	  class="directory">.hg/patches</filename> directory is a
+	repository, it will automatically <command role="hg-cmd">hg
+	  add</command> every patch that you create and import.</para>
+
+      <para id="x_42b">MQ provides a shortcut command, <command
+	  role="hg-ext-mq">qcommit</command>, that runs <command
+	  role="hg-cmd">hg commit</command> in the <filename
+	  role="special" class="directory">.hg/patches</filename>
+	directory.  This saves some bothersome typing.</para>
+
+      <para id="x_42c">Finally, as a convenience to manage the patch directory,
+	you can define the alias <command>mq</command> on Unix
+	systems. For example, on Linux systems using the
+	<command>bash</command> shell, you can include the following
+	snippet in your <filename
+	  role="home">~/.bashrc</filename>.</para>
+
+      <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting>
+
+      <para id="x_42d">You can then issue commands of the form <command>mq
+	  pull</command> from the main repository.</para>
+    </sect2>
+
+    <sect2>
+      <title>A few things to watch out for</title>
+
+      <para id="x_42e">MQ's support for working with a repository full of patches
+	is limited in a few small respects.</para>
+
+      <para id="x_42f">MQ cannot automatically detect changes that you make to
+	the patch directory.  If you <command role="hg-cmd">hg
+	  pull</command>, manually edit, or <command role="hg-cmd">hg
+	  update</command> changes to patches or the <filename
+	  role="special">series</filename> file, you will have to
+	<command role="hg-cmd">hg qpop <option
+	    role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and
+	then <command role="hg-cmd">hg qpush <option
+	    role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> 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.</para>
+
+    </sect2>
+  </sect1>
+  <sect1 id="sec:mq:tools">
+    <title>Third party tools for working with patches</title>
+
+    <para id="x_430">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.</para>
+
+    <para id="x_431">The <command>diffstat</command> command
+      <citation>web:diffstat</citation> generates a histogram of the
+      modifications made to each file in a patch.  It provides a good
+      way to <quote>get a sense of</quote> a patch&emdash;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</command>'s <option
+	role="cmd-opt-diffstat">-p</option> 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.)</para>
+
+&interaction.mq.tools.tools;
+
+    <para id="x_432">The <literal role="package">patchutils</literal> package
+      <citation>web:patchutils</citation> is invaluable. It provides a
+      set of small utilities that follow the <quote>Unix
+	philosophy;</quote> each does one useful thing with a patch.
+      The <literal role="package">patchutils</literal> command I use
+      most is <command>filterdiff</command>, 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</command> can generate a
+      smaller patch that only touches files whose names match a
+      particular glob pattern.  See <xref
+	linkend="mq-collab:tips:interdiff"/> for another
+      example.</para>
+
+  </sect1>
+  <sect1>
+    <title>Good ways to work with patches</title>
+
+    <para id="x_433">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
+      organized.</para>
+
+    <para id="x_434">Give your patches descriptive names.  A good name for a
+      patch might be <filename>rework-device-alloc.patch</filename>,
+      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 <emphasis>will</emphasis> be
+      running commands like <command
+	role="hg-ext-mq">qapplied</command> and <command
+	role="hg-ext-mq">qtop</command> 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.</para>
+
+    <para id="x_435">Be aware of what patch you're working on.  Use the <command
+	role="hg-ext-mq">qtop</command> command and skim over the text
+      of your patches frequently&emdash;for example, using <command
+	role="hg-cmd">hg tip <option
+	  role="hg-opt-tip">-p</option></command>)&emdash;to be sure
+      of where you stand.  I have several times worked on and <command
+	role="hg-ext-mq">qrefresh</command>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.</para>
+
+    <para id="x_436">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 <xref linkend="sec:mq:tools"/>,
+      particularly
+      <command>diffstat</command> and <command>filterdiff</command>.
+      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.</para>
+
+  </sect1>
+  <sect1>
+    <title>MQ cookbook</title>
+
+    <sect2>
+      <title>Manage <quote>trivial</quote> patches</title>
+
+      <para id="x_437">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.</para>
+
+      <para id="x_438">Begin by downloading and unpacking the source tarball, and
+	turning it into a Mercurial repository.</para>
+
+      &interaction.mq.tarball.download;
+
+      <para id="x_439">Continue by creating a patch stack and making your
+	changes.</para>
+
+      &interaction.mq.tarball.qinit;
+
+      <para id="x_43a">Let's say a few weeks or months pass, and your package
+	author releases a new version.  First, bring their changes
+	into the repository.</para>
+
+      &interaction.mq.tarball.newsource;
+
+      <para id="x_43b">The pipeline starting with <command role="hg-cmd">hg
+	  locate</command> above deletes all files in the working
+	directory, so that <command role="hg-cmd">hg
+	  commit</command>'s <option
+	  role="hg-opt-commit">--addremove</option> option can
+	actually tell which files have really been removed in the
+	newer version of the source.</para>
+
+      <para id="x_43c">Finally, you can apply your patches on top of the new
+	tree.</para>
+
+      &interaction.mq.tarball.repush;
+    </sect2>
+
+    <sect2 id="sec:mq:combine">
+      <title>Combining entire patches</title>
+
+      <para id="x_43d">MQ provides a command, <command
+	  role="hg-ext-mq">qfold</command> that lets you combine
+	entire patches.  This <quote>folds</quote> 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.</para>
+
+      <para id="x_43e">The order in which you fold patches matters.  If your
+	topmost applied patch is <literal>foo</literal>, and you
+	<command role="hg-ext-mq">qfold</command>
+	<literal>bar</literal> and <literal>quux</literal> into it,
+	you will end up with a patch that has the same effect as if
+	you applied first <literal>foo</literal>, then
+	<literal>bar</literal>, followed by
+	<literal>quux</literal>.</para>
+    </sect2>
+
+    <sect2>
+      <title>Merging part of one patch into another</title>
+
+      <para id="x_43f">Merging <emphasis>part</emphasis> of one patch into
+	another is more difficult than combining entire
+	patches.</para>
+
+      <para id="x_440">If you want to move changes to entire files, you can use
+	<command>filterdiff</command>'s <option
+	  role="cmd-opt-filterdiff">-i</option> and <option
+	  role="cmd-opt-filterdiff">-x</option> 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 <command role="hg-ext-mq">qpush</command> it (from
+	the hunks you moved into the other patch), and you can simply
+	<command role="hg-ext-mq">qrefresh</command> the patch to drop
+	the duplicate hunks.</para>
+
+      <para id="x_441">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
+	<command>lsdiff -nvv</command> to print some metadata about
+	the patch.</para>
+
+      &interaction.mq.tools.lsdiff;
+
+      <para id="x_442">This command prints three different kinds of
+	number:</para>
+      <itemizedlist>
+	<listitem><para id="x_443">(in the first column) a <emphasis>file
+	      number</emphasis> to identify each file modified in the
+	    patch;</para>
+	</listitem>
+	<listitem><para id="x_444">(on the next line, indented) the line number
+	    within a modified file where a hunk starts; and</para>
+	</listitem>
+	<listitem><para id="x_445">(on the same line) a <emphasis>hunk
+	      number</emphasis> to identify that hunk.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_446">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</command>'s <option
+	  role="cmd-opt-filterdiff">--files</option> and <option
+	  role="cmd-opt-filterdiff">--hunks</option> options, to
+	select exactly the file and hunk you want to extract.</para>
+
+      <para id="x_447">Once you have this hunk, you can concatenate it onto the
+	end of your destination patch and continue with the remainder
+	of <xref linkend="sec:mq:combine"/>.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Differences between quilt and MQ</title>
+
+    <para id="x_448">If you are already familiar with quilt, MQ provides a
+      similar command set.  There are a few differences in the way
+      that it works.</para>
+
+    <para id="x_449">You will already have noticed that most quilt commands have
+      MQ counterparts that simply begin with a
+      <quote><literal>q</literal></quote>.  The exceptions are quilt's
+      <literal>add</literal> and <literal>remove</literal> commands,
+      the counterparts for which are the normal Mercurial <command
+	role="hg-cmd">hg add</command> and <command role="hg-cmd">hg
+	remove</command> commands.  There is no MQ equivalent of the
+      quilt <literal>edit</literal> command.</para>
+
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- a/en/ch13-hgext.xml	Thu May 07 21:06:49 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,554 +0,0 @@
-<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
-
-<chapter id="chap:hgext">
-  <?dbhtml filename="adding-functionality-with-extensions.html"?>
-  <title>Adding functionality with extensions</title>
-
-  <para id="x_4fe">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.</para>
-
-  <para id="x_4ff">However, Mercurial doesn't box you in with an inflexible
-    command set: you can add features to it as
-    <emphasis>extensions</emphasis> (sometimes known as
-    <emphasis>plugins</emphasis>).  We've already discussed a few of
-    these extensions in earlier chapters.</para>
-  <itemizedlist>
-    <listitem><para id="x_500"><xref linkend="sec:tour-merge:fetch"/>
-	covers the <literal role="hg-ext">fetch</literal> extension;
-	this combines pulling new changes and merging them with local
-	changes into a single command, <command
-	  role="hg-ext-fetch">fetch</command>.</para>
-    </listitem>
-    <listitem><para id="x_501">In <xref linkend="chap:hook"/>, we covered
-	several extensions that are useful for hook-related
-	functionality: <literal role="hg-ext">acl</literal> adds
-	access control lists; <literal
-	  role="hg-ext">bugzilla</literal> adds integration with the
-	Bugzilla bug tracking system; and <literal
-	  role="hg-ext">notify</literal> sends notification emails on
-	new changes.</para>
-    </listitem>
-    <listitem><para id="x_502">The Mercurial Queues patch management extension is
-	so invaluable that it merits two chapters and an appendix all
-	to itself. <xref linkend="chap:mq"/> covers the
-	basics; <xref
-	  linkend="chap:mq-collab"/> discusses advanced topics;
-	and <xref linkend="chap:mqref"/> goes into detail on
-	each
-	command.</para>
-    </listitem></itemizedlist>
-
-  <para id="x_503">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.</para>
-  <itemizedlist>
-    <listitem><para id="x_504">In <xref linkend="sec:hgext:inotify"/>,
-	we'll discuss the possibility of <emphasis>huge</emphasis>
-	performance improvements using the <literal
-	  role="hg-ext">inotify</literal> extension.</para>
-    </listitem></itemizedlist>
-
-  <sect1 id="sec:hgext:inotify">
-    <title>Improve performance with the <literal
-	role="hg-ext">inotify</literal> extension</title>
-
-    <para id="x_505">Are you interested in having some of the most common
-      Mercurial operations run as much as a hundred times faster?
-      Read on!</para>
-
-    <para id="x_506">Mercurial has great performance under normal circumstances.
-      For example, when you run the <command role="hg-cmd">hg
-	status</command> 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 <command
-	role="hg-cmd">hg diff</command> command uses the status
-      machinery to avoid doing an expensive comparison operation on
-      files that obviously haven't changed.</para>
-
-    <para id="x_507">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 <command role="hg-cmd">hg
-	status</command>, 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.</para>
-
-    <para id="x_508">To put a number on the magnitude of this effect, I created a
-      repository containing 150,000 managed files.  I timed <command
-	role="hg-cmd">hg status</command> as taking ten seconds to
-      run, even when <emphasis>none</emphasis> of those files had been
-      modified.</para>
-
-    <para id="x_509">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
-      <literal>inotify</literal>.</para>
-
-    <para id="x_50a">Mercurial's <literal role="hg-ext">inotify</literal>
-      extension talks to the kernel's <literal>inotify</literal>
-      component to optimise <command role="hg-cmd">hg status</command>
-      commands.  The extension has two components.  A daemon sits in
-      the background and receives notifications from the
-      <literal>inotify</literal> subsystem.  It also listens for
-      connections from a regular Mercurial command.  The extension
-      modifies Mercurial's behavior 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.</para>
-
-    <para id="x_50b">Recall the ten seconds that I measured plain Mercurial as
-      taking to run <command role="hg-cmd">hg status</command> on a
-      150,000 file repository.  With the <literal
-	role="hg-ext">inotify</literal> extension enabled, the time
-      dropped to 0.1 seconds, a factor of <emphasis>one
-	hundred</emphasis> faster.</para>
-
-    <para id="x_50c">Before we continue, please pay attention to some
-      caveats.</para>
-    <itemizedlist>
-      <listitem><para id="x_50d">The <literal role="hg-ext">inotify</literal>
-	  extension is Linux-specific.  Because it interfaces directly
-	  to the Linux kernel's <literal>inotify</literal> subsystem,
-	  it does not work on other operating systems.</para>
-      </listitem>
-      <listitem><para id="x_50e">It should work on any Linux distribution that
-	  was released after early 2005.  Older distributions are
-	  likely to have a kernel that lacks
-	  <literal>inotify</literal>, or a version of
-	  <literal>glibc</literal> that does not have the necessary
-	  interfacing support.</para>
-      </listitem>
-      <listitem><para id="x_50f">Not all filesystems are suitable for use with
-	  the <literal role="hg-ext">inotify</literal> 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 <literal>inotify</literal> system has no way of
-	  knowing about changes made on another system.  Most local
-	  filesystems (e.g. ext3, XFS, ReiserFS) should work
-	  fine.</para>
-      </listitem></itemizedlist>
-
-    <para id="x_510">The <literal role="hg-ext">inotify</literal> 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!</para>
-
-    <para id="x_511">The extension currently comes in two parts: a set of patches
-      to the Mercurial source code, and a library of Python bindings
-      to the <literal>inotify</literal> subsystem.</para>
-    <note>
-      <para id="x_512">  There are <emphasis>two</emphasis> Python
-	<literal>inotify</literal> binding libraries.  One of them is
-	called <literal>pyinotify</literal>, and is packaged by some
-	Linux distributions as <literal>python-inotify</literal>.
-	This is <emphasis>not</emphasis> the one you'll need, as it is
-	too buggy and inefficient to be practical.</para>
-    </note>
-    <para id="x_513">To get going, it's best to already have a functioning copy
-      of Mercurial installed.</para>
-    <note>
-      <para id="x_514">  If you follow the instructions below, you'll be
-	<emphasis>replacing</emphasis> and overwriting any existing
-	installation of Mercurial that you might already have, using
-	the latest <quote>bleeding edge</quote> Mercurial code. Don't
-	say you weren't warned!</para>
-    </note>
-    <orderedlist>
-      <listitem><para id="x_515">Clone the Python <literal>inotify</literal>
-	  binding repository.  Build and install it.</para>
-	<programlisting>hg clone http://hg.kublai.com/python/inotify
-cd inotify
-python setup.py build --force
-sudo python setup.py install --skip-build</programlisting>
-      </listitem>
-      <listitem><para id="x_516">Clone the <filename
-	    class="directory">crew</filename> Mercurial repository.
-	  Clone the <literal role="hg-ext">inotify</literal> patch
-	  repository so that Mercurial Queues will be able to apply
-	  patches to your cope of the <filename
-	    class="directory">crew</filename> repository.</para>
-	<programlisting>hg clone http://hg.intevation.org/mercurial/crew
-hg clone crew inotify
-hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches</programlisting>
-      </listitem>
-      <listitem><para id="x_517">Make sure that you have the Mercurial Queues
-	  extension, <literal role="hg-ext">mq</literal>, enabled.  If
-	  you've never used MQ, read <xref
-	    linkend="sec:mq:start"/> to get started
-	  quickly.</para>
-      </listitem>
-      <listitem><para id="x_518">Go into the <filename
-	    class="directory">inotify</filename> repo, and apply all
-	  of the <literal role="hg-ext">inotify</literal> patches
-	  using the <option role="hg-ext-mq-cmd-qpush-opt">hg
-	    -a</option> option to the <command
-	    role="hg-ext-mq">qpush</command> command.</para>
-	<programlisting>cd inotify
-hg qpush -a</programlisting>
-      </listitem>
-      <listitem><para id="x_519">  If you get an error message from <command
-	    role="hg-ext-mq">qpush</command>, you should not continue.
-	  Instead, ask for help.</para>
-      </listitem>
-      <listitem><para id="x_51a">Build and install the patched version of
-	  Mercurial.</para>
-	<programlisting>python setup.py build --force
-sudo python setup.py install --skip-build</programlisting>
-      </listitem>
-    </orderedlist>
-    <para id="x_51b">Once you've build a suitably patched version of Mercurial,
-      all you need to do to enable the <literal
-	role="hg-ext">inotify</literal> extension is add an entry to
-      your <filename role="special">~/.hgrc</filename>.</para>
-    <programlisting>[extensions] inotify =</programlisting>
-    <para id="x_51c">When the <literal role="hg-ext">inotify</literal> 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.</para>
-
-    <para id="x_51d">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 <literal role="hg-ext">inotify</literal>
-      extension and run a few commands in different repositories,
-      you'll thus see a few <literal>hg</literal> processes sitting
-      around, waiting for updates from the kernel and queries from
-      Mercurial.</para>
-
-    <para id="x_51e">The first time you run a Mercurial command in a repository
-      when you have the <literal role="hg-ext">inotify</literal>
-      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, <emphasis>every</emphasis> 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 <literal role="hg-ext">inotify</literal> daemon makes
-      status operations almost instantaneous on repositories of all
-      sizes!</para>
-
-    <para id="x_51f">If you like, you can manually start a status daemon using
-      the <command role="hg-ext-inotify">inserve</command> command.
-      This gives you slightly finer control over how the daemon ought
-      to run.  This command will of course only be available when the
-      <literal role="hg-ext">inotify</literal> extension is
-      enabled.</para>
-
-    <para id="x_520">When you're using the <literal
-	role="hg-ext">inotify</literal> extension, you should notice
-      <emphasis>no difference at all</emphasis> in Mercurial's
-      behavior, 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.</para>
-
-  </sect1>
-  <sect1 id="sec:hgext:extdiff">
-    <title>Flexible diff support with the <literal
-	role="hg-ext">extdiff</literal> extension</title>
-
-    <para id="x_521">Mercurial's built-in <command role="hg-cmd">hg
-	diff</command> command outputs plaintext unified diffs.</para>
-
-    &interaction.extdiff.diff;
-
-    <para id="x_522">If you would like to use an external tool to display
-      modifications, you'll want to use the <literal
-	role="hg-ext">extdiff</literal> extension.  This will let you
-      use, for example, a graphical diff tool.</para>
-
-    <para id="x_523">The <literal role="hg-ext">extdiff</literal> extension is
-      bundled with Mercurial, so it's easy to set up.  In the <literal
-	role="rc-extensions">extensions</literal> section of your
-      <filename role="special">~/.hgrc</filename>, simply add a
-      one-line entry to enable the extension.</para>
-    <programlisting>[extensions]
-extdiff =</programlisting>
-    <para id="x_524">This introduces a command named <command
-	role="hg-ext-extdiff">extdiff</command>, which by default uses
-      your system's <command>diff</command> command to generate a
-      unified diff in the same form as the built-in <command
-	role="hg-cmd">hg diff</command> command.</para>
-    
-    &interaction.extdiff.extdiff;
-
-    <para id="x_525">The result won't be exactly the same as with the built-in
-      <command role="hg-cmd">hg diff</command> variations, because the
-      output of <command>diff</command> varies from one system to
-      another, even when passed the same options.</para>
-
-    <para id="x_526">As the <quote><literal>making snapshot</literal></quote>
-      lines of output above imply, the <command
-	role="hg-ext-extdiff">extdiff</command> 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 <command
-	role="hg-ext-extdiff">extdiff</command> 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.</para>
-
-    <para id="x_527">Snapshot directory names have the same base name as your
-      repository. If your repository path is <filename
-	class="directory">/quux/bar/foo</filename>, then <filename
-	class="directory">foo</filename> 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 <literal>a631aca1083f</literal>, the directory will be
-      named <filename class="directory">foo.a631aca1083f</filename>.
-      A snapshot of the working directory won't have a changeset ID
-      appended, so it would just be <filename
-	class="directory">foo</filename> in this example.  To see what
-      this looks like in practice, look again at the <command
-	role="hg-ext-extdiff">extdiff</command> example above.  Notice
-      that the diff has the snapshot directory names embedded in its
-      header.</para>
-
-    <para id="x_528">The <command role="hg-ext-extdiff">extdiff</command> command
-      accepts two important options. The <option
-	role="hg-ext-extdiff-cmd-extdiff-opt">hg -p</option> option
-      lets you choose a program to view differences with, instead of
-      <command>diff</command>.  With the <option
-	role="hg-ext-extdiff-cmd-extdiff-opt">hg -o</option> option,
-      you can change the options that <command
-	role="hg-ext-extdiff">extdiff</command> passes to the program
-      (by default, these options are
-      <quote><literal>-Npru</literal></quote>, which only make sense
-      if you're running <command>diff</command>).  In other respects,
-      the <command role="hg-ext-extdiff">extdiff</command> command
-      acts similarly to the built-in <command role="hg-cmd">hg
-	diff</command> command: you use the same option names, syntax,
-      and arguments to specify the revisions you want, the files you
-      want, and so on.</para>
-
-    <para id="x_529">As an example, here's how to run the normal system
-      <command>diff</command> command, getting it to generate context
-      diffs (using the <option role="cmd-opt-diff">-c</option> option)
-      instead of unified diffs, and five lines of context instead of
-      the default three (passing <literal>5</literal> as the argument
-      to the <option role="cmd-opt-diff">-C</option> option).</para>
-
-      &interaction.extdiff.extdiff-ctx;
-
-    <para id="x_52a">Launching a visual diff tool is just as easy.  Here's how to
-      launch the <command>kdiff3</command> viewer.</para>
-    <programlisting>hg extdiff -p kdiff3 -o</programlisting>
-
-    <para id="x_52b">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 <literal
-	role="hg-ext">mq</literal> extension and the
-      <command>interdiff</command> command, see <xref
-	linkend="mq-collab:tips:interdiff"/>.</para>
-
-    <sect2>
-      <title>Defining command aliases</title>
-
-      <para id="x_52c">It can be cumbersome to remember the options to both the
-	<command role="hg-ext-extdiff">extdiff</command> command and
-	the diff viewer you want to use, so the <literal
-	  role="hg-ext">extdiff</literal> extension lets you define
-	<emphasis>new</emphasis> commands that will invoke your diff
-	viewer with exactly the right options.</para>
-
-      <para id="x_52d">All you need to do is edit your <filename
-	  role="special">~/.hgrc</filename>, and add a section named
-	<literal role="rc-extdiff">extdiff</literal>.  Inside this
-	section, you can define multiple commands.  Here's how to add
-	a <literal>kdiff3</literal> command.  Once you've defined
-	this, you can type <quote><literal>hg kdiff3</literal></quote>
-	and the <literal role="hg-ext">extdiff</literal> extension
-	will run <command>kdiff3</command> for you.</para>
-      <programlisting>[extdiff]
-cmd.kdiff3 =</programlisting>
-      <para id="x_52e">If you leave the right hand side of the definition empty,
-	as above, the <literal role="hg-ext">extdiff</literal>
-	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
-	<quote><literal>hg wibble</literal></quote>, which runs
-	<command>kdiff3</command>.</para>
-      <programlisting>[extdiff]
- cmd.wibble = kdiff3</programlisting>
-
-      <para id="x_52f">You can also specify the default options that you want to
-	invoke your diff viewing program with.  The prefix to use is
-	<quote><literal>opts.</literal></quote>, followed by the name
-	of the command to which the options apply.  This example
-	defines a <quote><literal>hg vimdiff</literal></quote> command
-	that runs the <command>vim</command> editor's
-	<literal>DirDiff</literal> extension.</para>
-      <programlisting>[extdiff]
- cmd.vimdiff = vim
-opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'</programlisting>
-
-    </sect2>
-  </sect1>
-  <sect1 id="sec:hgext:transplant">
-    <title>Cherrypicking changes with the <literal
-	role="hg-ext">transplant</literal> extension</title>
-
-    <para id="x_530">Need to have a long chat with Brendan about this.</para>
-
-  </sect1>
-  <sect1 id="sec:hgext:patchbomb">
-    <title>Send changes via email with the <literal
-	role="hg-ext">patchbomb</literal> extension</title>
-
-    <para id="x_531">Many projects have a culture of <quote>change
-	review</quote>, 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.</para>
-
-    <para id="x_532">Mercurial makes it easy to send changes over email for
-      review or application, via its <literal
-	role="hg-ext">patchbomb</literal> extension.  The extension is
-      so named 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 <quote>bombing</quote> the
-      recipient's inbox, hence <quote>patchbomb</quote>.</para>
-
-    <para id="x_533">As usual, the basic configuration of the <literal
-	role="hg-ext">patchbomb</literal> extension takes just one or
-      two lines in your <filename role="special">
-	/.hgrc</filename>.</para>
-    <programlisting>[extensions]
-patchbomb =</programlisting>
-    <para id="x_534">Once you've enabled the extension, you will have a new
-      command available, named <command
-	role="hg-ext-patchbomb">email</command>.</para>
-
-    <para id="x_535">The safest and best way to invoke the <command
-	role="hg-ext-patchbomb">email</command> command is to
-      <emphasis>always</emphasis> run it first with the <option
-	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option.
-      This will show you what the command <emphasis>would</emphasis>
-      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 <option
-	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option
-      removed.</para>
-
-    <para id="x_536">The <command role="hg-ext-patchbomb">email</command> command
-      accepts the same kind of revision syntax as every other
-      Mercurial command.  For example, this command will send every
-      revision between 7 and <literal>tip</literal>, inclusive.</para>
-    <programlisting>hg email -n 7:tip</programlisting>
-    <para id="x_537">You can also specify a <emphasis>repository</emphasis> to
-      compare with.  If you provide a repository but no revisions, the
-      <command role="hg-ext-patchbomb">email</command> 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 <option
-	role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> option),
-      this will constrain the revisions sent.</para>
-
-    <para id="x_538">It's perfectly safe to run the <command
-	role="hg-ext-patchbomb">email</command> 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
-      <literal>readline</literal>-style editing capabilities when
-      entering those headers, too, which is useful.)</para>
-
-    <para id="x_539">When you are sending just one revision, the <command
-	role="hg-ext-patchbomb">email</command> command will by
-      default use the first line of the changeset description as the
-      subject of the single email message it sends.</para>
-
-    <para id="x_53a">If you send multiple revisions, the <command
-	role="hg-ext-patchbomb">email</command> 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.</para>
-
-    <sect2>
-      <title>Changing the behavior of patchbombs</title>
-
-      <para id="x_53b">Not every project has exactly the same conventions for
-	sending changes in email; the <literal
-	  role="hg-ext">patchbomb</literal> extension tries to
-	accommodate a number of variations through command line
-	options.</para>
-      <itemizedlist>
-	<listitem><para id="x_53c">You can write a subject for the introductory
-	    message on the command line using the <option
-	      role="hg-ext-patchbomb-cmd-email-opt">hg -s</option>
-	    option.  This takes one argument, the text of the subject
-	    to use.</para>
-	</listitem>
-	<listitem><para id="x_53d">To change the email address from which the
-	    messages originate, use the <option
-	      role="hg-ext-patchbomb-cmd-email-opt">hg -f</option>
-	    option.  This takes one argument, the email address to
-	    use.</para>
-	</listitem>
-	<listitem><para id="x_53e">The default behavior is to send unified diffs
-	    (see <xref linkend="sec:mq:patch"/> for a
-	    description of the
-	    format), one per message.  You can send a binary bundle
-	    instead with the <option
-	      role="hg-ext-patchbomb-cmd-email-opt">hg -b</option>
-	    option.</para>
-	</listitem>
-	<listitem><para id="x_53f">Unified diffs are normally prefaced with a
-	    metadata header.  You can omit this, and send unadorned
-	    diffs, with the <option
-	      role="hg-ext-patchbomb-cmd-email-opt">hg
-	      --plain</option> option.</para>
-	</listitem>
-	<listitem><para id="x_540">Diffs are normally sent <quote>inline</quote>,
-	    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 <option
-	      role="hg-ext-patchbomb-cmd-email-opt">hg -a</option>
-	    option.</para>
-	</listitem>
-	<listitem><para id="x_541">Instead of sending mail messages, you can
-	    write them to an <literal>mbox</literal>-format mail
-	    folder using the <option
-	      role="hg-ext-patchbomb-cmd-email-opt">hg -m</option>
-	    option.  That option takes one argument, the name of the
-	    file to write to.</para>
-	</listitem>
-	<listitem><para id="x_542">If you would like to add a
-	    <command>diffstat</command>-format summary to each patch,
-	    and one to the introductory message, use the <option
-	      role="hg-ext-patchbomb-cmd-email-opt">hg -d</option>
-	    option.  The <command>diffstat</command> 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.</para>
-	</listitem></itemizedlist>
-
-    </sect2>
-  </sect1>
-</chapter>
-
-<!--
-local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
-end:
--->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch13-mq-collab.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,518 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:mq-collab">
+  <?dbhtml filename="advanced-uses-of-mercurial-queues.html"?>
+  <title>Advanced uses of Mercurial Queues</title>
+
+  <para id="x_15d">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.</para>
+
+  <para id="x_15e">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.</para>
+
+  <para id="x_15f">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.</para>
+
+  <sect1>
+    <title>The problem of many targets</title>
+
+    <para id="x_160">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 <emphasis>compile</emphasis> correctly against,
+      typically, any other version.</para>
+
+    <para id="x_161">To maintain a driver, we have to keep a number of distinct
+      versions of Linux in mind.</para>
+    <itemizedlist>
+      <listitem><para id="x_162">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
+	  <quote>drive-by</quote> modifications to the driver as they
+	  develop and refine kernel subsystems.</para>
+      </listitem>
+      <listitem><para id="x_163">We also maintain a number of
+	  <quote>backports</quote> 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 <emphasis>backport</emphasis> 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.)</para>
+      </listitem>
+      <listitem><para id="x_164">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.</para>
+      </listitem></itemizedlist>
+
+    <sect2>
+      <title>Tempting approaches that don't work well</title>
+
+      <para id="x_165">There are two <quote>standard</quote> ways to maintain a
+	piece of software that has to target many different
+	environments.</para>
+
+      <para id="x_166">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 <quote>pristine</quote> 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.</para>
+
+      <para id="x_167">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
+	<quote>ifdefs</quote> 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.</para>
+
+      <para id="x_168">Neither of these approaches is well suited to a situation
+	where you don't <quote>own</quote> 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 <quote>my</quote> 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.</para>
+
+      <para id="x_169">These approaches have the added weakness of making it
+	difficult to generate well-formed patches to submit
+	upstream.</para>
+
+      <para id="x_16a">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.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Conditionally applying patches with guards</title>
+
+    <para id="x_16b">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 <quote>guards</quote>
+      (which originates with quilt's <literal>guards</literal>
+      command) that does just this.  To start off, let's create a
+      simple repository for experimenting in.</para>
+
+    &interaction.mq.guards.init;
+
+    <para id="x_16c">This gives us a tiny repository that contains two patches
+      that don't have any dependencies on each other, because they
+      touch different files.</para>
+
+    <para id="x_16d">The idea behind conditional application is that you can
+      <quote>tag</quote> a patch with a <emphasis>guard</emphasis>,
+      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.</para>
+
+    <para id="x_16e">A patch can have an arbitrary number of guards; each one is
+      <emphasis>positive</emphasis> (<quote>apply this patch if this
+	guard is selected</quote>) or <emphasis>negative</emphasis>
+      (<quote>skip this patch if this guard is selected</quote>).  A
+      patch with no guards is always applied.</para>
+
+  </sect1>
+  <sect1>
+    <title>Controlling the guards on a patch</title>
+
+    <para id="x_16f">The <command role="hg-ext-mq">qguard</command> 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.</para>
+
+      &interaction.mq.guards.qguard;
+
+    <para id="x_170">To set a positive guard on a patch, prefix the name of the
+      guard with a <quote><literal>+</literal></quote>.</para>
+
+      &interaction.mq.guards.qguard.pos;
+
+    <para id="x_171">To set a negative guard
+      on a patch, prefix the name of the guard with a
+      <quote><literal>-</literal></quote>.</para>
+
+    &interaction.mq.guards.qguard.neg;
+
+    <note>
+      <para id="x_172">  The <command role="hg-ext-mq">qguard</command> command
+	<emphasis>sets</emphasis> the guards on a patch; it doesn't
+	<emphasis>modify</emphasis> them.  What this means is that if
+	you run <command role="hg-cmd">hg qguard +a +b</command> on a
+	patch, then <command role="hg-cmd">hg qguard +c</command> on
+	the same patch, the <emphasis>only</emphasis> guard that will
+	be set on it afterwards is <literal>+c</literal>.</para>
+    </note>
+
+    <para id="x_173">Mercurial stores guards in the <filename
+	role="special">series</filename> 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 <command
+	role="hg-ext-mq">qguard</command> command if you don't want
+      to; it's okay to simply edit the <filename
+	role="special">series</filename> file.)</para>
+
+    &interaction.mq.guards.series;
+
+  </sect1>
+  <sect1>
+    <title>Selecting the guards to use</title>
+
+    <para id="x_174">The <command role="hg-ext-mq">qselect</command> 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 <command role="hg-ext-mq">qpush</command>.  It has
+      no other effect; in particular, it doesn't do anything to
+      patches that are already applied.</para>
+
+    <para id="x_175">With no arguments, the <command
+	role="hg-ext-mq">qselect</command> command lists the guards
+      currently in effect, one per line of output.  Each argument is
+      treated as the name of a guard to apply.</para>
+
+      &interaction.mq.guards.qselect.foo;
+
+    <para id="x_176">In case you're interested, the currently selected guards are
+      stored in the <filename role="special">guards</filename> file.</para>
+
+    &interaction.mq.guards.qselect.cat;
+
+    <para id="x_177">We can see the effect the selected guards have when we run
+      <command role="hg-ext-mq">qpush</command>.</para>
+
+    &interaction.mq.guards.qselect.qpush;
+
+    <para id="x_178">A guard cannot start with a
+      <quote><literal>+</literal></quote> or
+      <quote><literal>-</literal></quote> 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:</para>
+
+    &interaction.mq.guards.qselect.error;
+      
+    <para id="x_179">Changing the selected guards changes the patches that are
+      applied.</para>
+
+    &interaction.mq.guards.qselect.quux;
+
+    <para id="x_17a">You can see in the example below that negative guards take
+      precedence over positive guards.</para>
+
+    &interaction.mq.guards.qselect.foobar;
+
+  </sect1>
+  <sect1>
+    <title>MQ's rules for applying patches</title>
+
+    <para id="x_17b">The rules that MQ uses when deciding whether to apply a
+      patch are as follows.</para>
+    <itemizedlist>
+      <listitem><para id="x_17c">A patch that has no guards is always
+	  applied.</para>
+      </listitem>
+      <listitem><para id="x_17d">If the patch has any negative guard that matches
+	  any currently selected guard, the patch is skipped.</para>
+      </listitem>
+      <listitem><para id="x_17e">If the patch has any positive guard that matches
+	  any currently selected guard, the patch is applied.</para>
+      </listitem>
+      <listitem><para id="x_17f">If the patch has positive or negative guards,
+	  but none matches any currently selected guard, the patch is
+	  skipped.</para>
+      </listitem></itemizedlist>
+
+  </sect1>
+  <sect1>
+    <title>Trimming the work environment</title>
+
+    <para id="x_180">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.</para>
+
+    <para id="x_181">I then choose a <quote>base</quote> 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
+      <quote>shape</quote> 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.</para>
+
+    <para id="x_182">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.</para>
+
+  </sect1>
+  <sect1>
+    <title>Dividing up the <filename role="special">series</filename>
+      file</title>
+
+    <para id="x_183">I categorise the patches in the <filename
+	role="special">series</filename> 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.</para>
+
+    <para id="x_184">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.</para>
+    <itemizedlist>
+      <listitem><para id="x_185">The <quote>accepted</quote> 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 <quote>read only</quote> patches,
+	  present only to transform the tree into a similar state as
+	  it is in the upstream maintainer's repository.</para>
+      </listitem>
+      <listitem><para id="x_186">The <quote>rework</quote> group.  Patches that I
+	  have submitted, but that the upstream maintainer has
+	  requested modifications to before he will accept
+	  them.</para>
+      </listitem>
+      <listitem><para id="x_187">The <quote>pending</quote> group.  Patches that
+	  I have not yet submitted to the upstream maintainer, but
+	  which we have finished working on. These will be <quote>read
+	    only</quote> for a while.  If the upstream maintainer
+	  accepts them upon submission, I'll move them to the end of
+	  the <quote>accepted</quote> group.  If he requests that I
+	  modify any, I'll move them to the beginning of the
+	  <quote>rework</quote> group.</para>
+      </listitem>
+      <listitem><para id="x_188">The <quote>in progress</quote> group.  Patches
+	  that are actively being developed, and should not be
+	  submitted anywhere yet.</para>
+      </listitem>
+      <listitem><para id="x_189">The <quote>backport</quote> group.  Patches that
+	  adapt the source tree to older versions of the kernel
+	  tree.</para>
+      </listitem>
+      <listitem><para id="x_18a">The <quote>do not ship</quote> 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.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_18b">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 <filename
+	role="special">series</filename> file serves this
+      purpose.</para>
+
+    <para id="x_18c">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.</para>
+
+    <para id="x_18d">The <quote>backport</quote> and <quote>do not ship</quote>
+      patches float at the end of the <filename
+	role="special">series</filename> file.  The backport patches
+      must be applied on top of all other patches, and the <quote>do
+	not ship</quote> patches might as well stay out of harm's
+      way.</para>
+
+  </sect1>
+  <sect1>
+    <title>Maintaining the patch series</title>
+
+    <para id="x_18e">In my work, I use a number of guards to control which
+      patches are to be applied.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_18f"><quote>Accepted</quote> patches are guarded with
+	  <literal>accepted</literal>.  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.</para>
+      </listitem>
+      <listitem><para id="x_190">Patches that are <quote>finished</quote>, 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.</para>
+      </listitem>
+      <listitem><para id="x_191">Those patches that need reworking before being
+	  resubmitted are guarded with
+	  <literal>rework</literal>.</para>
+      </listitem>
+      <listitem><para id="x_192">For those patches that are still under
+	  development, I use <literal>devel</literal>.</para>
+      </listitem>
+      <listitem><para id="x_193">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 <literal>2.6.9</literal> guard.</para>
+      </listitem></itemizedlist>
+    <para id="x_194">This variety of guards gives me considerable flexibility in
+      determining 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.</para>
+
+    <sect2>
+      <title>The art of writing backport patches</title>
+
+      <para id="x_195">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.</para>
+
+      <para id="x_196">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
+	<quote>rat's nest</quote> effect of lots of
+	<literal>#ifdef</literal>s (hunks of source code that are only
+	used conditionally) in your code, don't introduce
+	version-dependent <literal>#ifdef</literal>s into the patches.
+	Instead, write several patches, each of which makes
+	unconditional changes, and control their application using
+	guards.</para>
+
+      <para id="x_197">There are two reasons to divide backport patches into a
+	distinct group, away from the <quote>regular</quote> patches
+	whose effects they modify. The first is that intermingling the
+	two makes it more difficult to use a tool like the <literal
+	  role="hg-ext">patchbomb</literal> 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
+	<emphasis>without</emphasis> the earlier backport patch
+	already being applied.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Useful tips for developing with MQ</title>
+
+    <sect2>
+      <title>Organising patches in directories</title>
+
+      <para id="x_198">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.</para>
+
+      <para id="x_199">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.</para>
+
+    </sect2>
+    <sect2 id="mq-collab:tips:interdiff">
+      <title>Viewing the history of a patch</title>
+
+      <para id="x_19a">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 <xref linkend="sec:mq:repo"/>.  If you do
+	so, you'll quickly
+	discover that using the <command role="hg-cmd">hg
+	  diff</command> 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.</para>
+
+      <para id="x_19b">However, you can use the <literal
+	  role="hg-ext">extdiff</literal> 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 <literal role="package">patchutils</literal>
+	<citation>web:patchutils</citation>.  This provides a command
+	named <command>interdiff</command>, 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.</para>
+
+      <para id="x_19c">You can enable the <literal
+	  role="hg-ext">extdiff</literal> extension in the usual way,
+	by adding a line to the <literal
+	  role="rc-extensions">extensions</literal> section of your
+	<filename role="special">~/.hgrc</filename>.</para>
+      <programlisting>[extensions]
+extdiff =</programlisting>
+      <para id="x_19d">The <command>interdiff</command> command expects to be
+	passed the names of two files, but the <literal
+	  role="hg-ext">extdiff</literal> 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</command> on each pair of files in
+	these two directories.  This program is available as <filename
+	  role="special">hg-interdiff</filename> in the <filename
+	  class="directory">examples</filename> directory of the
+	source code repository that accompanies this book. <!--
+	&example.hg-interdiff; --></para>
+
+      <para id="x_19e">With the <filename role="special">hg-interdiff</filename>
+	program in your shell's search path, you can run it as
+	follows, from inside an MQ patch directory:</para>
+      <programlisting>hg extdiff -p hg-interdiff -r A:B my-change.patch</programlisting>
+      <para id="x_19f">Since you'll probably want to use this long-winded command
+	a lot, you can get <literal role="hg-ext">hgext</literal> to
+	make it available as a normal Mercurial command, again by
+	editing your <filename
+	  role="special">~/.hgrc</filename>.</para>
+      <programlisting>[extdiff]
+cmd.interdiff = hg-interdiff</programlisting>
+      <para id="x_1a0">This directs <literal role="hg-ext">hgext</literal> to
+	make an <literal>interdiff</literal> command available, so you
+	can now shorten the previous invocation of <command
+	  role="hg-ext-extdiff">extdiff</command> to something a
+	little more wieldy.</para>
+      <programlisting>hg interdiff -r A:B my-change.patch</programlisting>
+
+      <note>
+	<para id="x_1a1">  The <command>interdiff</command> 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</command> may not produce useful
+	  output.</para>
+      </note>
+
+      <para id="x_1a2">The <literal role="hg-ext">extdiff</literal> extension is
+	useful for more than merely improving the presentation of MQ
+	patches.  To read more about it, go to <xref
+	  linkend="sec:hgext:extdiff"/>.</para>
+
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch14-hgext.xml	Thu May 07 21:07:35 2009 -0700
@@ -0,0 +1,554 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:hgext">
+  <?dbhtml filename="adding-functionality-with-extensions.html"?>
+  <title>Adding functionality with extensions</title>
+
+  <para id="x_4fe">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.</para>
+
+  <para id="x_4ff">However, Mercurial doesn't box you in with an inflexible
+    command set: you can add features to it as
+    <emphasis>extensions</emphasis> (sometimes known as
+    <emphasis>plugins</emphasis>).  We've already discussed a few of
+    these extensions in earlier chapters.</para>
+  <itemizedlist>
+    <listitem><para id="x_500"><xref linkend="sec:tour-merge:fetch"/>
+	covers the <literal role="hg-ext">fetch</literal> extension;
+	this combines pulling new changes and merging them with local
+	changes into a single command, <command
+	  role="hg-ext-fetch">fetch</command>.</para>
+    </listitem>
+    <listitem><para id="x_501">In <xref linkend="chap:hook"/>, we covered
+	several extensions that are useful for hook-related
+	functionality: <literal role="hg-ext">acl</literal> adds
+	access control lists; <literal
+	  role="hg-ext">bugzilla</literal> adds integration with the
+	Bugzilla bug tracking system; and <literal
+	  role="hg-ext">notify</literal> sends notification emails on
+	new changes.</para>
+    </listitem>
+    <listitem><para id="x_502">The Mercurial Queues patch management extension is
+	so invaluable that it merits two chapters and an appendix all
+	to itself. <xref linkend="chap:mq"/> covers the
+	basics; <xref
+	  linkend="chap:mq-collab"/> discusses advanced topics;
+	and <xref linkend="chap:mqref"/> goes into detail on
+	each
+	command.</para>
+    </listitem></itemizedlist>
+
+  <para id="x_503">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.</para>
+  <itemizedlist>
+    <listitem><para id="x_504">In <xref linkend="sec:hgext:inotify"/>,
+	we'll discuss the possibility of <emphasis>huge</emphasis>
+	performance improvements using the <literal
+	  role="hg-ext">inotify</literal> extension.</para>
+    </listitem></itemizedlist>
+
+  <sect1 id="sec:hgext:inotify">
+    <title>Improve performance with the <literal
+	role="hg-ext">inotify</literal> extension</title>
+
+    <para id="x_505">Are you interested in having some of the most common
+      Mercurial operations run as much as a hundred times faster?
+      Read on!</para>
+
+    <para id="x_506">Mercurial has great performance under normal circumstances.
+      For example, when you run the <command role="hg-cmd">hg
+	status</command> 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 <command
+	role="hg-cmd">hg diff</command> command uses the status
+      machinery to avoid doing an expensive comparison operation on
+      files that obviously haven't changed.</para>
+
+    <para id="x_507">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 <command role="hg-cmd">hg
+	status</command>, 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.</para>
+
+    <para id="x_508">To put a number on the magnitude of this effect, I created a
+      repository containing 150,000 managed files.  I timed <command
+	role="hg-cmd">hg status</command> as taking ten seconds to
+      run, even when <emphasis>none</emphasis> of those files had been
+      modified.</para>
+
+    <para id="x_509">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
+      <literal>inotify</literal>.</para>
+
+    <para id="x_50a">Mercurial's <literal role="hg-ext">inotify</literal>
+      extension talks to the kernel's <literal>inotify</literal>
+      component to optimise <command role="hg-cmd">hg status</command>
+      commands.  The extension has two components.  A daemon sits in
+      the background and receives notifications from the
+      <literal>inotify</literal> subsystem.  It also listens for
+      connections from a regular Mercurial command.  The extension
+      modifies Mercurial's behavior 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.</para>
+
+    <para id="x_50b">Recall the ten seconds that I measured plain Mercurial as
+      taking to run <command role="hg-cmd">hg status</command> on a
+      150,000 file repository.  With the <literal
+	role="hg-ext">inotify</literal> extension enabled, the time
+      dropped to 0.1 seconds, a factor of <emphasis>one
+	hundred</emphasis> faster.</para>
+
+    <para id="x_50c">Before we continue, please pay attention to some
+      caveats.</para>
+    <itemizedlist>
+      <listitem><para id="x_50d">The <literal role="hg-ext">inotify</literal>
+	  extension is Linux-specific.  Because it interfaces directly
+	  to the Linux kernel's <literal>inotify</literal> subsystem,
+	  it does not work on other operating systems.</para>
+      </listitem>
+      <listitem><para id="x_50e">It should work on any Linux distribution that
+	  was released after early 2005.  Older distributions are
+	  likely to have a kernel that lacks
+	  <literal>inotify</literal>, or a version of
+	  <literal>glibc</literal> that does not have the necessary
+	  interfacing support.</para>
+      </listitem>
+      <listitem><para id="x_50f">Not all filesystems are suitable for use with
+	  the <literal role="hg-ext">inotify</literal> 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 <literal>inotify</literal> system has no way of
+	  knowing about changes made on another system.  Most local
+	  filesystems (e.g. ext3, XFS, ReiserFS) should work
+	  fine.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_510">The <literal role="hg-ext">inotify</literal> 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!</para>
+
+    <para id="x_511">The extension currently comes in two parts: a set of patches
+      to the Mercurial source code, and a library of Python bindings
+      to the <literal>inotify</literal> subsystem.</para>
+    <note>
+      <para id="x_512">  There are <emphasis>two</emphasis> Python
+	<literal>inotify</literal> binding libraries.  One of them is
+	called <literal>pyinotify</literal>, and is packaged by some
+	Linux distributions as <literal>python-inotify</literal>.
+	This is <emphasis>not</emphasis> the one you'll need, as it is
+	too buggy and inefficient to be practical.</para>
+    </note>
+    <para id="x_513">To get going, it's best to already have a functioning copy
+      of Mercurial installed.</para>
+    <note>
+      <para id="x_514">  If you follow the instructions below, you'll be
+	<emphasis>replacing</emphasis> and overwriting any existing
+	installation of Mercurial that you might already have, using
+	the latest <quote>bleeding edge</quote> Mercurial code. Don't
+	say you weren't warned!</para>
+    </note>
+    <orderedlist>
+      <listitem><para id="x_515">Clone the Python <literal>inotify</literal>
+	  binding repository.  Build and install it.</para>
+	<programlisting>hg clone http://hg.kublai.com/python/inotify
+cd inotify
+python setup.py build --force
+sudo python setup.py install --skip-build</programlisting>
+      </listitem>
+      <listitem><para id="x_516">Clone the <filename
+	    class="directory">crew</filename> Mercurial repository.
+	  Clone the <literal role="hg-ext">inotify</literal> patch
+	  repository so that Mercurial Queues will be able to apply
+	  patches to your cope of the <filename
+	    class="directory">crew</filename> repository.</para>
+	<programlisting>hg clone http://hg.intevation.org/mercurial/crew
+hg clone crew inotify
+hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches</programlisting>
+      </listitem>
+      <listitem><para id="x_517">Make sure that you have the Mercurial Queues
+	  extension, <literal role="hg-ext">mq</literal>, enabled.  If
+	  you've never used MQ, read <xref
+	    linkend="sec:mq:start"/> to get started
+	  quickly.</para>
+      </listitem>
+      <listitem><para id="x_518">Go into the <filename
+	    class="directory">inotify</filename> repo, and apply all
+	  of the <literal role="hg-ext">inotify</literal> patches
+	  using the <option role="hg-ext-mq-cmd-qpush-opt">hg
+	    -a</option> option to the <command
+	    role="hg-ext-mq">qpush</command> command.</para>
+	<programlisting>cd inotify
+hg qpush -a</programlisting>
+      </listitem>
+      <listitem><para id="x_519">  If you get an error message from <command
+	    role="hg-ext-mq">qpush</command>, you should not continue.
+	  Instead, ask for help.</para>
+      </listitem>
+      <listitem><para id="x_51a">Build and install the patched version of
+	  Mercurial.</para>
+	<programlisting>python setup.py build --force
+sudo python setup.py install --skip-build</programlisting>
+      </listitem>
+    </orderedlist>
+    <para id="x_51b">Once you've build a suitably patched version of Mercurial,
+      all you need to do to enable the <literal
+	role="hg-ext">inotify</literal> extension is add an entry to
+      your <filename role="special">~/.hgrc</filename>.</para>
+    <programlisting>[extensions] inotify =</programlisting>
+    <para id="x_51c">When the <literal role="hg-ext">inotify</literal> 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.</para>
+
+    <para id="x_51d">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 <literal role="hg-ext">inotify</literal>
+      extension and run a few commands in different repositories,
+      you'll thus see a few <literal>hg</literal> processes sitting
+      around, waiting for updates from the kernel and queries from
+      Mercurial.</para>
+
+    <para id="x_51e">The first time you run a Mercurial command in a repository
+      when you have the <literal role="hg-ext">inotify</literal>
+      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, <emphasis>every</emphasis> 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 <literal role="hg-ext">inotify</literal> daemon makes
+      status operations almost instantaneous on repositories of all
+      sizes!</para>
+
+    <para id="x_51f">If you like, you can manually start a status daemon using
+      the <command role="hg-ext-inotify">inserve</command> command.
+      This gives you slightly finer control over how the daemon ought
+      to run.  This command will of course only be available when the
+      <literal role="hg-ext">inotify</literal> extension is
+      enabled.</para>
+
+    <para id="x_520">When you're using the <literal
+	role="hg-ext">inotify</literal> extension, you should notice
+      <emphasis>no difference at all</emphasis> in Mercurial's
+      behavior, 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.</para>
+
+  </sect1>
+  <sect1 id="sec:hgext:extdiff">
+    <title>Flexible diff support with the <literal
+	role="hg-ext">extdiff</literal> extension</title>
+
+    <para id="x_521">Mercurial's built-in <command role="hg-cmd">hg
+	diff</command> command outputs plaintext unified diffs.</para>
+
+    &interaction.extdiff.diff;
+
+    <para id="x_522">If you would like to use an external tool to display
+      modifications, you'll want to use the <literal
+	role="hg-ext">extdiff</literal> extension.  This will let you
+      use, for example, a graphical diff tool.</para>
+
+    <para id="x_523">The <literal role="hg-ext">extdiff</literal> extension is
+      bundled with Mercurial, so it's easy to set up.  In the <literal
+	role="rc-extensions">extensions</literal> section of your
+      <filename role="special">~/.hgrc</filename>, simply add a
+      one-line entry to enable the extension.</para>
+    <programlisting>[extensions]
+extdiff =</programlisting>
+    <para id="x_524">This introduces a command named <command
+	role="hg-ext-extdiff">extdiff</command>, which by default uses
+      your system's <command>diff</command> command to generate a
+      unified diff in the same form as the built-in <command
+	role="hg-cmd">hg diff</command> command.</para>
+    
+    &interaction.extdiff.extdiff;
+
+    <para id="x_525">The result won't be exactly the same as with the built-in
+      <command role="hg-cmd">hg diff</command> variations, because the
+      output of <command>diff</command> varies from one system to
+      another, even when passed the same options.</para>
+
+    <para id="x_526">As the <quote><literal>making snapshot</literal></quote>
+      lines of output above imply, the <command
+	role="hg-ext-extdiff">extdiff</command> 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 <command
+	role="hg-ext-extdiff">extdiff</command> 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.</para>
+
+    <para id="x_527">Snapshot directory names have the same base name as your
+      repository. If your repository path is <filename
+	class="directory">/quux/bar/foo</filename>, then <filename
+	class="directory">foo</filename> 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 <literal>a631aca1083f</literal>, the directory will be
+      named <filename class="directory">foo.a631aca1083f</filename>.
+      A snapshot of the working directory won't have a changeset ID
+      appended, so it would just be <filename
+	class="directory">foo</filename> in this example.  To see what
+      this looks like in practice, look again at the <command
+	role="hg-ext-extdiff">extdiff</command> example above.  Notice
+      that the diff has the snapshot directory names embedded in its
+      header.</para>
+
+    <para id="x_528">The <command role="hg-ext-extdiff">extdiff</command> command
+      accepts two important options. The <option
+	role="hg-ext-extdiff-cmd-extdiff-opt">hg -p</option> option
+      lets you choose a program to view differences with, instead of
+      <command>diff</command>.  With the <option
+	role="hg-ext-extdiff-cmd-extdiff-opt">hg -o</option> option,
+      you can change the options that <command
+	role="hg-ext-extdiff">extdiff</command> passes to the program
+      (by default, these options are
+      <quote><literal>-Npru</literal></quote>, which only make sense
+      if you're running <command>diff</command>).  In other respects,
+      the <command role="hg-ext-extdiff">extdiff</command> command
+      acts similarly to the built-in <command role="hg-cmd">hg
+	diff</command> command: you use the same option names, syntax,
+      and arguments to specify the revisions you want, the files you
+      want, and so on.</para>
+
+    <para id="x_529">As an example, here's how to run the normal system
+      <command>diff</command> command, getting it to generate context
+      diffs (using the <option role="cmd-opt-diff">-c</option> option)
+      instead of unified diffs, and five lines of context instead of
+      the default three (passing <literal>5</literal> as the argument
+      to the <option role="cmd-opt-diff">-C</option> option).</para>
+
+      &interaction.extdiff.extdiff-ctx;
+
+    <para id="x_52a">Launching a visual diff tool is just as easy.  Here's how to
+      launch the <command>kdiff3</command> viewer.</para>
+    <programlisting>hg extdiff -p kdiff3 -o</programlisting>
+
+    <para id="x_52b">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 <literal
+	role="hg-ext">mq</literal> extension and the
+      <command>interdiff</command> command, see <xref
+	linkend="mq-collab:tips:interdiff"/>.</para>
+
+    <sect2>
+      <title>Defining command aliases</title>
+
+      <para id="x_52c">It can be cumbersome to remember the options to both the
+	<command role="hg-ext-extdiff">extdiff</command> command and
+	the diff viewer you want to use, so the <literal
+	  role="hg-ext">extdiff</literal> extension lets you define
+	<emphasis>new</emphasis> commands that will invoke your diff
+	viewer with exactly the right options.</para>
+
+      <para id="x_52d">All you need to do is edit your <filename
+	  role="special">~/.hgrc</filename>, and add a section named
+	<literal role="rc-extdiff">extdiff</literal>.  Inside this
+	section, you can define multiple commands.  Here's how to add
+	a <literal>kdiff3</literal> command.  Once you've defined
+	this, you can type <quote><literal>hg kdiff3</literal></quote>
+	and the <literal role="hg-ext">extdiff</literal> extension
+	will run <command>kdiff3</command> for you.</para>
+      <programlisting>[extdiff]
+cmd.kdiff3 =</programlisting>
+      <para id="x_52e">If you leave the right hand side of the definition empty,
+	as above, the <literal role="hg-ext">extdiff</literal>
+	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
+	<quote><literal>hg wibble</literal></quote>, which runs
+	<command>kdiff3</command>.</para>
+      <programlisting>[extdiff]
+ cmd.wibble = kdiff3</programlisting>
+
+      <para id="x_52f">You can also specify the default options that you want to
+	invoke your diff viewing program with.  The prefix to use is
+	<quote><literal>opts.</literal></quote>, followed by the name
+	of the command to which the options apply.  This example
+	defines a <quote><literal>hg vimdiff</literal></quote> command
+	that runs the <command>vim</command> editor's
+	<literal>DirDiff</literal> extension.</para>
+      <programlisting>[extdiff]
+ cmd.vimdiff = vim
+opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'</programlisting>
+
+    </sect2>
+  </sect1>
+  <sect1 id="sec:hgext:transplant">
+    <title>Cherrypicking changes with the <literal
+	role="hg-ext">transplant</literal> extension</title>
+
+    <para id="x_530">Need to have a long chat with Brendan about this.</para>
+
+  </sect1>
+  <sect1 id="sec:hgext:patchbomb">
+    <title>Send changes via email with the <literal
+	role="hg-ext">patchbomb</literal> extension</title>
+
+    <para id="x_531">Many projects have a culture of <quote>change
+	review</quote>, 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.</para>
+
+    <para id="x_532">Mercurial makes it easy to send changes over email for
+      review or application, via its <literal
+	role="hg-ext">patchbomb</literal> extension.  The extension is
+      so named 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 <quote>bombing</quote> the
+      recipient's inbox, hence <quote>patchbomb</quote>.</para>
+
+    <para id="x_533">As usual, the basic configuration of the <literal
+	role="hg-ext">patchbomb</literal> extension takes just one or
+      two lines in your <filename role="special">
+	/.hgrc</filename>.</para>
+    <programlisting>[extensions]
+patchbomb =</programlisting>
+    <para id="x_534">Once you've enabled the extension, you will have a new
+      command available, named <command
+	role="hg-ext-patchbomb">email</command>.</para>
+
+    <para id="x_535">The safest and best way to invoke the <command
+	role="hg-ext-patchbomb">email</command> command is to
+      <emphasis>always</emphasis> run it first with the <option
+	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option.
+      This will show you what the command <emphasis>would</emphasis>
+      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 <option
+	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option
+      removed.</para>
+
+    <para id="x_536">The <command role="hg-ext-patchbomb">email</command> command
+      accepts the same kind of revision syntax as every other
+      Mercurial command.  For example, this command will send every
+      revision between 7 and <literal>tip</literal>, inclusive.</para>
+    <programlisting>hg email -n 7:tip</programlisting>
+    <para id="x_537">You can also specify a <emphasis>repository</emphasis> to
+      compare with.  If you provide a repository but no revisions, the
+      <command role="hg-ext-patchbomb">email</command> 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 <option
+	role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> option),
+      this will constrain the revisions sent.</para>
+
+    <para id="x_538">It's perfectly safe to run the <command
+	role="hg-ext-patchbomb">email</command> 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
+      <literal>readline</literal>-style editing capabilities when
+      entering those headers, too, which is useful.)</para>
+
+    <para id="x_539">When you are sending just one revision, the <command
+	role="hg-ext-patchbomb">email</command> command will by
+      default use the first line of the changeset description as the
+      subject of the single email message it sends.</para>
+
+    <para id="x_53a">If you send multiple revisions, the <command
+	role="hg-ext-patchbomb">email</command> 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.</para>
+
+    <sect2>
+      <title>Changing the behavior of patchbombs</title>
+
+      <para id="x_53b">Not every project has exactly the same conventions for
+	sending changes in email; the <literal
+	  role="hg-ext">patchbomb</literal> extension tries to
+	accommodate a number of variations through command line
+	options.</para>
+      <itemizedlist>
+	<listitem><para id="x_53c">You can write a subject for the introductory
+	    message on the command line using the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -s</option>
+	    option.  This takes one argument, the text of the subject
+	    to use.</para>
+	</listitem>
+	<listitem><para id="x_53d">To change the email address from which the
+	    messages originate, use the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -f</option>
+	    option.  This takes one argument, the email address to
+	    use.</para>
+	</listitem>
+	<listitem><para id="x_53e">The default behavior is to send unified diffs
+	    (see <xref linkend="sec:mq:patch"/> for a
+	    description of the
+	    format), one per message.  You can send a binary bundle
+	    instead with the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -b</option>
+	    option.</para>
+	</listitem>
+	<listitem><para id="x_53f">Unified diffs are normally prefaced with a
+	    metadata header.  You can omit this, and send unadorned
+	    diffs, with the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg
+	      --plain</option> option.</para>
+	</listitem>
+	<listitem><para id="x_540">Diffs are normally sent <quote>inline</quote>,
+	    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 <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -a</option>
+	    option.</para>
+	</listitem>
+	<listitem><para id="x_541">Instead of sending mail messages, you can
+	    write them to an <literal>mbox</literal>-format mail
+	    folder using the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -m</option>
+	    option.  That option takes one argument, the name of the
+	    file to write to.</para>
+	</listitem>
+	<listitem><para id="x_542">If you would like to add a
+	    <command>diffstat</command>-format summary to each patch,
+	    and one to the introductory message, use the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -d</option>
+	    option.  The <command>diffstat</command> 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.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->