# HG changeset patch
# User Frédéric Bouquet <youshe.jaalon@gmail.com>
# Date 1252505256 -7200
# Node ID f0110009e9469d8b188347354267d7633695a31c
# Parent  c075fb0481c07f1f8ed6502cc51c50296db5cebe
french translation : sync with original files (en/ch05 to en/ch14 and appD)

diff -r c075fb0481c0 -r f0110009e946 fr/appD-license.xml
--- a/fr/appD-license.xml	Wed Sep 09 15:25:09 2009 +0200
+++ b/fr/appD-license.xml	Wed Sep 09 16:07:36 2009 +0200
@@ -1,185 +1,179 @@
 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter>
-<title>Open Publication License</title>
-<para>\label{cha:opl}</para>
+<appendix id="cha:opl">
+  <?dbhtml filename="open-publication-license.html"?>
+  <title>Open Publication License</title>
 
-<para>Version 1.0, 8 June 1999</para>
+  <para id="x_638">Version 1.0, 8 June 1999</para>
 
-<sect1>
-<title>Requirements on both unmodified and modified versions</title>
+  <sect1>
+    <title>Requirements on both unmodified and modified
+      versions</title>
 
-<para>The Open Publication works may be reproduced and distributed in whole
-or in part, in any medium physical or electronic, provided that the
-terms of this license are adhered to, and that this license or an
-incorporation of it by reference (with any options elected by the
-author(s) and/or publisher) is displayed in the reproduction.</para>
+    <para id="x_639">The Open Publication works may be reproduced and distributed
+      in whole or in part, in any medium physical or electronic,
+      provided that the terms of this license are adhered to, and that
+      this license or an incorporation of it by reference (with any
+      options elected by the author(s) and/or publisher) is displayed
+      in the reproduction.</para>
 
-<para>Proper form for an incorporation by reference is as follows:</para>
+    <para id="x_63a">Proper form for an incorporation by reference is as
+      follows:</para>
 
-<blockquote>
-<para>  Copyright (c) <emphasis>year</emphasis> by <emphasis>author's name or designee</emphasis>. This
-  material may be distributed only subject to the terms and conditions
-  set forth in the Open Publication License, v<emphasis>x.y</emphasis> or later (the
-  latest version is presently available at
-  <ulink url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).</para>
-</blockquote>
+    <blockquote>
+      <para id="x_63b">  Copyright (c) <emphasis>year</emphasis> by
+	<emphasis>author's name or designee</emphasis>. This material
+	may be distributed only subject to the terms and conditions
+	set forth in the Open Publication License,
+	v<emphasis>x.y</emphasis> or later (the latest version is
+	presently available at <ulink
+	  url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).</para>
+    </blockquote>
 
-<para>The reference must be immediately followed with any options elected by
-the author(s) and/or publisher of the document (see
-section <xref linkend="sec:opl:options"/>).</para>
+    <para id="x_63c">The reference must be immediately followed with any options
+      elected by the author(s) and/or publisher of the document (see
+      <xref linkend="sec:opl:options"/>).</para>
 
-<para>Commercial redistribution of Open Publication-licensed material is
-permitted.</para>
+    <para id="x_63d">Commercial redistribution of Open Publication-licensed
+      material is permitted.</para>
 
-<para>Any publication in standard (paper) book form shall require the
-citation of the original publisher and author. The publisher and
-author's names shall appear on all outer surfaces of the book. On all
-outer surfaces of the book the original publisher's name shall be as
-large as the title of the work and cited as possessive with respect to
-the title.</para>
+    <para id="x_63e">Any publication in standard (paper) book form shall require
+      the citation of the original publisher and author. The publisher
+      and author's names shall appear on all outer surfaces of the
+      book. On all outer surfaces of the book the original publisher's
+      name shall be as large as the title of the work and cited as
+      possessive with respect to the title.</para>
 
-</sect1>
-<sect1>
-<title>Copyright</title>
+  </sect1>
+  <sect1>
+    <title>Copyright</title>
 
-<para>The copyright to each Open Publication is owned by its author(s) or
-designee.
-</para>
+    <para id="x_63f">The copyright to each Open Publication is owned by its
+      author(s) or designee.</para>
 
-</sect1>
-<sect1>
-<title>Scope of license</title>
+  </sect1>
+  <sect1>
+    <title>Scope of license</title>
 
-<para>The following license terms apply to all Open Publication works,
-unless otherwise explicitly stated in the document.
-</para>
+    <para id="x_640">The following license terms apply to all Open Publication
+      works, unless otherwise explicitly stated in the
+      document.</para>
 
-<para>Mere aggregation of Open Publication works or a portion of an Open
-Publication work with other works or programs on the same media shall
-not cause this license to apply to those other works. The aggregate
-work shall contain a notice specifying the inclusion of the Open
-Publication material and appropriate copyright notice.
-</para>
+    <para id="x_641">Mere aggregation of Open Publication works or a portion of
+      an Open Publication work with other works or programs on the
+      same media shall not cause this license to apply to those other
+      works. The aggregate work shall contain a notice specifying the
+      inclusion of the Open Publication material and appropriate
+      copyright notice.</para>
 
-<para><emphasis role="bold">Severability</emphasis>. If any part of this license is found to be
-unenforceable in any jurisdiction, the remaining portions of the
-license remain in force.
-</para>
+    <para id="x_642"><emphasis role="bold">Severability</emphasis>. If any part
+      of this license is found to be unenforceable in any
+      jurisdiction, the remaining portions of the license remain in
+      force.</para>
 
-<para><emphasis role="bold">No warranty</emphasis>. Open Publication works are licensed and provided
-<quote>as is</quote> without warranty of any kind, express or implied, including,
-but not limited to, the implied warranties of merchantability and
-fitness for a particular purpose or a warranty of non-infringement.
-</para>
+    <para id="x_643"><emphasis role="bold">No warranty</emphasis>. Open
+      Publication works are licensed and provided <quote>as is</quote>
+      without warranty of any kind, express or implied, including, but
+      not limited to, the implied warranties of merchantability and
+      fitness for a particular purpose or a warranty of
+      non-infringement.</para>
 
-</sect1>
-<sect1>
-<title>Requirements on modified works</title>
+  </sect1>
+  <sect1>
+    <title>Requirements on modified works</title>
 
-<para>All modified versions of documents covered by this license, including
-translations, anthologies, compilations and partial documents, must
-meet the following requirements:
-</para>
+    <para id="x_644">All modified versions of documents covered by this license,
+      including translations, anthologies, compilations and partial
+      documents, must meet the following requirements:</para>
 
-<orderedlist>
-<listitem><para>The modified version must be labeled as such.
-</para>
-</listitem>
-<listitem><para>The person making the modifications must be identified and the
-  modifications dated.
-</para>
-</listitem>
-<listitem><para>Acknowledgement of the original author and publisher if
-  applicable must be retained according to normal academic citation
-  practices.
-</para>
-</listitem>
-<listitem><para>The location of the original unmodified document must be
-  identified.
-</para>
-</listitem>
-<listitem><para>The original author's (or authors') name(s) may not be used to
-  assert or imply endorsement of the resulting document without the
-  original author's (or authors') permission.
-</para>
-</listitem></orderedlist>
+    <orderedlist>
+      <listitem><para id="x_645">The modified version must be labeled as
+	  such.</para>
+      </listitem>
+      <listitem><para id="x_646">The person making the modifications must be
+	  identified and the modifications dated.</para>
+      </listitem>
+      <listitem><para id="x_647">Acknowledgement of the original author and
+	  publisher if applicable must be retained according to normal
+	  academic citation practices.</para>
+      </listitem>
+      <listitem><para id="x_648">The location of the original unmodified document
+	  must be identified.</para>
+      </listitem>
+      <listitem><para id="x_649">The original author's (or authors') name(s) may
+	  not be used to assert or imply endorsement of the resulting
+	  document without the original author's (or authors')
+	  permission.</para>
+      </listitem></orderedlist>
 
-</sect1>
-<sect1>
-<title>Good-practice recommendations</title>
+  </sect1>
+  <sect1>
+    <title>Good-practice recommendations</title>
 
-<para>In addition to the requirements of this license, it is requested from
-and strongly recommended of redistributors that:
-</para>
+    <para id="x_64a">In addition to the requirements of this license, it is
+      requested from and strongly recommended of redistributors
+      that:</para>
 
-<orderedlist>
-<listitem><para>If you are distributing Open Publication works on hardcopy or
-  CD-ROM, you provide email notification to the authors of your intent
-  to redistribute at least thirty days before your manuscript or media
-  freeze, to give the authors time to provide updated documents. This
-  notification should describe modifications, if any, made to the
-  document.
-</para>
-</listitem>
-<listitem><para>All substantive modifications (including deletions) be either
-  clearly marked up in the document or else described in an attachment
-  to the document.
-</para>
-</listitem>
-<listitem><para>Finally, while it is not mandatory under this license, it is
-  considered good form to offer a free copy of any hardcopy and CD-ROM
-  expression of an Open Publication-licensed work to its author(s).
-</para>
-</listitem></orderedlist>
+    <orderedlist>
+      <listitem><para id="x_64b">If you are distributing Open Publication works
+	  on hardcopy or CD-ROM, you provide email notification to the
+	  authors of your intent to redistribute at least thirty days
+	  before your manuscript or media freeze, to give the authors
+	  time to provide updated documents. This notification should
+	  describe modifications, if any, made to the document.</para>
+      </listitem>
+      <listitem><para id="x_64c">All substantive modifications (including
+	  deletions) be either clearly marked up in the document or
+	  else described in an attachment to the document.</para>
+      </listitem>
+      <listitem><para id="x_64d">Finally, while it is not mandatory under this
+	  license, it is considered good form to offer a free copy of
+	  any hardcopy and CD-ROM expression of an Open
+	  Publication-licensed work to its author(s).</para>
+      </listitem></orderedlist>
 
-</sect1>
-<sect1>
-<title>License options</title>
-<para>\label{sec:opl:options}
-</para>
+  </sect1>
+  <sect1 id="sec:opl:options">
+    <title>License options</title>
 
-<para>The author(s) and/or publisher of an Open Publication-licensed
-document may elect certain options by appending language to the
-reference to or copy of the license. These options are considered part
-of the license instance and must be included with the license (or its
-incorporation by reference) in derived works.
-</para>
+    <para id="x_64e">The author(s) and/or publisher of an Open
+      Publication-licensed document may elect certain options by
+      appending language to the reference to or copy of the license.
+      These options are considered part of the license instance and
+      must be included with the license (or its incorporation by
+      reference) in derived works.</para>
 
-<orderedlist>
-<listitem><para>To prohibit distribution of substantively modified versions
-  without the explicit permission of the author(s). <quote>Substantive
-  modification</quote> is defined as a change to the semantic content of the
-  document, and excludes mere changes in format or typographical
-  corrections.
-</para>
-</listitem>
-<listitem><para>  To accomplish this, add the phrase <quote>Distribution of substantively
-  modified versions of this document is prohibited without the
-  explicit permission of the copyright holder.</quote> to the license
-  reference or copy.
-</para>
-</listitem>
-</para>
-</listitem>
-<listitem><para>To prohibit any publication of this work or derivative works in
-  whole or in part in standard (paper) book form for commercial
-  purposes is prohibited unless prior permission is obtained from the
-  copyright holder.
-</para>
-</listitem>
-<listitem><para>  To accomplish this, add the phrase <quote>Distribution of the work or
-  derivative of the work in any standard (paper) book form is
-  prohibited unless prior permission is obtained from the copyright
-  holder.</quote> to the license reference or copy.
-</para>
-</listitem></orderedlist>
+    <orderedlist>
+      <listitem><para id="x_64f">To prohibit distribution of substantively
+	  modified versions without the explicit permission of the
+	  author(s). <quote>Substantive modification</quote> is
+	  defined as a change to the semantic content of the document,
+	  and excludes mere changes in format or typographical
+	  corrections.</para>
+      </listitem>
+      <listitem><para id="x_650">  To accomplish this, add the phrase
+	  <quote>Distribution of substantively modified versions of
+	    this document is prohibited without the explicit
+	    permission of the copyright holder.</quote> to the license
+	  reference or copy.</para>
+      </listitem>
+      <listitem><para id="x_651">To prohibit any publication of this work or
+	  derivative works in whole or in part in standard (paper)
+	  book form for commercial purposes is prohibited unless prior
+	  permission is obtained from the copyright holder.</para>
+      </listitem>
+      <listitem><para id="x_652">To accomplish this, add the phrase
+	  <quote>Distribution of the work or derivative of the work in
+	    any standard (paper) book form is prohibited unless prior
+	    permission is obtained from the copyright holder.</quote>
+	  to the license reference or copy.</para>
+      </listitem></orderedlist>
 
-</sect1>
-</chapter>
+  </sect1>
+</appendix>
 
 <!--
 local variables: 
-sgml-parent-document: ("00book.xml" "book" "chapter")
+sgml-parent-document: ("00book.xml" "book" "appendix")
 end:
--->
\ No newline at end of file
+-->
diff -r c075fb0481c0 -r f0110009e946 fr/ch05-daily.xml
--- a/fr/ch05-daily.xml	Wed Sep 09 15:25:09 2009 +0200
+++ b/fr/ch05-daily.xml	Wed Sep 09 16:07:36 2009 +0200
@@ -1,474 +1,840 @@
 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter>
-<title>Mercurial in daily use</title>
-<para>\label{chap:daily}</para>
-
-<sect1>
-<title>Telling Mercurial which files to track</title>
-
-<para>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>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>.
-<!-- &interaction.daily.files.add; --></para>
-
-<para>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 <command role="hg-cmd">hg status</command> only tells you about
-<quote>interesting</quote> files&emdash;those that you have modified or told Mercurial
-to do something with&emdash;by default.  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>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>A useful behaviour 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>.
-<!-- &interaction.daily.files.add-dir; -->
-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>a</filename> in the earlier example.</para>
-
-<para>What's going on is that in the former case, we explicitly named the
-file to add on the command line, so the assumption that Mercurial
-makes in such cases is that you know what you were doing, and it
-doesn't print any output.</para>
-
-<para>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 behaviour is common to most Mercurial commands.</para>
-
-</sect2>
-<sect2>
-<title>Aside: Mercurial tracks files, not directories</title>
-
-<para>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>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>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 in
-figure <xref linkend="ex:daily:hidden"/>.
-</para>
-
-<informalfigure>
-<para>  <!-- &interaction.daily.files.hidden; -->
-  <caption><para>Simulating an empty directory using a hidden file</para></caption>
-  \label{ex:daily:hidden}
-</para>
-</informalfigure>
-
-<para>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>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.  A removed file is represented in the output of
-<command role="hg-cmd">hg status</command> with a <quote><literal>R</literal></quote>.
-<!-- &interaction.daily.files.remove; -->
-</para>
-
-<para>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>It is important to understand that removing a file has only two
-effects.
-</para>
-<itemizedlist>
-<listitem><para>It removes the current version of the file from the working
-  directory.
-</para>
-</listitem>
-<listitem><para>It stops Mercurial from tracking changes to the file, from the
-  time of the next commit.
-</para>
-</listitem></itemizedlist>
-<para>Removing a file <emphasis>does not</emphasis> in any way alter the <emphasis>history</emphasis> of
-the file.
-</para>
-
-<para>If you update the working directory to a changeset in which a file
-that you have removed was still tracked, it 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>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.
-<!-- &interaction.daily.files.missing; -->
-</para>
-
-<para>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.
-<!-- &interaction.daily.files.remove-after; -->
-</para>
-
-<para>On the other hand, if you deleted the missing file by accident, use
-<command role="hg-cmd">hg revert <emphasis>filename</emphasis></command> to recover the file.  It will
-reappear, in unmodified form.
-<!-- &interaction.daily.files.recover-missing; -->
-</para>
-
-<para>\subsection{Aside: why tell Mercurial explicitly to
-  remove a file?}
-</para>
-
-<para>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>
-
-<para>\subsection{Useful shorthand&emdash;adding and removing files
-  in one step}
-</para>
-
-<para>Mercurial offers a combination command, <command role="hg-cmd">hg addremove</command>, that adds
-untracked files and marks missing files as removed.
-<!-- &interaction.daily.files.addremove; -->
-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.
-<!-- &interaction.daily.files.commit-addremove; -->
-</para>
-
-</sect2>
-</sect1>
-<sect1>
-<title>Copying files</title>
-
-<para>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>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.
-<!-- &interaction.daily.copy.init; -->
-We need to do some work in parallel, so that we'll have something to
-merge.  So let's clone our repository.
-<!-- &interaction.daily.copy.clone; -->
-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.
-<!-- &interaction.daily.copy.copy; -->
-</para>
-
-<para>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.
-<!-- &interaction.daily.copy.status; -->
-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>.
-<!-- &interaction.daily.copy.status-copy; -->
-</para>
-
-<para>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.
-<!-- &interaction.daily.copy.other; -->
-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>.
-<!-- &interaction.daily.copy.merge; -->
-</para>
-
-</sect2>
-<sect2>
-<title>Why should changes follow copies?</title>
-<para>\label{sec:daily:why-copy}
-</para>
-
-<para>This behaviour, of changes to a file propagating out to copies of the
-file, might seem esoteric, but in most cases it's highly desirable.
-</para>
-
-<para>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>The second thing to know is that modifications will only propagate
-across a copy as long as the repository that you're pulling changes
-from <emphasis>doesn't know</emphasis> about the copy.
-</para>
-
-<para>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>If you pulled and merged my changes, and Mercurial <emphasis>didn't</emphasis>
-propagate changes across copies, your source file would now contain
-the bug, and unless you remembered to propagate the bug fix by hand,
-the bug would <emphasis>remain</emphasis> in your copy of the file.
-</para>
-
-<para>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>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 until this point, and no
-further.
-</para>
-
-</sect2>
-<sect2>
-<title>How to make changes <emphasis>not</emphasis> follow a copy</title>
-
-<para>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
-section <xref linkend="sec:daily:why-copy"/>, and make an informed decision that
-this behaviour is not appropriate to your specific case.
-</para>
-
-</sect2>
-<sect2>
-<title>Behaviour of the <command role="hg-cmd">hg copy</command> command</title>
-
-<para>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 behaviour a little counterintuitive, which is why I mention
-it here.)
-</para>
-
-<para>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).  The last
-argument is the <emphasis>destination</emphasis>, and all prior arguments are
-<emphasis>sources</emphasis>.  If you pass it a single file as the source, and the
-destination does not exist, it creates a new file with that name.
-<!-- &interaction.daily.copy.simple; -->
-If the destination is a directory, Mercurial copies its sources into
-that directory.
-<!-- &interaction.daily.copy.dir-dest; -->
-Copying a directory is recursive, and preserves the directory
-structure of the source.
-<!-- &interaction.daily.copy.dir-src; -->
-If the source and destination are both directories, the source tree is
-recreated in the destination directory.
-<!-- &interaction.daily.copy.dir-src-dest; -->
-</para>
-
-<para>As with the <command role="hg-cmd">hg rename</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>.
-<!-- &interaction.daily.copy.after; -->
-</para>
-
-</sect2>
-</sect1>
-<sect1>
-<title>Renaming files</title>
-
-<para>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>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.
-<!-- &interaction.daily.rename.rename; -->
-The <command role="hg-cmd">hg status</command> command shows the newly copied file as added, and
-the copied-from file as removed.
-<!-- &interaction.daily.rename.status; -->
-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.
-<!-- &interaction.daily.rename.status-copy; -->
-</para>
-
-<para>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 behaviour 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>
-
-<sect2>
-<title>Renaming files and merging changes</title>
-
-<para>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>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>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>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>
-
-<para><!-- &interaction.rename.divergent.clone; -->
-Anne renames the file to <filename>bar</filename>.
-<!-- &interaction.rename.divergent.rename.anne; -->
-Meanwhile, Bob renames it to <filename>quux</filename>.
-<!-- &interaction.rename.divergent.rename.bob; -->
-</para>
-
-<para>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>What do you think should happen when they merge their work?
-Mercurial's actual behaviour is that it always preserves <emphasis>both</emphasis>
-names when it merges changesets that contain divergent renames.
-<!-- &interaction.rename.divergent.merge; -->
-</para>
-
-<para>Notice that Mercurial does warn about the divergent renames, but 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>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>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>.
-<!-- &interaction.issue29.go; -->
-</para>
-
-</sect2>
-</sect1>
-<sect1>
-<title>Recovering from mistakes</title>
-
-<para>Mercurial has some useful commands that will help you to recover from
-some common mistakes.
-</para>
-
-<para>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>It's useful 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>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
-chapter <xref linkend="chap:undo"/>.
-</para>
-
-</sect1>
+<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:
--->
\ No newline at end of file
+-->
diff -r c075fb0481c0 -r f0110009e946 fr/ch06-collab.xml
--- a/fr/ch06-collab.xml	Wed Sep 09 15:25:09 2009 +0200
+++ b/fr/ch06-collab.xml	Wed Sep 09 16:07:36 2009 +0200
@@ -1,1405 +1,1565 @@
 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter>
-<title>Collaborating with other people</title>
-<para>\label{cha:collab}</para>
-
-<para>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>Mercurial has a powerful web interface that provides several
-useful capabilities.</para>
-
-<para>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.</para>
-
-<para>Also for human consumption, the web interface provides an RSS feed of
-the changes in a repository.  This lets you <quote>subscribe</quote> to a
-repository using your favourite 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>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>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?style=gitweb">http://www.selenic.com/repo/hg?style=gitweb</ulink>.</para>
-
-<para>If you're interested in providing a web interface to your own
-repositories, Mercurial provides two ways to do this.  The first is
-using the <command role="hg-cmd">hg serve</command> command, which is best suited to short-term
-<quote>lightweight</quote> serving.  See section <xref linkend="sec:collab:serve"/> below for
-details of how to use this command.  If you have a long-lived
-repository that you'd like to make permanently available, Mercurial
-has built-in support for the CGI (Common Gateway Interface) standard,
-which all common web servers support.  See
-section <xref linkend="sec:collab:cgi"/> for details of CGI configuration.</para>
-
-</sect1>
-<sect1>
-<title>Collaboration models</title>
-
-<para>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>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>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>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>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>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 organising 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>A sprint is the perfect place to use the <command role="hg-cmd">hg serve</command> command, since
-<command role="hg-cmd">hg serve</command> does not requires any fancy server infrastructure.  You
-can get started with <command role="hg-cmd">hg serve</command> in moments, by reading
-section <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>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 $n$ different repositories to pull from.
-</para>
-
-</sect2>
-<sect2>
-<title>A single central repository</title>
-
-<para>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>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>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>In this kind of scenario, people usually use the <command>ssh</command>
-protocol to securely push changes to the central repository, as
-documented in section <xref linkend="sec:collab:ssh"/>.  It's also usual to
-publish a read-only copy of the repository over HTTP using CGI, as in
-section <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>Working with multiple branches</title>
-
-<para>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>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 in.
-</para>
-
-<para>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.
-<!-- &interaction.branching.init; -->
-People clone it, make changes locally, test them, and push them back.
-</para>
-
-<para>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.
-<!-- &interaction.branching.tag; -->
-Let's say some ongoing development occurs on the main branch.
-<!-- &interaction.branching.main; -->
-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.
-<!-- &interaction.branching.update; -->
-</para>
-
-<para>In addition, immediately after the main branch is tagged, someone can
-then clone the main branch on the server to a new <quote>stable</quote> branch,
-also on the server.
-<!-- &interaction.branching.clone; -->
-</para>
-
-<para>Someone who needs to make a change to the stable branch can then clone
-<emphasis>that</emphasis> repository, make their changes, commit, and push their
-changes back there.
-<!-- &interaction.branching.stable; -->
-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 you made on the
-main branch don't <quote>leak</quote> to the stable branch, and vice versa.
-</para>
-
-<para>You'll often want all of your bugfixes on the stable branch to show up
-on the main branch, too.  Rather than rewrite a bugfix on the main
-branch, you can simply pull and merge changes from the stable to the
-main branch, and Mercurial will bring those bugfixes in for you.
-<!-- &interaction.branching.merge; -->
-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.
-</para>
-
-</sect2>
-<sect2>
-<title>Feature branches</title>
-
-<para>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>
-
-<informalfigure>
-
-<para>  <mediaobject><imageobject><imagedata fileref="feature-branches"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
-  <caption><para>Feature branches</para></caption>
-  \label{fig:collab:feature-branches}
-</para>
-</informalfigure>
-
-<para>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>Some projects are organised 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>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>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>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>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>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>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>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>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>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>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>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>A good distributed revision control tool, such as Mercurial, 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>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
-chapter <xref linkend="chap:branch"/>.
-</para>
-
-</sect2>
-</sect1>
-<sect1>
-<title>The technical side of sharing</title>
-
-<para>The remainder of this chapter is devoted to the question of serving
-data to your collaborators.
-</para>
-
-</sect1>
-<sect1>
-<title>Informal sharing with <command role="hg-cmd">hg serve</command></title>
-<para>\label{sec:collab:serve}
-</para>
-
-<para>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>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>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>Allow people to browse the history of the repository it's
-  serving, from their normal web browsers.
-</para>
-</listitem>
-<listitem><para>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>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>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>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>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>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>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>
-<title>Using the Secure Shell (ssh) protocol</title>
-<para>\label{sec:collab:ssh}
-</para>
-
-<para>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>If you're not familiar with ssh, it's a network protocol that lets 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>(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>An ssh URL tends to look like this:
-</para>
-<programlisting>
-<para>  ssh://bos@hg.serpentine.com:22/hg/hgbook
-</para>
+<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>
-<orderedlist>
-<listitem><para>The <quote><literal>ssh://</literal></quote> part tells Mercurial to use the ssh
-  protocol.
-</para>
-</listitem>
-<listitem><para>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>The <quote><literal>hg.serpentine.com</literal></quote> gives the hostname of the
-  server to log into.
-</para>
-</listitem>
-<listitem><para>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 this part
-  if you're <emphasis>not</emphasis> using port 22.
-</para>
-</listitem>
-<listitem><para>The remainder of the URL is the local path to the repository on
-  the server.
-</para>
-</listitem></orderedlist>
-
-<para>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>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>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>
-<para>  ssh://server/ otheruser/hg/repo
-</para>
-</programlisting>
-
-<para>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>
-<para>  ssh://server//absolute/path
-</para>
-</programlisting>
-
-</sect2>
-<sect2>
-<title>Finding an ssh client for your system</title>
-
-<para>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>On Windows, you'll first need to download a suitable ssh
-client.  There are two alternatives.
-</para>
-<itemizedlist>
-<listitem><para>Simon Tatham's excellent PuTTY package <citation>web:putty</citation> provides
-  a complete suite of ssh client commands.
-</para>
-</listitem>
-<listitem><para>If you have a high tolerance for pain, you can use the Cygwin
-  port of OpenSSH.
-</para>
-</listitem></itemizedlist>
-<para>In either case, you'll need to edit your \hgini\ file to tell
-Mercurial where to find the actual client command.  For example, if
-you're using PuTTY, you'll need to use the <command>plink</command> command as
-a command-line ssh client.
-</para>
-<programlisting>
-<para>  [ui]
-  ssh = C:/path/to/plink.exe -ssh -i "C:/path/to/my/private/key"
-</para>
-</programlisting>
-
-<note>
-<para>  The path to <command>plink</command> shouldn't contain any whitespace
-  characters, or Mercurial may not be able to run it correctly (so
-  putting it in <filename class="directory">C:\\Program Files</filename> is probably not a good
-  idea).
-</para>
-</note>
-
-</sect2>
-<sect2>
-<title>Generating a key pair</title>
-
-<para>To avoid the need to repetitively type a password every time you need
-to use your ssh client, I recommend generating a key pair.  On a
-Unix-like system, the <command>ssh-keygen</command> command will do the trick.
-On Windows, if you're using PuTTY, the <command>puttygen</command> command is
-what you'll need.
-</para>
-
-<para>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>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>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>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>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>
-
-<para>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.  On Windows, if you're using PuTTY, the <command>pageant</command>
-command acts as the agent.  It adds an icon to your system tray that
-will let you manage stored passphrases.
-</para>
-
-</sect2>
-<sect2>
-<title>Configuring the server side properly</title>
-
-<para>Because ssh can be fiddly to set up if you're new to it, there's a
-variety of things that 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>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>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>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>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>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>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>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>You might have forgotten to use <command>ssh-add</command> or
-  <command>pageant</command> to store the passphrase.
-</para>
-</listitem>
-<listitem><para>You might have stored the passphrase for the wrong key.
-</para>
-</listitem></itemizedlist>
-<para>If you're being prompted for the remote user's password, there are
-another few possible problems to check.
-</para>
-<itemizedlist>
-<listitem><para>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>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>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>
-<para>  ssh myserver date
-</para>
-</programlisting>
-
-<para>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 makes
-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>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>
-<para>  ssh myserver hg version
-</para>
-</programlisting>
-<para>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>Is Mercurial really installed on the server at all?  I know this
-  sounds trivial, but it's worth checking!
-</para>
-</listitem>
-<listitem><para>Maybe your shell's search path (usually set via the <envar>PATH</envar>
-  environment variable) is simply misconfigured.
-</para>
-</listitem>
-<listitem><para>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>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>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>Mercurial does not compress data when it uses the ssh protocol,
-because the ssh protocol can transparently compress data.  However,
-the default behaviour of ssh clients is <emphasis>not</emphasis> to request
-compression.
-</para>
-
-<para>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>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.
-</para>
-<programlisting>
-<para>  [ui]
-  ssh = ssh -C
-</para>
-</programlisting>
-
-<para>If you use <command>ssh</command>, 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>
-<para>  Host hg
-    Compression yes
-    HostName hg.example.com
-</para>
-</programlisting>
-<para>This defines an alias, <literal>hg</literal>.  When you use it 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>
-<title>Serving over HTTP using CGI</title>
-<para>\label{sec:collab:cgi}
-</para>
-
-<para>Depending on how ambitious you are, configuring Mercurial's CGI
-interface can take anything from a few moments to several hours.
-</para>
-
-<para>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>
-<para>  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>
-</note>
-
-<sect2>
-<title>Web server configuration checklist</title>
-
-<para>Before you continue, do take a few moments to check a few aspects of
-your system's setup.
-</para>
-
-<orderedlist>
-<listitem><para>Do you have a web server installed at all?  Mac OS X ships with
-  Apache, but many other systems may not have a web server installed.
-</para>
-</listitem>
-<listitem><para>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>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>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>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/\ {</literal>username/foo}.
-</para>
-
-<para>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>You'll need to copy this script into your <filename class="directory">public_html</filename>
-directory, and ensure that it's executable.
-</para>
-<programlisting>
-<para>  cp .../hgweb.cgi  /public_html
-  chmod 755  /public_html/hgweb.cgi
-</para>
-</programlisting>
-<para>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>
-<para>  chmod 755  /public_html
-</para>
-</programlisting>
-
-<sect3>
-<title>What could <emphasis>possibly</emphasis> go wrong?</title>
-<para>\label{sec:collab:wtf}
-</para>
-
-<para>Once you've copied the CGI script into place, go into a web browser,
-and try to open the URL <ulink url="http://myhostname/ myuser/hgweb.cgi">http://myhostname/ myuser/hgweb.cgi</ulink>,
-<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>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>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>
-<para>  chmod 755  
-  find  /public_html -type d -print0 | xargs -0r chmod 755
-  find  /public_html -type f -print0 | xargs -0r chmod 644
-</para>
-</programlisting>
-
-<para>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 \emph{too
-  permissive}.  Apache's <literal>suexec</literal> subsystem won't execute a
-script that's group- or world-writable, for example.
-</para>
-
-<para>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>
-<programlisting>
-<para>  &lt;Directory /home/*/public_html&gt;
-      AllowOverride FileInfo AuthConfig Limit
-      Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
-      &lt;Limit GET POST OPTIONS&gt;
-          Order allow,deny
-          Allow from all
-      &lt;/Limit&gt;
-      &lt;LimitExcept GET POST OPTIONS&gt;
-          Order deny,allow
-          Deny from all
-      &lt;/LimitExcept&gt;
-  &lt;/Directory&gt;
-</para>
-</programlisting>
-<para>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>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>
-<para>  AddHandler cgi-script .cgi
-</para>
-</programlisting>
-
-<para>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>Finally, you are <emphasis>certain</emphasis> to by 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>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>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>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>
-<para>  userdir.path = "public_html"
-  cgi.assign = ( ".cgi" =&gt; "" )
-</para>
-</programlisting>
-<para>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>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>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>You'll need to copy this script into your <filename class="directory">public_html</filename>
-directory, and ensure that it's executable.
-</para>
-<programlisting>
-<para>  cp .../hgwebdir.cgi  /public_html
-  chmod 755  /public_html  /public_html/hgwebdir.cgi
-</para>
-</programlisting>
-<para>With basic configuration out of the way, try to visit
-<ulink url="http://myhostname/ myuser/hgwebdir.cgi">http://myhostname/ myuser/hgwebdir.cgi</ulink> 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 section <xref linkend="sec:collab:wtf"/>.
-</para>
-
-<para>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>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>
-<para>  [collections]
-  /my/root = /my/root
-</para>
-</programlisting>
-<para>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>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 <ulink url="http://myhostname/ myuser/hgwebdir.cgi">http://myhostname/ myuser/hgwebdir.cgi</ulink>, the complete
-URL for that repository will be
-<ulink url="http://myhostname/ myuser/hgwebdir.cgi/this/repo">http://myhostname/ myuser/hgwebdir.cgi/this/repo</ulink>.
-</para>
-
-<para>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>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>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>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>
-<para>  [paths]
-  repo1 = /my/path/to/some/repo
-  repo2 = /some/path/to/another
-</para>
-</programlisting>
-<para>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>If you wish, you can use both the <literal>collections</literal> and
-<literal>paths</literal> mechanisms simultaneously in a single configuration
-file.
-</para>
-
-<note>
-<para>  If multiple 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>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>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>.
-</para>
-
-</sect2>
-<sect2>
-<title>Web configuration options</title>
-
-<para>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><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>
-</listitem><itemizedlist>
-<listitem><para>  \item <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.
-  \item <literal>gz</literal>: A <command>tar</command> archive, compressed using
-    <literal>gzip</literal> compression.
-  \item <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>  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>
-<para>    [web]
-    allow_archive = bz2 gz zip
-</para>
-</programlisting>
-<listitem><para><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><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><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><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><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><envar role="rc-item-web">style</envar>: Controls the template Mercurial uses to
-  display the web interface.  Mercurial ships with two web templates,
-  named <literal>default</literal> and <literal>gitweb</literal> (the latter is much more
-  visually attractive).  You can also specify a custom template of
-  your own; see chapter <xref linkend="chap:template"/> for details.  Here, you
-  can see how to enable the <literal>gitweb</literal> style.
-</para>
-</listitem><programlisting>
-<listitem><para>    [web]
-    style = gitweb
-</para>
-</listitem></programlisting>
-</para>
-</listitem>
-<listitem><para><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>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>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><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><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>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><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><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><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><envar role="rc-item-web">ipv6</envar>: Boolean.  Whether to use the IPv6 protocol.
-  By default, IPv6 is not used.
-</para>
-</listitem>
-<listitem><para><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>
-
-<para>\subsubsection{Choosing the right <filename role="special"> /.hgrc</filename>\ file to add <literal role="rc-web">web</literal>
-  items to}
-</para>
-
-<para>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>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 behaviour 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>
+    </sect2>
+  </sect1>
 </chapter>
 
 <!--
 local variables: 
 sgml-parent-document: ("00book.xml" "book" "chapter")
 end:
--->
\ No newline at end of file
+-->
diff -r c075fb0481c0 -r f0110009e946 fr/ch07-filenames.xml
--- a/fr/ch07-filenames.xml	Wed Sep 09 15:25:09 2009 +0200
+++ b/fr/ch07-filenames.xml	Wed Sep 09 16:07:36 2009 +0200
@@ -1,388 +1,451 @@
 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter>
-<title>File names and pattern matching</title>
-<para>\label{chap:names}</para>
-
-<para>Mercurial provides mechanisms that let you work with file names in a
-consistent and expressive way.</para>
-
-<sect1>
-<title>Simple file naming</title>
-
-<para>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>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>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.
-<!-- &interaction.filenames.dirs; --></para>
-
-</sect1>
-<sect1>
-<title>Running commands without any file names</title>
-
-<para>Mercurial's commands that work with file names have useful default
-behaviours when you invoke them without providing any file names or
-patterns.  What kind of behaviour 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>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>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>It's easy to work around these default behaviours 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>.
-<!-- &interaction.filenames.wdir-subdir; -->
-</para>
-
-<para>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.
-<!-- &interaction.filenames.wdir-relname; -->
-</para>
-
-</sect1>
-<sect1>
-<title>Telling you what's going on</title>
-
-<para>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>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>,
-because you provided no names, or a directory, or a pattern (see
-below), it's safest to tell you what it's doing.
-</para>
-
-<para>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>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>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>To provide a pattern in place of a regular name on the command line,
-the mechanism is simple:
-</para>
-<programlisting>
-<para>  syntax:patternbody
-</para>
+<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>
-<para>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>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>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>The <literal>re</literal> syntax is more powerful; it lets you specify patterns
-using regular expressions, also known as regexps.
-</para>
-
-<para>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>This is an overview of the kinds of patterns you can use when you're
-matching on glob patterns.
-</para>
-
-<para>The <quote><literal>*</literal></quote> character matches any string, within a single
-directory.
-<!-- &interaction.filenames.glob.star; -->
-</para>
-
-<para>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.
-<!-- &interaction.filenames.glob.starstar; -->
-</para>
-
-<para>The <quote><literal>?</literal></quote> pattern matches any single character.
-<!-- &interaction.filenames.glob.question; -->
-</para>
-
-<para>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>.
-<!-- &interaction.filenames.glob.range; -->
-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>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>\texttt{}}</quote> ends the group.
-<!-- &interaction.filenames.glob.group; -->
-</para>
-
-<sect3>
-<title>Watch out!</title>
-
-<para>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.
-<!-- &interaction.filenames.glob.star-starstar; -->
-</para>
-
-</sect3>
-</sect2>
-<sect2>
-<title>Regular expression matching with <literal>re</literal> patterns</title>
-
-<para>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>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>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>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>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><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><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>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>You can read a <option role="hg-opt-global">-I</option> filter as <quote>process only the files that
-match this filter</quote>.
-<!-- &interaction.filenames.filter.include; -->
-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>.
-<!-- &interaction.filenames.filter.exclude; -->
-</para>
-
-</sect1>
-<sect1>
-<title>Ignoring unwanted files and directories</title>
-
-<para>XXX.
-</para>
-
-</sect1>
-<sect1>
-<title>Case sensitivity</title>
-<para>\label{sec:names:case}
-</para>
-
-<para>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>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>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>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 \emph{case
-    folding}.
-</para>
-</listitem>
-<listitem><para>Case sensitive.  The case of a name is significant at all times.
-  The names <filename>foo</filename> and {FoO} identify different files.  This
-  is the way Linux and Unix systems normally work.
-</para>
-</listitem></itemizedlist>
-
-<para>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>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>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>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>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>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>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>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>
-
-<note>
-<para>  Prior to version 0.9.3, Mercurial did not use a case safe repository
-  storage mechanism, and did not detect case folding conflicts.  If
-  you are using an older version of Mercurial on Windows or MacOS, I
-  strongly recommend that you upgrade.
-</para>
-</note>
-
-</sect2>
-</sect1>
+  </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:
--->
\ No newline at end of file
+-->
diff -r c075fb0481c0 -r f0110009e946 fr/ch08-branch.xml
--- a/fr/ch08-branch.xml	Wed Sep 09 15:25:09 2009 +0200
+++ b/fr/ch08-branch.xml	Wed Sep 09 16:07:36 2009 +0200
@@ -1,473 +1,533 @@
 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter>
-<title>Managing releases and branchy development</title>
-<para>\label{chap:branch}</para>
-
-<para>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>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>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>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>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>.
-<!-- &interaction.tag.tag; --></para>
-
-<para>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>Colon (ASCII 58, <quote><literal>:</literal></quote>)</para>
-</listitem>
-<listitem><para>Carriage return (ASCII 13, <quote><literal>\r</literal></quote>)
-</para>
-</listitem>
-<listitem><para>Newline (ASCII 10, <quote><literal>\n</literal></quote>)
-</para>
-</listitem></itemizedlist>
-
-<para>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.
-<!-- &interaction.tag.tags; -->
-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>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>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.
-<!-- &interaction.tag.log; -->
-</para>
-
-<para>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.
-<!-- &interaction.tag.log.v1.0; -->
-</para>
-
-<para>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>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>If you want to remove a tag that you no longer want, use
-<command role="hg-cmd">hg tag --remove</command>.
-<!-- &interaction.tag.remove; -->
-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.
-<!-- &interaction.tag.replace; -->
-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>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
-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>.
-<!-- &interaction.tag.tip; -->
-</para>
-
-<sect2>
-<title>Handling tag conflicts during a merge</title>
-
-<para>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>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>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>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>Recall that a tag is stored as a revision to the <filename role="special">.hgtags</filename>
-file, so that when you create a tag, the changeset in which it's
-recorded necessarily 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 \emph{will not contain the history that
-  created the tag} that you used to clone the repository.  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>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>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>To return to the outline I sketched at the beginning of a chapter,
-let's think about a project that has multiple concurrent pieces of
-work under development at once.
-</para>
-
-<para>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>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><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><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>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.
-<!-- &interaction.branch-repo.tag; -->
-You can then clone a new shared <literal>myproject-1.0.1</literal> repository as
-of that tag.
-<!-- &interaction.branch-repo.clone; -->
-</para>
-
-<para>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.
-<!-- &interaction.branch-repo.bugfix; -->
-Meanwhile, development for the next major release can continue,
-isolated and unabated, in the <literal>myproject</literal> repository.
-<!-- &interaction.branch-repo.new; -->
-</para>
-
-</sect1>
-<sect1>
-<title>Don't repeat yourself: merging across branches</title>
-
-<para>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>In the simplest instance, all you need to do is pull changes from your
-maintenance branch into your local clone of the target branch.
-<!-- &interaction.branch-repo.pull; -->
-You'll then need to merge the heads of the two branches, and push back
-to the main branch.
-<!-- &interaction.branch-repo.merge; -->
-</para>
-
-</sect1>
-<sect1>
-<title>Naming branches within one repository</title>
-
-<para>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>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>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>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>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.
-<!-- &interaction.branch-named.branches; -->
-Since you haven't created any named branches yet, the only one that
-exists is <literal>default</literal>.
-</para>
-
-<para>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.
-<!-- &interaction.branch-named.branch; -->
-</para>
-
-<para>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.
-<!-- &interaction.branch-named.create; -->
-</para>
-
-<para>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?
-<!-- &interaction.branch-named.status; -->
-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>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.
-<!-- &interaction.branch-named.commit; -->
-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>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.
-<!-- &interaction.branch-named.rebranch; -->
-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>If you have more than one named branch in a repository, Mercurial will
-remember the branch that your working directory 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>This behaviour 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.
-<!-- &interaction.branch-named.parents; -->
-We're on the <literal>bar</literal> branch, but there also exists an older
-<command role="hg-cmd">hg foo</command> branch.
-</para>
-
-<para>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.
-<!-- &interaction.branch-named.update-switchy; -->
-</para>
-
-<para>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>.
-<!-- &interaction.branch-named.update-nothing; -->
-</para>
-
-<para>Committing a new change on the <literal>foo</literal> branch introduces a new
-head.
-<!-- &interaction.branch-named.foo-commit; -->
-</para>
-
-</sect1>
-<sect1>
-<title>Branch names and merging</title>
-
-<para>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>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>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>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.
-<!-- &interaction.branch-named.merge; -->
-</para>
-
-<para>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>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>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>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>
-<para>  [hooks]
-  pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch
-</para>
-</programlisting>
-
-</sect1>
+<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:
--->
\ No newline at end of file
+-->
diff -r c075fb0481c0 -r f0110009e946 fr/ch09-undo.xml
--- a/fr/ch09-undo.xml	Wed Sep 09 15:25:09 2009 +0200
+++ b/fr/ch09-undo.xml	Wed Sep 09 16:07:36 2009 +0200
@@ -1,963 +1,1201 @@
 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter>
-<title>Finding and fixing your mistakes</title>
-<para>\label{chap:undo}</para>
-
-<para>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>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>
-<title>Rolling back a transaction</title>
-<para>\label{sec:undo:rollback}</para>
-
-<para>In section <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
-section <xref linkend="sec:undo:rollback-after-push"/> for an important caveat
-about the use of this command.)</para>
-
-<para>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.
-<!-- &interaction.rollback.commit; -->
-Looking at the output of <command role="hg-cmd">hg status</command> after the commit immediately
-confirms the error.
-<!-- &interaction.rollback.status; -->
-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>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.
-<!-- &interaction.rollback.rollback; -->
-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.
-<!-- &interaction.rollback.add; --></para>
-
-</sect2>
-<sect2>
-<title>The erroneous pull</title>
-
-<para>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>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>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>
-<title>Rolling back is useless once you've pushed</title>
-<para>\label{sec:undo:rollback-after-push}
-</para>
-
-<para>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>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.  What
-will happen if you push a changeset somewhere, then roll it back, then
-pull from the repository you pushed to, is that the changeset will
-reappear in your repository.
-</para>
-
-<para>(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 really not rely on this working reliably.  If you do this,
-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>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 behaviour you will get.
-<!-- &interaction.rollback.twice; -->
-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>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>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.
-<!-- &interaction.daily.revert.modify; -->
-If we don't want that change, we can simply <command role="hg-cmd">hg revert</command> the file.
-<!-- &interaction.daily.revert.unmodify; -->
-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.
-<!-- &interaction.daily.revert.status; -->
-</para>
-
-<para>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>If you modify a file, it will restore the file to its unmodified
-  state.
-</para>
-</listitem>
-<listitem><para>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>If you delete a file without telling Mercurial, it will restore
-  the file to its unmodified contents.
-</para>
-</listitem>
-<listitem><para>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>
-<title>File management errors</title>
-<para>\label{sec:undo:mgmt}
-</para>
-
-<para>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>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.
-<!-- &interaction.daily.revert.add; -->
-</para>
-
-<para>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>).
-<!-- &interaction.daily.revert.missing; -->
-</para>
-
-<para>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.
-<!-- &interaction.daily.revert.copy; -->
-</para>
-
-<sect3>
-<title>A slightly special case: reverting a rename</title>
-
-<para>If you <command role="hg-cmd">hg rename</command> a file, there is one small detail that
-you should remember.  When you <command role="hg-cmd">hg revert</command> a rename, it's not
-enough to provide the name of the renamed-to file, as you can see
-here.
-<!-- &interaction.daily.revert.rename; -->
-As you can see from the output of <command role="hg-cmd">hg status</command>, the renamed-to file
-is no longer identified as added, but the renamed-<emphasis>from</emphasis> file is
-still removed!  This is counter-intuitive (at least to me), but at
-least it's easy to deal with.
-<!-- &interaction.daily.revert.rename-orig; -->
-So remember, to revert a <command role="hg-cmd">hg rename</command>, you must provide <emphasis>both</emphasis>
-the source and destination names.
-</para>
-
-<para>% TODO: the output doesn't look like it will be removed!
-</para>
-
-<para>(By the way, if you rename a file, then modify the renamed-to file,
-then revert both components of the rename, when Mercurial restores the
-file that was removed as part of the rename, it will be unmodified.
-If you need the modifications in the renamed-to file to show up in the
-renamed-from file, don't forget to copy them over.)
-</para>
-
-<para>These fiddly aspects of reverting a rename arguably constitute a small
-bug in Mercurial.
-</para>
-
-</sect3>
-</sect2>
-</sect1>
-<sect1>
-<title>Dealing with committed changes</title>
-
-<para>Consider a case where you have committed a change $a$, and another
-change $b$ on top of it; you then realise that change $a$ 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>Before you read this section, here's something to keep in mind: the
-<command role="hg-cmd">hg backout</command> command undoes changes by <emphasis>adding</emphasis> 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
-section <xref linkend="sec:undo:aaaiiieee"/>.
-</para>
-
-<sect2>
-<title>Backing out a changeset</title>
-
-<para>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>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.
-<!-- &interaction.backout.init; -->
-</para>
-
-<para>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>We're going to start by backing out the last changeset we committed.
-<!-- &interaction.backout.simple; -->
-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
-figure <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>
-
-<informalfigure>
-
-<para>  <mediaobject><imageobject><imagedata fileref="undo-simple"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
-  <caption><para>Backing out a change using the <command role="hg-cmd">hg backout</command> command</para></caption>
-  \label{fig:undo:backout}
-</para>
-</informalfigure>
-
-</sect2>
-<sect2>
-<title>Backing out a non-tip change</title>
-
-<para>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.
-<!-- &interaction.backout.non-tip.clone; -->
-This makes backing out any changeset a <quote>one-shot</quote> operation that's
-usually simple and fast.
-<!-- &interaction.backout.non-tip.backout; -->
-</para>
-
-<para>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.
-<!-- &interaction.backout.non-tip.cat; -->
-</para>
-
-<para>As the graphical history in figure <xref linkend="fig:undo:backout-non-tip"/>
-illustrates, Mercurial actually commits <emphasis>two</emphasis> changes in this
-kind of situation (the box-shaped nodes are the ones that Mercurial
-commits automatically).  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, and commits the result of the merge.
-</para>
-
-<para>% TODO: to me it looks like mercurial doesn't commit the second merge automatically!
-</para>
-
-<informalfigure>
-
-<para>  <mediaobject><imageobject><imagedata fileref="undo-non-tip"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
-  <caption><para>Automated backout of a non-tip change using the <command role="hg-cmd">hg backout</command> command</para></caption>
-  \label{fig:undo:backout-non-tip}
-</para>
-</informalfigure>
-
-<para>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>
-
-<sect3>
-<title>Always use the <option role="hg-opt-backout">--merge</option> option</title>
-
-<para>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>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>
-
-<para><!-- &interaction.backout.manual.clone; -->
-As with our earlier example, We'll commit a third changeset, then back
-out its parent, and see what happens.
-<!-- &interaction.backout.manual.backout; -->
-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.
-<!-- &interaction.backout.manual.log; -->
-</para>
-
-<para>Again, it's easier to see what has happened by looking at a graph of
-the revision history, in figure <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>
-
-<informalfigure>
-
-<para>  <mediaobject><imageobject><imagedata fileref="undo-manual"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
-  <caption><para>Backing out a change using the <command role="hg-cmd">hg backout</command> command</para></caption>
-  \label{fig:undo:backout-manual}
-</para>
-</informalfigure>
-
-<para>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.
-<!-- &interaction.backout.manual.parents; -->
-Now we have two isolated sets of changes.
-<!-- &interaction.backout.manual.heads; -->
-</para>
-
-<para>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>.
-<!-- &interaction.backout.manual.cat; -->
-To get the third change back into the file, we just do a normal merge
-of our two heads.
-<!-- &interaction.backout.manual.merge; -->
-Afterwards, the graphical history of our repository looks like
-figure <xref linkend="fig:undo:backout-manual-merge"/>.
-</para>
-
-<informalfigure>
-
-<para>  <mediaobject><imageobject><imagedata fileref="undo-manual-merge"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
-  <caption><para>Manually merging a backout change</para></caption>
-  \label{fig:undo:backout-manual-merge}
-</para>
-</informalfigure>
-
-</sect2>
-<sect2>
-<title>Why <command role="hg-cmd">hg backout</command> works as it does</title>
-
-<para>Here's a brief description of how the <command role="hg-cmd">hg backout</command> command works.
-</para>
-<orderedlist>
-<listitem><para>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>It remembers the current parent of the working directory.  Let's
-  call this changeset <literal>orig</literal>
-</para>
-</listitem>
-<listitem><para>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>It finds the parent of that changeset.  Let's call that
-  changeset <literal>parent</literal>.
-</para>
-</listitem>
-<listitem><para>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>It commits the result as a new changeset.  This changeset has
-  <literal>backout</literal> as its parent.
-</para>
-</listitem>
-<listitem><para>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>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>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>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>
-<title>Changes that should never have been</title>
-<para>\label{sec:undo:aaaiiieee}
-</para>
-
-<para>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>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>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>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 section <xref linkend="sec:undo:rollback"/>.
-</para>
-
-<para>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>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
-changeefrom <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>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>
-
-<para>XXX This needs filling out.  The <literal>hg-replay</literal> script in the
-<literal>examples</literal> directory works, but doesn't handle merge
-changesets.  Kind of an important omission.
-</para>
-
-<sect2>
-<title>Protect yourself from <quote>escaped</quote> changes</title>
-
-<para>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>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>For instance, an incoming change hook that verifies that a changeset
-will actually compile can prevent people from inadvertantly <quote>breaking
-the build</quote>.
-</para>
-
-</sect2>
-</sect1>
-<sect1>
-<title>Finding the source of a bug</title>
-<para>\label{sec:undo:bisect}
-</para>
-
-<para>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>The idea behind the <command role="hg-cmd">hg bisect</command> command is that a changeset has
-introduced some change of behaviour that you can identify with a
-simple binary 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>Here are a few scenarios to help you understand how you might apply
-this command.
-</para>
-<itemizedlist>
-<listitem><para>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>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>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>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>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>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.
-</para>
-
-<para>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>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>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>Here's an example of <command role="hg-cmd">hg bisect</command> in action.
-</para>
-
-<note>
-<para>  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>Now let's create a repository, so that we can try out the
-<command role="hg-cmd">hg bisect</command> command in isolation.
-<!-- &interaction.bisect.init; -->
-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>.
-<!-- &interaction.bisect.commits; -->
-</para>
-
-<para>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.
-<!-- &interaction.bisect.help; -->
-</para>
-
-<para>The <command role="hg-cmd">hg bisect</command> command works in steps.  Each step proceeds as follows.
-</para>
-<orderedlist>
-<listitem><para>You run your binary test.
-</para>
-</listitem><itemizedlist>
-<listitem><para>  \item 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.
-  \item If it failed, run the <command role="hg-cmd">hg bisect --bad</command> command.
-</para>
-</listitem></itemizedlist>
-<listitem><para>The command uses your information to decide which changeset to
-  test next.
-</para>
-</listitem>
-<listitem><para>It updates the working directory to that changeset, and the
-  process begins again.
-</para>
-</listitem></orderedlist>
-<para>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>To start the search, we must run the <command role="hg-cmd">hg bisect --reset</command> command.
-<!-- &interaction.bisect.search.init; -->
-</para>
-
-<para>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>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>.
-<!-- &interaction.bisect.search.bad-init; -->
-</para>
-
-<para>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.)
-<!-- &interaction.bisect.search.good-init; -->
-</para>
-
-<para>Notice that this command printed some output.
-</para>
-<itemizedlist>
-<listitem><para>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>It updated the working directory to the next changeset to test,
-  and told us which changeset it's testing.
-</para>
-</listitem></itemizedlist>
-
-<para>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>This test looks like a perfect candidate for automation, so let's turn
-it into a shell function.
-<!-- &interaction.bisect.search.mytest; -->
-We can now run an entire test step with a single command,
-<literal>mytest</literal>.
-<!-- &interaction.bisect.search.step2; -->
-A few more invocations of our canned test step command, and we're
-done.
-<!-- &interaction.bisect.search.rest; -->
-</para>
-
-<para>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>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>.
-<!-- &interaction.bisect.search.reset; -->
-</para>
-
-</sect2>
-</sect1>
-<sect1>
-<title>Tips for finding bugs effectively</title>
-
-<sect2>
-<title>Give consistent input</title>
-
-<para>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>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>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>The key to automated testing is twofold:
-</para>
-<itemizedlist>
-<listitem><para>always test for the same symptom, and
-</para>
-</listitem>
-<listitem><para>always feed consistent input to the <command role="hg-cmd">hg bisect</command> command.
-</para>
-</listitem></itemizedlist>
-<para>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>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>The changeset that it reports as the first bad revision.  Your
-  test should still report this as bad.
-</para>
-</listitem>
-<listitem><para>The parent of that changeset (either parent, if it's a merge).
-  Your test should report this changeset as good.
-</para>
-</listitem>
-<listitem><para>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>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>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>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>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>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>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>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 behaviour.
-</para>
-
-</sect2>
-</sect1>
+<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:
--->
\ No newline at end of file
+-->
diff -r c075fb0481c0 -r f0110009e946 fr/ch10-hook.xml
--- a/fr/ch10-hook.xml	Wed Sep 09 15:25:09 2009 +0200
+++ b/fr/ch10-hook.xml	Wed Sep 09 16:07:36 2009 +0200
@@ -1,1883 +1,1928 @@
 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter>
-<title>Handling repository events with hooks</title>
-<para>\label{chap:hook}</para>
-
-<para>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>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>Here is a brief list of the hooks that Mercurial supports.  We will
-revisit each of these hooks in more detail later, in
-section <xref linkend="sec:hook:ref"/>.</para>
-
-<itemizedlist>
-<listitem><para><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><literal role="hook">commit</literal>: This is run after a new changeset has been
-  created in the local repository.</para>
-</listitem>
-<listitem><para><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><literal role="hook">outgoing</literal>: This is run after a group of changesets
-  has been transmitted from this repository.</para>
-</listitem>
-<listitem><para><literal role="hook">prechangegroup</literal>: This is run before starting to
-  bring a group of changesets into the repository.
-</para>
-</listitem>
-<listitem><para><literal role="hook">precommit</literal>: Controlling. This is run before starting
-  a commit.
-</para>
-</listitem>
-<listitem><para><literal role="hook">preoutgoing</literal>: Controlling. This is run before
-  starting to transmit a group of changesets from this repository.
-</para>
-</listitem>
-<listitem><para><literal role="hook">pretag</literal>: Controlling. This is run before creating a tag.
-</para>
-</listitem>
-<listitem><para><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><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><literal role="hook">preupdate</literal>: Controlling. This is run before starting
-  an update or merge of the working directory.
-</para>
-</listitem>
-<listitem><para><literal role="hook">tag</literal>: This is run after a tag is created.
-</para>
-</listitem>
-<listitem><para><literal role="hook">update</literal>: This is run after an update or merge of the
-  working directory has finished.
-</para>
-</listitem></itemizedlist>
-<para>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>
-
-</sect1>
-<sect1>
-<title>Hooks and security</title>
-
-<sect2>
-<title>Hooks are run with your privileges</title>
-
-<para>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>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>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>  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>XXX To see what hooks are defined in a repository, use the
-<command role="hg-cmd">hg config 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>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>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>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>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>Mercurial allows you to override a hook definition by redefining the
-hook.  You can disable it by setting its value to the empty string, or
-change its behaviour as you wish.
-</para>
-
-<para>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>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>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>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>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>
-<title>Care with <literal>pretxn</literal> hooks in a shared-access repository</title>
-
-<para>If you want to use hooks to do some automated work in a repository
-that a number of people have shared access to, you need to be careful
-in how you do this.
-</para>
-
-<para>Mercurial only locks a repository when it is writing to the
-repository, and only the parts of Mercurial that write to the
-repository pay attention to locks.  Write locks are necessary to
-prevent multiple simultaneous writers from scribbling on each other's
-work, corrupting the repository.
-</para>
-
-<para>Because Mercurial is careful with the order in which it reads and
-writes data, it does not need to acquire a lock when it wants to read
-data from the repository.  The parts of Mercurial that read from the
-repository never pay attention to locks.  This lockless reading scheme
-greatly increases performance and concurrency.
-</para>
-
-<para>With great performance comes a trade-off, though, one which has the
-potential to cause you trouble unless you're aware of it.  To describe
-this requires a little detail about how Mercurial adds changesets to a
-repository and reads those changes.
-</para>
-
-<para>When Mercurial <emphasis>writes</emphasis> metadata, it writes it straight into the
-destination file.  It writes file data first, then manifest data
-(which contains pointers to the new file data), then changelog data
-(which contains pointers to the new manifest data).  Before the first
-write to each file, it stores a record of where the end of the file
-was in its transaction log.  If the transaction must be rolled back,
-Mercurial simply truncates each file back to the size it was before the
-transaction began.
-</para>
-
-<para>When Mercurial <emphasis>reads</emphasis> metadata, it reads the changelog first,
-then everything else.  Since a reader will only access parts of the
-manifest or file metadata that it can see in the changelog, it can
-never see partially written data.
-</para>
-
-<para>Some controlling hooks (<literal role="hook">pretxncommit</literal> and
-<literal role="hook">pretxnchangegroup</literal>) run when a transaction is almost complete.
-All of the metadata has been written, but Mercurial can still roll the
-transaction back and cause the newly-written data to disappear.
-</para>
-
-<para>If one of these hooks runs for long, it opens a window of time during
-which a reader can see the metadata for changesets that are not yet
-permanent, and should not be thought of as <quote>really there</quote>.  The
-longer the hook runs, the longer that window is open.
-</para>
-
-<sect2>
-<title>The problem illustrated</title>
-
-<para>In principle, a good use for the <literal role="hook">pretxnchangegroup</literal> hook would
-be to automatically build and test incoming changes before they are
-accepted into a central repository.  This could let you guarantee that
-nobody can push changes to this repository that <quote>break the build</quote>.
-But if a client can pull changes while they're being tested, the
-usefulness of the test is zero; an unsuspecting someone can pull
-untested changes, potentially breaking their build.
-</para>
-
-<para>The safest technological answer to this challenge is to set up such a
-<quote>gatekeeper</quote> repository as <emphasis>unidirectional</emphasis>.  Let it take
-changes pushed in from the outside, but do not allow anyone to pull
-changes from it (use the <literal role="hook">preoutgoing</literal> hook to lock it down).
-Configure a <literal role="hook">changegroup</literal> hook so that if a build or test
-succeeds, the hook will push the new changes out to another repository
-that people <emphasis>can</emphasis> pull from.
-</para>
-
-<para>In practice, putting a centralised bottleneck like this in place is
-not often a good idea, and transaction visibility has nothing to do
-with the problem.  As the size of a project&emdash;and the time it takes to
-build and test&emdash;grows, you rapidly run into a wall with this <quote>try
-before you buy</quote> approach, where you have more changesets to test than
-time in which to deal with them.  The inevitable result is frustration
-on the part of all involved.
-</para>
-
-<para>An approach that scales better is to get people to build and test
-before they push, then run automated builds and tests centrally
-<emphasis>after</emphasis> a push, to be sure all is well.  The advantage of this
-approach is that it does not impose a limit on the rate at which the
-repository can accept changes.
-</para>
-
-</sect2>
-</sect1>
-<sect1>
-<title>A short tutorial on using hooks</title>
-<para>\label{sec:hook:simple}
-</para>
-
-<para>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>
-
-<informalfigure>
-<para>  <!-- &interaction.hook.simple.init; -->
-  <caption><para>A simple hook that runs when a changeset is committed</para></caption>
-  \label{ex:hook:init}
-</para>
-</informalfigure>
-
-<para>All hooks follow the pattern in example <xref linkend="ex:hook:init"/>.  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>Quite often, you will want to define more than one hook for a
-particular kind of event, as shown in example <xref linkend="ex:hook:ext"/>.
-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>
-
-<informalfigure>
-<para>  <!-- &interaction.hook.simple.ext; -->
-  <caption><para>Defining a second <literal role="hook">commit</para></caption> hook</literal>
-  \label{ex:hook:ext}
-</para>
-</informalfigure>
-
-<para>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>It is a good idea to use a somewhat descriptive extension when you
-define a new hook.  This will help you to remember what the hook was
-for.  If the hook fails, you'll get an error message that contains the
-hook name and extension, so using a descriptive extension could give
-you an immediate hint as to why the hook failed (see
-section <xref linkend="sec:hook:perm"/> for an example).
-</para>
-
-</sect2>
-<sect2>
-<title>Controlling whether an activity can proceed</title>
-<para>\label{sec:hook:perm}
-</para>
-
-<para>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>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>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>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>
-
-<informalfigure>
-<para>  <!-- &interaction.hook.simple.pretxncommit; -->
-  <caption><para>Using the <literal role="hook">pretxncommit</para></caption> hook to control commits</literal>
-  \label{ex:hook:pretxncommit}
-</para>
-</informalfigure>
-
-<para>The hook in example <xref linkend="ex:hook:pretxncommit"/> checks that a commit
-comment contains a bug ID.  If it does, the commit can complete.  If
-not, the commit is rolled back.
-</para>
-
-</sect2>
-</sect1>
-<sect1>
-<title>Writing your own hooks</title>
-
-<para>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>
-<title>Choosing how your hook should run</title>
-<para>\label{sec:hook:lang}
-</para>
-
-<para>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>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>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>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>
-<title>Hook parameters</title>
-<para>\label{sec:hook:param}
-</para>
-
-<para>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>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>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>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>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>An executable hook is always run with its current directory set to a
-repository's root directory.
-</para>
-
-<para>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>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>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>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>The following <filename role="special"> /.hgrc</filename>\ example snippet illustrates the syntax and
-meaning of the notions we just described.
-</para>
-<programlisting>
-<para>  [hooks]
-  commit.example = python:mymodule.submodule.myhook
-</para>
-</programlisting>
-<para>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>The simplest in-process hook does nothing, but illustrates the basic
-shape of the hook API:
-</para>
-<programlisting>
-<para>  def myhook(ui, repo, **kwargs):
-      pass
-</para>
-</programlisting>
-<para>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>It's hard to imagine a useful commit message being very short.  The
-simple <literal role="hook">pretxncommit</literal> hook of figure <xref linkend="ex:hook:msglen.go"/>
-will prevent you from committing a changeset with a message that is
-less than ten bytes long.
-</para>
-
-<informalfigure>
-<para>  <!-- &interaction.hook.msglen.go; -->
-  <caption><para>A hook that forbids overly short commit messages</para></caption>
-  \label{ex:hook:msglen.go}
-</para>
-</informalfigure>
-
-</sect2>
-<sect2>
-<title>Checking for trailing whitespace</title>
-
-<para>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>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>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>
-
-<informalfigure>
-<para>  <!-- &interaction.hook.ws.simple; -->
-  <caption><para>A simple hook that checks for trailing whitespace</para></caption>
-  \label{ex:hook:ws.simple}
-</para>
-</informalfigure>
-
-<para>Figure <xref linkend="ex:hook:ws.simple"/> introduces 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>
-
-<informalfigure>
-<para>  <!-- &interaction.hook.ws.better; -->
-  <caption><para>A better trailing whitespace hook</para></caption>
-  \label{ex:hook:ws.better}
-</para>
-</informalfigure>
-
-<para>The example of figure <xref linkend="ex:hook:ws.better"/> is much more complex,
-but also more useful.  It parses a unified diff to see if any lines
-add trailing whitespace, and prints the name of the file and the line
-number of each such occurrence.  Even better, if the change adds
-trailing whitespace, this hook saves the commit comment and prints the
-name of the save file before exiting and telling Mercurial to roll the
-transaction back, so you can use
-<command role="hg-cmd">hg commit <option role="hg-opt-commit">-l</option> <emphasis>filename</emphasis></command> to reuse the
-saved commit message once you've corrected the problem.
-</para>
-
-<para>As a final aside, note in figure <xref linkend="ex:hook:ws.better"/> the use of
-<command>perl</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.
-</para>
-<programlisting>
-<para>  perl -pi -e 's,\textbackslash{}s+$,,' filename
-</para>
-</programlisting>
-
-</sect2>
-</sect1>
-<sect1>
-<title>Bundled hooks</title>
-
-<para>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>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>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>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>
-<para>  [hooks]
-  pretxnchangegroup.acl = python:hgext.acl.hook
-</para>
-</programlisting>
-
-<para>The <literal role="hg-ext">acl</literal> extension is configured using three sections.
-</para>
-
-<para>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><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><envar role="rc-item-acl">pull</envar>: Control incoming changesets that are
-  arriving via a pull from a local repository.
-</para>
-</listitem>
-<listitem><para><envar role="rc-item-acl">push</envar>: Control incoming changesets that are
-  arriving via a push from a local repository.
-</para>
-</listitem>
-<listitem><para><envar role="rc-item-acl">bundle</envar>: Control incoming changesets that are
-  arriving from another repository via a bundle.
-</para>
-</listitem></itemizedlist>
-
-<para>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>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>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>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>
-<para>  [acl.allow]
-  docs/** = docwriter
-</para>
-
-<para>  [acl.deny]
-  source/sensitive/** = intern
-</para>
-</programlisting>
-
-</sect3>
-<sect3>
-<title>Testing and troubleshooting</title>
-
-<para>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>
-<para>  [ui]
-  debug = true
-</para>
-</programlisting>
-<para>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>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>It adds a comment to the bug that looks like this (you can configure
-the contents of the comment&emdash;see below):
-</para>
-<programlisting>
-<para>  Changeset aad8b264143a, made by Joe User &lt;joe.user@domain.com&gt; in
-  the frobnitz repository, refers to this bug.
-</para>
-
-<para>  For complete details, see
-  http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
-</para>
-
-<para>  Changeset description:
-        Fix bug 10483 by guarding against some NULL pointers
-</para>
-</programlisting>
-<para>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>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>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>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>
-<title>Configuring the <literal role="hook">bugzilla</literal> hook</title>
-<para>\label{sec:hook:bugzilla:config}
-</para>
-
-<para>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>
-<para>  [hooks]
-  incoming.bugzilla = python:hgext.bugzilla.hook
-</para>
-</programlisting>
-
-<para>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>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>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><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.
-  At the moment, the only version supported is <literal>2.16</literal>.
-</para>
-</listitem>
-<listitem><para><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><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><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><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><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>
-</listitem><programlisting>
-<listitem><para>    cd /var/www/html/bugzilla &amp;&amp; ./processmail %s nobody@nowhere.com
-</para>
-</listitem></programlisting>
-<listitem><para>  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>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>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>
-<para>  [usermap]
-  jane.user@example.com = jane
-</para>
-</programlisting>
-<para>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>
-<para>  # regular hgrc file refers to external usermap file
-  [bugzilla]
-  usermap = /home/hg/repos/userdata/bugzilla-usermap.conf
-</para>
-</programlisting>
-<para>While the <filename>usermap</filename> file that it refers to might look like
-this:
-</para>
-<programlisting>
-<para>  # bugzilla-usermap.conf - inside a hg repository
-  [usermap]
-  stephanie@example.com = steph
-</para>
-</programlisting>
-
-</sect3>
-<sect3>
-<title>Configuring the text that gets added to a bug</title>
-
-<para>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
-behaviour.
-</para>
-<itemizedlist>
-<listitem><para><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><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>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>
-<para>  [web]
-  baseurl = http://hg.domain.com/
-</para>
-</programlisting>
-
-<para>Here is an example set of <literal role="hg-ext">bugzilla</literal> hook config information.
-</para>
-<programlisting>
-<para>  [bugzilla]
-  host = bugzilla.example.com
-  password = mypassword
-  version = 2.16
-  # server-side repos live in /home/hg/repos, so strip 4 leading
-  # separators
-  strip = 4
-  hgweb = http://hg.example.com/
-  usermap = /home/hg/repos/notify/bugzilla.conf
-  template = Changeset {node|short}, made by {author} in the {webroot}
-    repo, refers to this bug.\\nFor complete details, see
-    {hgweb}{webroot}?cmd=changeset;node={node|short}\\nChangeset
-    description:\\n\\t{desc|tabindent}
-</para>
-</programlisting>
-
-</sect3>
-<sect3>
-<title>Testing and troubleshooting</title>
-
-<para>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>Recall from section <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>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>
-<para>  hg_user = (httpd_user) NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s
-</para>
-</programlisting>
-<para>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>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>
-<para>  #!/bin/sh
-  cd `dirname $0` &amp;&amp; ./processmail "$1" nobody@example.com
-</para>
-</programlisting>
-<para>It doesn't seem to matter what email address you pass to
-<filename>processmail</filename>.
-</para>
-
-<para>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>
-<para>  cannot find bugzilla user id for john.q.public@example.com
-</para>
-</programlisting>
-<para>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>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>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>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>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>
-<para>  [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
-</para>
-</programlisting>
-
-<para>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><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><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><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><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><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><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 section <xref linkend="sec:hook:sources"/> for
-  the sources you can specify here.
-</para>
-</listitem></itemizedlist>
-
-<para>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>Here is an example set of <literal role="hg-ext">notify</literal> configuration information.
-</para>
-<programlisting>
-<para>  [notify]
-  # really send email
-  test = false
-  # subscriber data lives in the notify repo
-  config = /home/hg/repos/notify/notify.conf
-  # repos live in /home/hg/repos on server, so strip 4 "/" chars
-  strip = 4
-  template = X-Hg-Repo: {webroot}
-    Subject: {webroot}: {desc|firstline|strip}
-    From: {author}
-</para>
-
-<para>    changeset {node|short} in {root}
-    details: {baseurl}{webroot}?cmd=changeset;node={node|short}
-    description:
-      {desc|tabindent|strip}
-</para>
-
-<para>  [web]
-  baseurl = http://hg.example.com/
-</para>
-</programlisting>
-
-<para>This will produce a message that looks like the following:
-</para>
-<programlisting>
-<para>  X-Hg-Repo: tests/slave
-  Subject: tests/slave: Handle error case when slave has no buffers
-  Date: Wed,  2 Aug 2006 15:25:46 -0700 (PDT)
-</para>
-
-<para>  changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave
-  details: http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5
-  description:
-          Handle error case when slave has no buffers
-  diffs (54 lines):
-</para>
-
-<para>  diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h
-  &emdash; a/include/tests.h      Wed Aug 02 15:19:52 2006 -0700
-  +++ b/include/tests.h      Wed Aug 02 15:25:26 2006 -0700
-  @@ -212,6 +212,15 @@ static __inline__ void test_headers(void *h)
-  [...snip...]
-</para>
-</programlisting>
-
-</sect3>
-<sect3>
-<title>Testing and troubleshooting</title>
-
-<para>Do not forget that by default, the <literal role="hg-ext">notify</literal> extension \emph{will
-  not send any mail} 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>
-<title>Information for writers of hooks</title>
-<para>\label{sec:hook:ref}
-</para>
-
-<sect2>
-<title>In-process hook execution</title>
-
-<para>An in-process hook is called with arguments of the following form:
-</para>
-<programlisting>
-<para>  def myhook(ui, repo, **kwargs):
-      pass
-</para>
-</programlisting>
-<para>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>If a parameter is named <literal>node</literal> or
-  <literal>parent<emphasis>N</emphasis></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>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>Boolean-valued parameters are represented as Python
-  <literal>bool</literal> objects.
-</para>
-</listitem></itemizedlist>
-
-<para>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>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>Note that changeset IDs are passed into Python hooks as hexadecimal
-strings, not the binary hashes that Mercurial's APIs normally use.  To
-convert a hash from hex to binary, use the
-\pymodfunc{mercurial.node}{bin} function.
-</para>
-
-</sect2>
-<sect2>
-<title>External hook execution</title>
-
-<para>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>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>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>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>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>
-<title>Sources of changesets</title>
-<para>\label{sec:hook:sources}
-</para>
-
-<para>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><literal>serve</literal>: Changesets are transferred to or from a remote
-  repository over http or ssh.
-</para>
-</listitem>
-<listitem><para><literal>pull</literal>: Changesets are being transferred via a pull from
-  one repository into another.
-</para>
-</listitem>
-<listitem><para><literal>push</literal>: Changesets are being transferred via a push from
-  one repository into another.
-</para>
-</listitem>
-<listitem><para><literal>bundle</literal>: Changesets are being transferred to or from a
-  bundle.
-</para>
-</listitem></itemizedlist>
-
-</sect3>
-<sect3>
-<title>Where changes are going&emdash;remote repository URLs</title>
-<para>\label{sec:hook:url}
-</para>
-
-<para>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>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><literal>remote:ssh:<emphasis>ip-address</emphasis></literal>&emdash;remote ssh client, at
-  the given IP address.
-</para>
-</listitem>
-<listitem><para><literal>remote:http:<emphasis>ip-address</emphasis></literal>&emdash;remote http client, at
-  the given IP address.  If the client is using SSL, this will be of
-  the form <literal>remote:https:<emphasis>ip-address</emphasis></literal>.
-</para>
-</listitem>
-<listitem><para>Empty&emdash;no information could be discovered about the remote
-  client.
-</para>
-</listitem></itemizedlist>
-
-</sect3>
-</sect2>
-</sect1>
-<sect1>
-<title>Hook reference</title>
-
-<sect2>
-<title><literal role="hook">changegroup</literal>&emdash;after remote changesets added</title>
-<para>\label{sec:hook:changegroup}
-</para>
-
-<para>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>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>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><literal>node</literal>: A changeset ID.  The changeset ID of the first
-  changeset in the group that was added.  All changesets between this
-  and \index{tags!<literal>tip</literal>}<literal>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><literal>source</literal>: A string.  The source of these changes.  See
-  section <xref linkend="sec:hook:sources"/> for details.
-</para>
-</listitem>
-<listitem><para><literal>url</literal>: A URL.  The location of the remote repository, if
-  known.  See section <xref linkend="sec:hook:url"/> for more information.
-</para>
-</listitem></itemizedlist>
-
-<para>See also: <literal role="hook">incoming</literal> (section <xref linkend="sec:hook:incoming"/>),
-<literal role="hook">prechangegroup</literal> (section <xref linkend="sec:hook:prechangegroup"/>),
-<literal role="hook">pretxnchangegroup</literal> (section <xref linkend="sec:hook:pretxnchangegroup"/>)
-</para>
-
-</sect2>
-<sect2>
-<title><literal role="hook">commit</literal>&emdash;after a new changeset is created</title>
-<para>\label{sec:hook:commit}
-</para>
-
-<para>This hook is run after a new changeset has been created.
-</para>
-
-<para>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><literal>node</literal>: A changeset ID.  The changeset ID of the newly
-  committed changeset.
-</para>
-</listitem>
-<listitem><para><literal>parent1</literal>: A changeset ID.  The changeset ID of the first
-  parent of the newly committed changeset.
-</para>
-</listitem>
-<listitem><para><literal>parent2</literal>: A changeset ID.  The changeset ID of the second
-  parent of the newly committed changeset.
-</para>
-</listitem></itemizedlist>
-
-<para>See also: <literal role="hook">precommit</literal> (section <xref linkend="sec:hook:precommit"/>),
-<literal role="hook">pretxncommit</literal> (section <xref linkend="sec:hook:pretxncommit"/>)
-</para>
-
-</sect2>
-<sect2>
-<title><literal role="hook">incoming</literal>&emdash;after one remote changeset is added</title>
-<para>\label{sec:hook:incoming}
-</para>
-
-<para>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>You can use this hook for the same purposes as the <literal role="hook">changegroup</literal>
-hook (section <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>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><literal>node</literal>: A changeset ID.  The ID of the newly added
-  changeset.
-</para>
-</listitem>
-<listitem><para><literal>source</literal>: A string.  The source of these changes.  See
-  section <xref linkend="sec:hook:sources"/> for details.
-</para>
-</listitem>
-<listitem><para><literal>url</literal>: A URL.  The location of the remote repository, if
-  known.  See section <xref linkend="sec:hook:url"/> for more information.
-</para>
-</listitem></itemizedlist>
-
-<para>See also: <literal role="hook">changegroup</literal> (section <xref linkend="sec:hook:changegroup"/>) <literal role="hook">prechangegroup</literal> (section <xref linkend="sec:hook:prechangegroup"/>), <literal role="hook">pretxnchangegroup</literal> (section <xref linkend="sec:hook:pretxnchangegroup"/>)
-</para>
-
-</sect2>
-<sect2>
-<title><literal role="hook">outgoing</literal>&emdash;after changesets are propagated</title>
-<para>\label{sec:hook:outgoing}
-</para>
-
-<para>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>One possible use for this hook is to notify administrators that
-changes have been pulled.
-</para>
-
-<para>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><literal>node</literal>: A changeset ID.  The changeset ID of the first
-  changeset of the group that was sent.
-</para>
-</listitem>
-<listitem><para><literal>source</literal>: A string.  The source of the of the operation
-  (see section <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><literal>url</literal>: A URL.  The location of the remote repository, if
-  known.  See section <xref linkend="sec:hook:url"/> for more information.
-</para>
-</listitem></itemizedlist>
-
-<para>See also: <literal role="hook">preoutgoing</literal> (section <xref linkend="sec:hook:preoutgoing"/>)
-</para>
-
-</sect2>
-<sect2>
-<title><literal role="hook">prechangegroup</literal>&emdash;before starting to add remote changesets</title>
-<para>\label{sec:hook:prechangegroup}
-</para>
-
-<para>This controlling hook is run before Mercurial begins to add a group of
-changesets from another repository.
-</para>
-
-<para>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>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>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><literal>source</literal>: A string.  The source of these changes.  See
-  section <xref linkend="sec:hook:sources"/> for details.
-</para>
-</listitem>
-<listitem><para><literal>url</literal>: A URL.  The location of the remote repository, if
-  known.  See section <xref linkend="sec:hook:url"/> for more information.
-</para>
-</listitem></itemizedlist>
-
-<para>See also: <literal role="hook">changegroup</literal> (section <xref linkend="sec:hook:changegroup"/>),
-<literal role="hook">incoming</literal> (section <xref linkend="sec:hook:incoming"/>), ,
-<literal role="hook">pretxnchangegroup</literal> (section <xref linkend="sec:hook:pretxnchangegroup"/>)
-</para>
-
-</sect2>
-<sect2>
-<title><literal role="hook">precommit</literal>&emdash;before starting to commit a changeset</title>
-<para>\label{sec:hook:precommit}
-</para>
-
-<para>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>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>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><literal>parent1</literal>: A changeset ID.  The changeset ID of the first
-  parent of the working directory.
-</para>
-</listitem>
-<listitem><para><literal>parent2</literal>: A changeset ID.  The changeset ID of the second
-  parent of the working directory.
-</para>
-</listitem></itemizedlist>
-<para>If the commit proceeds, the parents of the working directory will
-become the parents of the new changeset.
-</para>
-
-<para>See also: <literal role="hook">commit</literal> (section <xref linkend="sec:hook:commit"/>),
-<literal role="hook">pretxncommit</literal> (section <xref linkend="sec:hook:pretxncommit"/>)
-</para>
-
-</sect2>
-<sect2>
-<title><literal role="hook">preoutgoing</literal>&emdash;before starting to propagate changesets</title>
-<para>\label{sec:hook:preoutgoing}
-</para>
-
-<para>This hook is invoked before Mercurial knows the identities of the
-changesets to be transmitted.
-</para>
-
-<para>One use for this hook is to prevent changes from being transmitted to
-another repository.
-</para>
-
-<para>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><literal>source</literal>: A string.  The source of the operation that is
-  attempting to obtain changes from this repository (see
-  section <xref linkend="sec:hook:sources"/>).  See the documentation for the
-  <literal>source</literal> parameter to the <literal role="hook">outgoing</literal> hook, in
-  section <xref linkend="sec:hook:outgoing"/>, for possible values of this
-  parameter.
-</para>
-</listitem>
-<listitem><para><literal>url</literal>: A URL.  The location of the remote repository, if
-  known.  See section <xref linkend="sec:hook:url"/> for more information.
-</para>
-</listitem></itemizedlist>
-
-<para>See also: <literal role="hook">outgoing</literal> (section <xref linkend="sec:hook:outgoing"/>)
-</para>
-
-</sect2>
-<sect2>
-<title><literal role="hook">pretag</literal>&emdash;before tagging a changeset</title>
-<para>\label{sec:hook:pretag}
-</para>
-
-<para>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>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><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><literal>node</literal>: A changeset ID.  The ID of the changeset to be tagged.
-</para>
-</listitem>
-<listitem><para><literal>tag</literal>: A string.  The name of the tag to be created.
-</para>
-</listitem></itemizedlist>
-
-<para>If the tag to be created is revision-controlled, the <literal role="hook">precommit</literal>
-and <literal role="hook">pretxncommit</literal> hooks (sections <xref linkend="sec:hook:commit"/>
-and <xref linkend="sec:hook:pretxncommit"/>) will also be run.
-</para>
-
-<para>See also: <literal role="hook">tag</literal> (section <xref linkend="sec:hook:tag"/>)
-</para>
-
-<para>\subsection{<literal role="hook">pretxnchangegroup</literal>&emdash;before completing addition of
-  remote changesets}
-\label{sec:hook:pretxnchangegroup}
-</para>
-
-<para>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>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>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>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>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><literal>node</literal>: A changeset ID.  The changeset ID of the first
-  changeset in the group that was added.  All changesets between this
-  and \index{tags!<literal>tip</literal>}<literal>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><literal>source</literal>: A string.  The source of these changes.  See
-  section <xref linkend="sec:hook:sources"/> for details.
-</para>
-</listitem>
-<listitem><para><literal>url</literal>: A URL.  The location of the remote repository, if
-  known.  See section <xref linkend="sec:hook:url"/> for more information.
-</para>
-</listitem></itemizedlist>
-
-<para>See also: <literal role="hook">changegroup</literal> (section <xref linkend="sec:hook:changegroup"/>),
-<literal role="hook">incoming</literal> (section <xref linkend="sec:hook:incoming"/>),
-<literal role="hook">prechangegroup</literal> (section <xref linkend="sec:hook:prechangegroup"/>)
-</para>
-
-</sect2>
-<sect2>
-<title><literal role="hook">pretxncommit</literal>&emdash;before completing commit of new changeset</title>
-<para>\label{sec:hook:pretxncommit}
-</para>
-
-<para>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>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>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>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><literal>node</literal>: A changeset ID.  The changeset ID of the newly
-  committed changeset.
-</para>
-</listitem>
-<listitem><para><literal>parent1</literal>: A changeset ID.  The changeset ID of the first
-  parent of the newly committed changeset.
-</para>
-</listitem>
-<listitem><para><literal>parent2</literal>: A changeset ID.  The changeset ID of the second
-  parent of the newly committed changeset.
-</para>
-</listitem></itemizedlist>
-
-<para>See also: <literal role="hook">precommit</literal> (section <xref linkend="sec:hook:precommit"/>)
-</para>
-
-</sect2>
-<sect2>
-<title><literal role="hook">preupdate</literal>&emdash;before updating or merging working directory</title>
-<para>\label{sec:hook:preupdate}
-</para>
-
-<para>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>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><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><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>See also: <literal role="hook">update</literal> (section <xref linkend="sec:hook:update"/>)
-</para>
-
-</sect2>
-<sect2>
-<title><literal role="hook">tag</literal>&emdash;after tagging a changeset</title>
-<para>\label{sec:hook:tag}
-</para>
-
-<para>This hook is run after a tag has been created.
-</para>
-
-<para>Parameters to this hook:
-</para>
-<itemizedlist>
-<listitem><para><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><literal>node</literal>: A changeset ID.  The ID of the changeset that was
-  tagged.
-</para>
-</listitem>
-<listitem><para><literal>tag</literal>: A string.  The name of the tag that was created.
-</para>
-</listitem></itemizedlist>
-
-<para>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>See also: <literal role="hook">pretag</literal> (section <xref linkend="sec:hook:pretag"/>)
-</para>
-
-</sect2>
-<sect2>
-<title><literal role="hook">update</literal>&emdash;after updating or merging working directory</title>
-<para>\label{sec:hook:update}
-</para>
-
-<para>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><literal>error</literal>: A boolean.  Indicates whether the update or
-  merge completed successfully.
-</para>
-</listitem>
-<listitem><para><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><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>See also: <literal role="hook">preupdate</literal> (section <xref linkend="sec:hook:preupdate"/>)
-</para>
-
-</sect2>
-</sect1>
+<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:
--->
\ No newline at end of file
+-->
diff -r c075fb0481c0 -r f0110009e946 fr/ch11-template.xml
--- a/fr/ch11-template.xml	Wed Sep 09 15:25:09 2009 +0200
+++ b/fr/ch11-template.xml	Wed Sep 09 16:07:36 2009 +0200
@@ -1,689 +1,685 @@
 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter>
-<title>Customising the output of Mercurial</title>
-<para>\label{chap:template}</para>
-
-<para>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
-customise the entire appearance of the built-in web interface.</para>
-
-<sect1>
-<title>Using precanned output styles</title>
-<para>\label{sec:style}</para>
-
-<para>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>Before we take a look at Mercurial's bundled styles, let's review its
-normal output.</para>
-
-<para><!-- &interaction.template.simple.normal; --></para>
-
-<para>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>
-
-<para><!-- &interaction.template.simple.compact; --></para>
-
-<para>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>
-
-<para><!-- &interaction.template.simple.changelog; -->
-</para>
-
-<para>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>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>
-<para>  [ui]
-  style = compact
-</para>
-</programlisting>
-
-<para>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>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>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 customisable 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>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>Before we continue, let's look again at a simple example of
-Mercurial's normal output.
-</para>
-
-<para><!-- &interaction.template.simple.normal; -->
-</para>
-
-<para>Now, let's run the same command, but using a template to change its
-output.
-</para>
-
-<para><!-- &interaction.template.simple.simplest; -->
-</para>
-
-<para>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>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
-section <xref linkend="sec:template:escape"/> for more details of escape sequences.
-</para>
-
-<para>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>
-
-<para><!-- &interaction.template.simple.simplesub; -->
-</para>
-
-<para>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>\texttt{}}</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 section <xref linkend="sec:template:escape"/>.
-</para>
-
-</sect1>
-<sect1>
-<title>Common template keywords</title>
-<para>\label{sec:template:keyword}
-</para>
-
-<para>You can start writing simple templates immediately using the keywords
-below.
-</para>
-
-<itemizedlist>
-<listitem><para><literal role="template-keyword">author</literal>: String.  The unmodified author of the changeset.
-</para>
-</listitem>
-<listitem><para><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><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
-  section <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><literal role="template-keyword">desc</literal>: String.  The text of the changeset description.
-</para>
-</listitem>
-<listitem><para><literal role="template-keyword">files</literal>: List of strings.  All files modified, added, or
-  removed by this changeset.
-</para>
-</listitem>
-<listitem><para><literal role="template-keyword">file_adds</literal>: List of strings.  Files added by this
-  changeset.
-</para>
-</listitem>
-<listitem><para><literal role="template-keyword">file_dels</literal>: List of strings.  Files removed by this
-  changeset.
-</para>
-</listitem>
-<listitem><para><literal role="template-keyword">node</literal>: String.  The changeset identification hash, as a
-  40-character hexadecimal string.
-</para>
-</listitem>
-<listitem><para><literal role="template-keyword">parents</literal>: List of strings.  The parents of the
-  changeset.
-</para>
-</listitem>
-<listitem><para><literal role="template-keyword">rev</literal>: Integer.  The repository-local changeset revision
-  number.
-</para>
-</listitem>
-<listitem><para><literal role="template-keyword">tags</literal>: List of strings.  Any tags associated with the
-  changeset.
-</para>
-</listitem></itemizedlist>
-
-<para>A few simple experiments will show us what to expect when we use these
-keywords; you can see the results in
-figure <xref linkend="fig:template:keywords"/>.
-</para>
-
-<informalfigure>
-<para>  <!-- &interaction.template.simple.keywords; -->
-  <caption><para>Template keywords in use</para></caption>
-  \label{fig:template:keywords}
-</para>
-</informalfigure>
-
-<para>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 section <xref linkend="sec:template:filter"/>.
-</para>
-
-<para><!-- &interaction.template.simple.datekeyword; -->
-</para>
-
-</sect1>
-<sect1>
-<title>Escape sequences</title>
-<para>\label{sec:template:escape}
-</para>
-
-<para>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><literal>\textbackslash\textbackslash</literal>: Backslash, <quote><literal>\</literal></quote>,
-  ASCII 134.
-</para>
-</listitem>
-<listitem><para><literal>\textbackslash n</literal>: Newline, ASCII 12.
-</para>
-</listitem>
-<listitem><para><literal>\textbackslash r</literal>: Carriage return, ASCII 15.
-</para>
-</listitem>
-<listitem><para><literal>\textbackslash t</literal>: Tab, ASCII 11.
-</para>
-</listitem>
-<listitem><para><literal>\textbackslash v</literal>: Vertical tab, ASCII 13.
-</para>
-</listitem>
-<listitem><para><literal>\textbackslash {</literal>: Open curly brace, <quote><literal>{</literal></quote>, ASCII 173.
-</para>
-</listitem>
-<listitem><para><literal>\textbackslash }</literal>: Close curly brace, <quote><literal>}</literal></quote>, ASCII 175.
-</para>
-</listitem></itemizedlist>
-
-<para>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>
-<title>Filtering keywords to change their results</title>
-<para>\label{sec:template:filter}
-</para>
-
-<para>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>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><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><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><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><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><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><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><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><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><literal role="template-filter">fill76</literal>: Any text.  Wrap the text to fit in 76
-  columns.
-</para>
-</listitem>
-<listitem><para><literal role="template-filter">firstline</literal>: Any text.  Yield the first line of text,
-  without any trailing newlines.
-</para>
-</listitem>
-<listitem><para><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><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><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><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><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><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><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><literal role="template-filter">strip</literal>: Any text.  Strip all leading and trailing
-  whitespace from the string.
-</para>
-</listitem>
-<listitem><para><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><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><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>
-
-<informalfigure>
-<para>  <!-- &interaction.template.simple.manyfilters; -->
-  <caption><para>Template filters in action</para></caption>
-  \label{fig:template:filters}
-</para>
-</informalfigure>
-
-<note>
-<para>  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>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>
-
-<para><!-- &interaction.template.simple.combine; -->
-</para>
-
-<para>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>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>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>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>Our simple style file contains just one line:
-</para>
-
-<para><!-- &interaction.template.simple.rev; -->
-</para>
-
-<para>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>The syntax rules for a style file are simple.
-</para>
-
-<itemizedlist>
-<listitem><para>The file is processed one line at a time.
-</para>
-</listitem>
-</para>
-</listitem>
-<listitem><para>Leading and trailing white space are ignored.
-</para>
-</listitem>
-</para>
-</listitem>
-<listitem><para>Empty lines are skipped.
-</para>
-</listitem>
-</para>
-</listitem>
-<listitem><para>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>
-</para>
-</listitem>
-<listitem><para>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>
-</para>
-</listitem>
-<listitem><para>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>
-</para>
-</listitem>
-<listitem><para>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>
-</para>
-</listitem>
-<listitem><para>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>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>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>
-
-<para><!-- &interaction.template.svnstyle.syntax.input; -->
-</para>
-
-<para>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>
-
-<para><!-- &interaction.template.svnstyle.syntax.error; -->
-</para>
-
-<para>This error message looks intimidating, but it is not too hard to
-follow.
-</para>
-
-<itemizedlist>
-<listitem><para>The first component is simply Mercurial's way of saying <quote>I am
-  giving up</quote>.
-</para>
-</listitem><programlisting>
-<listitem><para>    <emphasis role="bold">abort:</emphasis> broken.style:1: parse error
-</para>
-</listitem></programlisting>
-
-</para>
-</listitem>
-<listitem><para>Next comes the name of the style file that contains the error.
-</para>
-</listitem><programlisting>
-<listitem><para>    abort: <emphasis role="bold">broken.style</emphasis>:1: parse error
-</para>
-</listitem></programlisting>
-
-</para>
-</listitem>
-<listitem><para>Following the file name is the line number where the error was
-  encountered.
-</para>
-</listitem><programlisting>
-<listitem><para>    abort: broken.style:<emphasis role="bold">1</emphasis>: parse error
-</para>
-</listitem></programlisting>
-
-</para>
-</listitem>
-<listitem><para>Finally, a description of what went wrong.
-</para>
-</listitem><programlisting>
-<listitem><para>    abort: broken.style:1: <emphasis role="bold">parse error</emphasis>
-</para>
-</listitem></programlisting>
-<listitem><para>  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>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.
-<!-- &interaction.template.svnstyle.id; -->
-This is not guaranteed to be unique, but it is nevertheless useful in
-many cases.
-</para>
-<itemizedlist>
-<listitem><para>It will not work in a completely empty repository, because such
-  a repository does not have a revision zero.
-</para>
-</listitem>
-<listitem><para>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>Here are some uses to which you could put this identifier:
-</para>
-<itemizedlist>
-<listitem><para>As a key into a table for a database that manages repositories
-  on a server.
-</para>
-</listitem>
-<listitem><para>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>Mimicking Subversion's output</title>
-
-<para>Let's try to emulate the default output format used by another
-revision control tool, Subversion.
-<!-- &interaction.template.svnstyle.short; -->
-</para>
-
-<para>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.
-<!-- &interaction.template.svnstyle.template; -->
-</para>
-
-<para>There are a few small ways in which this template deviates from the
-output produced by Subversion.
-</para>
-<itemizedlist>
-<listitem><para>Subversion prints a <quote>readable</quote> date (the <quote>\texttt{Wed, 27 Sep
-    2006}</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>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>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>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.
-<!-- &interaction.template.svnstyle.style; -->
-</para>
-
-<para>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 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:
--->
\ No newline at end of file
+-->
diff -r c075fb0481c0 -r f0110009e946 fr/ch12-mq.xml
--- a/fr/ch12-mq.xml	Wed Sep 09 15:25:09 2009 +0200
+++ b/fr/ch12-mq.xml	Wed Sep 09 16:07:36 2009 +0200
@@ -1,1309 +1,1368 @@
 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter>
-<title>Managing change with Mercurial Queues</title>
-<para>\label{chap:mq}</para>
-
-<sect1>
-<title>The patch management problem</title>
-<para>\label{sec:mq:patch-mgmt}</para>
-
-<para>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>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>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>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>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 section <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>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>Fortunately, Mercurial includes a powerful extension, Mercurial Queues
-(or simply <quote>MQ</quote>), that massively simplifies the patch management
-problem.
-</para>
-
-</sect1>
-<sect1>
-<title>The prehistory of Mercurial Queues</title>
-<para>\label{sec:mq:history}
-</para>
-
-<para>During the late 1990s, several Linux kernel developers started to
-maintain <quote>patch series</quote> that modified the behaviour of the Linux
-kernel.  Some of these series were focused on stability, some on
-feature coverage, and others were more speculative.
-</para>
-
-<para>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>
-<title>A patchwork quilt</title>
-<para>\label{sec:mq:quilt}
-</para>
-
-<para>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>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>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>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>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>
-<title>From patchwork quilt to Mercurial Queues</title>
-<para>\label{sec:mq:quilt-mq}
-</para>
-
-<para>In mid-2005, Chris Mason took the features of quilt and wrote an
-extension that he called Mercurial Queues, which added quilt-like
-behaviour to Mercurial.
-</para>
-
-<para>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>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>I cannot overstate the value that MQ offers through the unification of
-patches and revision control.
-</para>
-
-<para>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>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>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>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 use
-<command role="hg-cmd">hg log <emphasis>filename</emphasis></command> to see which changesets and patches
-affected a file.  You can use the <literal role="hg-ext">bisect</literal> 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>
-<title>Understanding patches</title>
-<para>\label{sec:mq:patch}
-</para>
-
-<para>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>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 at figure <xref linkend="ex:mq:diff"/> for a simple example of
-these commands in action.
-</para>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.dodiff.diff; -->
-  <caption><para>Simple uses of the <command>diff</para></caption> and \command{patch</command> commands}
-  \label{ex:mq:diff}
-</para>
-</informalfigure>
-
-<para>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>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>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>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>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>We will return to some of the more subtle aspects of patches later (in
-section <xref linkend="sec:mq:adv-patch"/>), but you should have enough information
-now to use MQ.
-</para>
-
-</sect1>
-<sect1>
-<title>Getting started with Mercurial Queues</title>
-<para>\label{sec:mq:start}
-</para>
-
-<para>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 in figure <xref linkend="ex:mq:config"/>.
-</para>
-
-<informalfigure>
-<programlisting>
-<para>    [extensions]
-    hgext.mq =
-</para>
-</programlisting>
-<para>  \label{ex:mq:config}
-  <caption><para>Contents to add to <filename role="home">~/.hgrc</para></caption> to enable the MQ extension</filename>
-</para>
-</informalfigure>
-
-<para>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; see
-the example in figure <xref linkend="ex:mq:enabled"/>.
-</para>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.qinit-help.help; -->
-  <caption><para>How to verify that MQ is enabled</para></caption>
-  \label{ex:mq:enabled}
-</para>
-</informalfigure>
-
-<para>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 (see
-figure <xref linkend="ex:mq:qinit"/>).  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>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.tutorial.qinit; -->
-  <caption><para>Preparing a repository for use with MQ</para></caption>
-  \label{ex:mq:qinit}
-</para>
-</informalfigure>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.tutorial.qnew; -->
-  <caption><para>Creating a new patch</para></caption>
-  \label{ex:mq:qnew}
-</para>
-</informalfigure>
-
-<sect2>
-<title>Creating a new patch</title>
-
-<para>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.  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 in figure <xref linkend="ex:mq:qnew"/>.
-</para>
-
-<para>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>  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>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>When you reach a point where you want to save your work, use the
-<command role="hg-ext-mq">qrefresh</command> command (figure <xref linkend="ex:mq:qnew"/>) to update the patch
-you are working on.  This command folds the changes you have made in
-the working directory into your patch, and updates its corresponding
-changeset to contain those changes.
-</para>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.tutorial.qrefresh; -->
-  <caption><para>Refreshing a patch</para></caption>
-  \label{ex:mq:qrefresh}
-</para>
-</informalfigure>
-
-<para>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>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.tutorial.qrefresh2; -->
-  <caption><para>Refresh a patch many times to accumulate changes</para></caption>
-  \label{ex:mq:qrefresh2}
-</para>
-</informalfigure>
-
-</sect2>
-<sect2>
-<title>Stacking and tracking patches</title>
-
-<para>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.  See
-figure <xref linkend="ex:mq:qnew2"/> for an example.  Notice that the patch
-contains the changes in our prior patch as part of its context (you
-can see this more clearly in the output of <command role="hg-cmd">hg annotate</command>).
-</para>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.tutorial.qnew2; -->
-  <caption><para>Stacking a second patch on top of the first</para></caption>
-  \label{ex:mq:qnew2}
-</para>
-</informalfigure>
-
-<para>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 in figure <xref linkend="ex:mq:qseries"/>:
-</para>
-
-<itemizedlist>
-<listitem><para>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>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>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.tutorial.qseries; -->
-  \caption{Understanding the patch stack with <command role="hg-ext-mq">qseries</command> and
-    <command role="hg-ext-mq">qapplied</command>}
-  \label{ex:mq:qseries}
-</para>
-</informalfigure>
-
-</sect2>
-<sect2>
-<title>Manipulating the patch stack</title>
-
-<para>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>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.  Figure <xref linkend="fig:mq:stack"/> illustrates the
-difference between applied and tracked patches.
-</para>
-
-<informalfigure>
-
-<para>  <mediaobject><imageobject><imagedata fileref="mq-stack"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>
-  <caption><para>Applied and unapplied patches in the MQ patch stack</para></caption>
-  \label{fig:mq:stack}
-</para>
-</informalfigure>
-
-<para>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 figure <xref linkend="ex:mq:qpop"/> for examples of <command role="hg-ext-mq">qpop</command>
-and <command role="hg-ext-mq">qpush</command> in action.  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>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.tutorial.qpop; -->
-  <caption><para>Modifying the stack of applied patches</para></caption>
-  \label{ex:mq:qpop}
-</para>
-</informalfigure>
-
-</sect2>
-<sect2>
-<title>Pushing and popping many patches</title>
-
-<para>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">-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 section <xref linkend="sec:mq:perf"/> below.)
-</para>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.tutorial.qpush-a; -->
-  <caption><para>Pushing all unapplied patches</para></caption>
-  \label{ex:mq:qpush-a}
-</para>
-</informalfigure>
-
-</sect2>
-<sect2>
-<title>Safety checks, and overriding them</title>
-
-<para>Several MQ commands check the working directory before they do
-anything, and fail if they find any modifications.  They do this to
-ensure that you won't lose any changes that you have made, but not yet
-incorporated into a patch.  Figure <xref linkend="ex:mq:add"/> 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>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.tutorial.add; -->
-  <caption><para>Forcibly creating a patch</para></caption>
-  \label{ex:mq:add}
-</para>
-</informalfigure>
-
-<para>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">-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">-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>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>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>
-<title>More about patches</title>
-<para>\label{sec:mq:adv-patch}
-</para>
-
-<para>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>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>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>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>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>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>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 -p<emphasis>N</emphasis></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">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.
-</sect2>
-<sect2>
-<title>Strategies for applying a patch</title>
-</para>
-
-<para>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>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>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>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>There are a few useful things to know about how <command>patch</command> works
-with files.
-</para>
-<itemizedlist>
-<listitem><para>This should already be obvious, but <command>patch</command> cannot
-  handle binary files.
-</para>
-</listitem>
-<listitem><para>Neither does it care about the executable bit; it creates new
-  files as readable, but not executable.
-</para>
-</listitem>
-<listitem><para><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>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>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><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>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>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>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>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 section <xref linkend="sec:mq:merge"/> for details.
-</para>
-
-<para>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>If you're feeling adventurous, Neil Brown, a Linux kernel hacker,
-wrote a tool called <command>wiggle</command> <citation>web:wiggle</citation>, which is more
-vigorous than <command>patch</command> in its attempts to make a patch apply.
-</para>
-
-<para>Another Linux kernel hacker, Chris Mason (the author of Mercurial
-Queues), wrote a similar tool called
-<command>mpatch</command> <citation>web:mpatch</citation>, 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>The context in the middle of a hunk has changed.
-</para>
-</listitem>
-<listitem><para>A hunk is missing some context at the beginning or end.
-</para>
-</listitem>
-<listitem><para>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>A hunk removes lines with slightly different content than those
-  currently present in the file.
-</para>
-</listitem></itemizedlist>
-
-<para>If you use <command>wiggle</command> or <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>Getting the best performance out of MQ</title>
-<para>\label{sec:mq:perf}
-</para>
-
-<para>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 <citation>web:europython</citation>.  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>On my old, slow laptop, I was able to
-<command role="hg-cmd">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">-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">-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>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>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>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>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>
-<title>Updating your patches when the underlying code changes</title>
-<para>\label{sec:mq:merge}
-</para>
-
-<para>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>The simplest way to do this is to <command role="hg-cmd">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">-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">-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>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>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>The process is a little involved.
-</para>
-<orderedlist>
-<listitem><para>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>Save a backup copy of your patch directory using
-  <command role="hg-cmd">hg qsave <option role="hg-ext-mq-cmd-qsave-opt">-e</option> <option role="hg-ext-mq-cmd-qsave-opt">-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.<emphasis>N</filename></emphasis>, where <literal><emphasis>N</emphasis></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>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>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>Merge all patches using \hgcmdargs{qpush}{<option role="hg-ext-mq-cmd-qpush-opt">-m</option>
-    <option role="hg-ext-mq-cmd-qpush-opt">-a</option>}.  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>During the <command role="hg-cmd">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">-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>When you finish resolving the effects of a patch, MQ refreshes your
-patch based on the result of the merge.
-</para>
-
-<para>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.<emphasis>N</filename></emphasis>. You can remove the extra head using
-<command role="hg-cmd">hg qpop <option role="hg-ext-mq-cmd-qpop-opt">-a</option> <option role="hg-ext-mq-cmd-qpop-opt">-n</option> patches.<emphasis>N</emphasis></command>
-or <command role="hg-cmd">hg strip</command>.  You can delete <filename role="special" class="directory">.hg/patches.<emphasis>N</filename></emphasis> once
-you are sure that you no longer need it as a backup.
-</para>
-
-</sect1>
-<sect1>
-<title>Identifying patches</title>
-
-<para>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>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>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>MQ also makes it easy to work with patches when you are using normal
-Mercurial commands.  Every command that accepts a changeset ID will
-also accept the name of an applied patch.  MQ augments the tags
-normally in the repository with an eponymous one for each applied
-patch.  In addition, the special tags \index{tags!special tag
-  names!<literal>qbase</literal>}<literal>qbase</literal> and \index{tags!special tag
-  names!<literal>qtip</literal>}<literal>qtip</literal> identify the <quote>bottom-most</quote> and
-topmost applied patches, respectively.
-</para>
-
-<para>These additions to Mercurial's normal tagging capabilities make
-dealing with patches even more of a breeze.
-</para>
-<itemizedlist>
-<listitem><para>Want to patchbomb a mailing list with your latest series of
-  changes?
-</para>
-</listitem><programlisting>
-<listitem><para>    hg email qbase:qtip
-</para>
-</listitem></programlisting>
-<listitem><para>  (Don't know what <quote>patchbombing</quote> is?  See
-  section <xref linkend="sec:hgext:patchbomb"/>.)
-</para>
-</listitem>
-<listitem><para>Need to see all of the patches since <literal>foo.patch</literal> that
-  have touched files in a subdirectory of your tree?
-</para>
-</listitem><programlisting>
-<listitem><para>    hg log -r foo.patch:qtip <emphasis>subdir</emphasis>
-</para>
-</listitem></programlisting>
-</itemizedlist>
-
-<para>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>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.id.output; -->
-  <caption><para>Using MQ's tag features to work with patches</para></caption>
-  \label{ex:mq:id}
-</para>
-</informalfigure>
-
-<para>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.  Figure <xref linkend="ex:mq:id"/> shows a few normal Mercurial
-commands in use with applied patches.
-</para>
-
-</sect1>
-<sect1>
-<title>Useful things to know about</title>
-
-<para>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>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
-  section <xref linkend="sec:mqref:cmd:qpush"/> for information as to why this is.
-</para>
-</listitem>
-<listitem><para>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>
-<title>Managing patches in a repository</title>
-<para>\label{sec:mq:repo}
-</para>
-
-<para>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>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>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>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>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">-c</option> option to
-create the <filename role="special" class="directory">.hg/patches</filename> directory as a Mercurial repository.
-</para>
-
-<note>
-<para>  If you forget to use the <option role="hg-ext-mq-cmd-qinit-opt">-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>  (<command role="hg-cmd">hg qinit <option role="hg-ext-mq-cmd-qinit-opt">-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>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>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>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>
-<para>  alias mq=`hg -R $(hg root)/.hg/patches'
-</para>
-</programlisting>
-
-<para>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>MQ's support for working with a repository full of patches is limited
-in a few small respects.
-</para>
-
-<para>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">-a</option></command> and then
-<command role="hg-cmd">hg qpush <option role="hg-ext-mq-cmd-qpush-opt">-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>
-<title>Third party tools for working with patches</title>
-<para>\label{sec:mq:tools}
-</para>
-
-<para>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>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>
-
-<informalfigure>
-<para>  <!-- &interaction.mq.tools.tools; -->
-  <caption><para>The <command>diffstat</para></caption>, \command{filterdiff</command>, and <command>lsdiff</command> commands}
-  \label{ex:mq:tools}
-</para>
-</informalfigure>
-
-<para>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
-section <xref linkend="mq-collab:tips:interdiff"/> for another example.
-</para>
-
-</sect1>
-<sect1>
-<title>Good ways to work with patches</title>
-
-<para>Whether you are working on a patch series to submit to a free software
-or open source project, or a series that you intend to treat as a
-sequence of regular changesets when you're done, you can use some
-simple techniques to keep your work well organised.
-</para>
-
-<para>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>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>For this reason, it is very much worth investing a little time to
-learn how to use some of the third-party tools I described in
-section <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>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>Begin by downloading and unpacking the source tarball,
-and turning it into a Mercurial repository.
-<!-- &interaction.mq.tarball.download; -->
-</para>
-
-<para>Continue by creating a patch stack and making your changes.
-<!-- &interaction.mq.tarball.qinit; -->
-</para>
-
-<para>Let's say a few weeks or months pass, and your package author releases
-a new version.  First, bring their changes into the repository.
-<!-- &interaction.mq.tarball.newsource; -->
-The pipeline starting with <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>Finally, you can apply your patches on top of the new tree.
-<!-- &interaction.mq.tarball.repush; -->
-</para>
-
-</sect2>
-<sect2>
-<title>Combining entire patches</title>
-<para>\label{sec:mq:combine}
-</para>
-
-<para>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>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>Merging <emphasis>part</emphasis> of one patch into another is more difficult than
-combining entire patches.
-</para>
-
-<para>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>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.
-<!-- &interaction.mq.tools.lsdiff; -->
-</para>
-
-<para>This command prints three different kinds of number:
-</para>
-<itemizedlist>
-<listitem><para>(in the first column) a <emphasis>file number</emphasis> to identify each file
-  modified in the patch;
-</para>
-</listitem>
-<listitem><para>(on the next line, indented) the line number within a modified
-  file where a hunk starts; and
-</para>
-</listitem>
-<listitem><para>(on the same line) a <emphasis>hunk number</emphasis> to identify that hunk.
-</para>
-</listitem></itemizedlist>
-
-<para>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>Once you have this hunk, you can concatenate it onto the end of your
-destination patch and continue with the remainder of
-section <xref linkend="sec:mq:combine"/>.
-</para>
-
-</sect2>
-</sect1>
-<sect1>
-<title>Differences between quilt and MQ</title>
-
-<para>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>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 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:
--->
\ No newline at end of file
+-->
diff -r c075fb0481c0 -r f0110009e946 fr/ch13-mq-collab.xml
--- a/fr/ch13-mq-collab.xml	Wed Sep 09 15:25:09 2009 +0200
+++ b/fr/ch13-mq-collab.xml	Wed Sep 09 16:07:36 2009 +0200
@@ -1,499 +1,525 @@
 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter>
-<title>Advanced uses of Mercurial Queues</title>
-<para>\label{chap:mq-collab}</para>
-
-<para>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>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>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>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>To maintain a driver, we have to keep a number of distinct versions of
-Linux in mind.</para>
-<itemizedlist>
-<listitem><para>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>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>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>There are two <quote>standard</quote> ways to maintain a piece of software that
-has to target many different environments.
-</para>
-
-<para>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>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>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>These approaches have the added weakness of making it difficult to
-generate well-formed patches to submit upstream.
-</para>
-
-<para>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>
-
-<para>\section{Conditionally applying patches with
-  guards}
-</para>
-
-<para>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.
-<!-- &interaction.mq.guards.init; -->
-This gives us a tiny repository that contains two patches that don't
-have any dependencies on each other, because they touch different files.
-</para>
-
-<para>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>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>
-
-</sect2>
-</sect1>
-<sect1>
-<title>Controlling the guards on a patch</title>
-
-<para>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.
-<!-- &interaction.mq.guards.qguard; -->
-To set a positive guard on a patch, prefix the name of the guard with
-a <quote><literal>+</literal></quote>.
-<!-- &interaction.mq.guards.qguard.pos; -->
-To set a negative guard on a patch, prefix the name of the guard with
-a <quote><literal>-</literal></quote>.
-<!-- &interaction.mq.guards.qguard.neg; -->
-</para>
-
-<note>
-<para>  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>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.)
-<!-- &interaction.mq.guards.series; -->
-</para>
-
-</sect1>
-<sect1>
-<title>Selecting the guards to use</title>
-
-<para>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>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.
-<!-- &interaction.mq.guards.qselect.foo; -->
-In case you're interested, the currently selected guards are stored in
-the <filename role="special">guards</filename> file.
-<!-- &interaction.mq.guards.qselect.cat; -->
-We can see the effect the selected guards have when we run
-<command role="hg-ext-mq">qpush</command>.
-<!-- &interaction.mq.guards.qselect.qpush; -->
-</para>
-
-<para>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:
-<!-- &interaction.mq.guards.qselect.error; -->
-Changing the selected guards changes the patches that are applied.
-<!-- &interaction.mq.guards.qselect.quux; -->
-You can see in the example below that negative guards take precedence
-over positive guards.
-<!-- &interaction.mq.guards.qselect.foobar; -->
-</para>
-
-</sect1>
-<sect1>
-<title>MQ's rules for applying patches</title>
-
-<para>The rules that MQ uses when deciding whether to apply a patch
-are as follows.
-</para>
-<itemizedlist>
-<listitem><para>A patch that has no guards is always applied.
-</para>
-</listitem>
-<listitem><para>If the patch has any negative guard that matches any currently
-  selected guard, the patch is skipped.
-</para>
-</listitem>
-<listitem><para>If the patch has any positive guard that matches any currently
-  selected guard, the patch is applied.
-</para>
-</listitem>
-<listitem><para>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>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>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>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>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>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>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>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>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>The <quote>in progress</quote> group.  Patches that are actively being
-  developed, and should not be submitted anywhere yet.
-</para>
-</listitem>
-<listitem><para>The <quote>backport</quote> group.  Patches that adapt the source tree to
-  older versions of the kernel tree.
-</para>
-</listitem>
-<listitem><para>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>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>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>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>In my work, I use a number of guards to control which patches are to
-be applied.
-</para>
-
-<itemizedlist>
-<listitem><para><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>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>Those patches that need reworking before being resubmitted are
-  guarded with <literal>rework</literal>.
-</para>
-</listitem>
-<listitem><para>For those patches that are still under development, I use
-  <literal>devel</literal>.
-</para>
-</listitem>
-<listitem><para>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>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>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>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>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>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>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>
-<title>Viewing the history of a patch</title>
-<para>\label{mq-collab:tips:interdiff}
-</para>
-
-<para>If you're developing a set of patches over a long time, it's a good
-idea to maintain them in a repository, as discussed in
-section <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>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>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>
-<para>  [extensions]
-  extdiff =
-</para>
-</programlisting>
-<para>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>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>
-<para>  hg extdiff -p hg-interdiff -r A:B my-change.patch
-</para>
-</programlisting>
-<para>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>
-<para>  [extdiff]
-  cmd.interdiff = hg-interdiff
-</para>
-</programlisting>
-<para>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>
-<para>  hg interdiff -r A:B my-change.patch
-</para>
-</programlisting>
-
-<note>
-<para>  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>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
-section <xref linkend="sec:hgext:extdiff"/>.
-</para>
-
-</sect2>
-</sect1>
+<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;
+
+    <para id="x_74a">Notice that we prefixed the arguments to the <command>hg
+	qguard</command> command with a <literal>--</literal> here, so
+      that Mercurial would not interpret the text
+      <literal>-quux</literal> as an option.</para>
+
+    <note>
+      <title>Setting vs. modifying</title>
+
+      <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:
--->
\ No newline at end of file
+-->
diff -r c075fb0481c0 -r f0110009e946 fr/ch14-hgext.xml
--- a/fr/ch14-hgext.xml	Wed Sep 09 15:25:09 2009 +0200
+++ b/fr/ch14-hgext.xml	Wed Sep 09 16:07:36 2009 +0200
@@ -1,539 +1,554 @@
 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter>
-<title>Adding functionality with extensions</title>
-<para>\label{chap:hgext}</para>
-
-<para>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>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>Section <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>In chapter <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>The Mercurial Queues patch management extension is so invaluable
-  that it merits two chapters and an appendix all to itself.
-  Chapter <xref linkend="chap:mq"/> covers the basics;
-  chapter <xref linkend="chap:mq-collab"/> discusses advanced topics; and
-  appendix <xref linkend="chap:mqref"/> goes into detail on each command.</para>
-</listitem></itemizedlist>
-
-<para>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>In section <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>
-<title>Improve performance with the <literal role="hg-ext">inotify</literal> extension</title>
-<para>\label{sec:hgext:inotify}
-</para>
-
-<para>Are you interested in having some of the most common Mercurial
-operations run as much as a hundred times faster?  Read on!
-</para>
-
-<para>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>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>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>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>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 behaviour so that instead of scanning
-the filesystem, it queries the daemon.  Since the daemon has perfect
-information about the state of the repository, it can respond with a
-result instantaneously, avoiding the need to scan every directory and
-file in the repository.
-</para>
-
-<para>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>Before we continue, please pay attention to some caveats.
-</para>
-<itemizedlist>
-<listitem><para>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>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>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>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>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>  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>To get going, it's best to already have a functioning copy of
-Mercurial installed.
-</para>
-<note>
-<para>  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>Clone the Python <literal>inotify</literal> binding repository.  Build and
-  install it.
-</para>
-</listitem><programlisting>
-<listitem><para>    hg clone http://hg.kublai.com/python/inotify
-    cd inotify
-    python setup.py build --force
-    sudo python setup.py install --skip-build
-</para>
-</listitem></programlisting>
-</para>
-</listitem>
-<listitem><para>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>
-</listitem><programlisting>
-<listitem><para>    hg clone http://hg.intevation.org/mercurial/crew
-    hg clone crew inotify
-    hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches
-</para>
-</listitem></programlisting>
-</para>
-</listitem>
-<listitem><para>Make sure that you have the Mercurial Queues extension,
-  <literal role="hg-ext">mq</literal>, enabled.  If you've never used MQ, read
-  section <xref linkend="sec:mq:start"/> to get started quickly.
-</para>
-</listitem>
-<listitem><para>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">-a</option> option to
-  the <command role="hg-ext-mq">qpush</command> command.
-</para>
-</listitem><programlisting>
-<listitem><para>    cd inotify
-    hg qpush -a
-</para>
-</listitem></programlisting>
-<listitem><para>  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>Build and install the patched version of Mercurial.
-</para>
-</listitem><programlisting>
-<listitem><para>    python setup.py build --force
-    sudo python setup.py install --skip-build
-</para>
-</listitem></programlisting>
-</orderedlist>
-<para>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>
-<para>  [extensions]
-  inotify =
-</para>
-</programlisting>
-<para>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>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>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>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>When you're using the <literal role="hg-ext">inotify</literal> extension, you should notice
-<emphasis>no difference at all</emphasis> in Mercurial's behaviour, with the sole
-exception of status-related commands running a whole lot faster than
-they used to.  You should specifically expect that commands will not
-print different output; neither should they give different results.
-If either of these situations occurs, please report a bug.
-</para>
-
-</sect1>
-<sect1>
-<title>Flexible diff support with the <literal role="hg-ext">extdiff</literal> extension</title>
-<para>\label{sec:hgext:extdiff}
-</para>
-
-<para>Mercurial's built-in <command role="hg-cmd">hg diff</command> command outputs plaintext unified
-diffs.
-<!-- &interaction.extdiff.diff; -->
-If you would like to use an external tool to display modifications,
-you'll want to use the <literal role="hg-ext">extdiff</literal> extension.  This will let you
-use, for example, a graphical diff tool.
-</para>
-
-<para>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>
-<para>  [extensions]
-  extdiff =
-</para>
-</programlisting>
-<para>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.
-<!-- &interaction.extdiff.extdiff; -->
-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>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>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>The <command role="hg-ext-extdiff">extdiff</command> command accepts two important options.
-The <option role="hg-ext-extdiff-cmd-extdiff-opt">-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">-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>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).
-<!-- &interaction.extdiff.extdiff-ctx; -->
-</para>
-
-<para>Launching a visual diff tool is just as easy.  Here's how to launch
-the <command>kdiff3</command> viewer.
-</para>
-<programlisting>
-<para>  hg extdiff -p kdiff3 -o </quote>
-</para>
-</programlisting>
-
-<para>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
-section <xref linkend="mq-collab:tips:interdiff"/>.
-</para>
-
-<sect2>
-<title>Defining command aliases</title>
-
-<para>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>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>
-<para>  [extdiff]
-  cmd.kdiff3 =
-</para>
-</programlisting>
-<para>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>\texttt{hg
-  wibble}</quote>, which runs <command>kdiff3</command>.
-</para>
-<programlisting>
-<para>  [extdiff]
-  cmd.wibble = kdiff3
-</para>
-</programlisting>
-
-<para>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>
-<para>  [extdiff]
-  cmd.vimdiff = vim
-  opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'
-</para>
-</programlisting>
-
-</sect2>
-</sect1>
-<sect1>
-<title>Cherrypicking changes with the <literal role="hg-ext">transplant</literal> extension</title>
-<para>\label{sec:hgext:transplant}
-</para>
-
-<para>Need to have a long chat with Brendan about this.
-</para>
-
-</sect1>
-<sect1>
-<title>Send changes via email with the <literal role="hg-ext">patchbomb</literal> extension</title>
-<para>\label{sec:hgext:patchbomb}
-</para>
-
-<para>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>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
-namd because changes are formatted as patches, and it's usual to send
-one changeset per email message.  Sending a long series of changes by
-email is thus much like <quote>bombing</quote> the recipient's inbox, hence
-<quote>patchbomb</quote>.
-</para>
-
-<para>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>
-<para>  [extensions]
-  patchbomb =
-</para>
-</programlisting>
-<para>Once you've enabled the extension, you will have a new command
-available, named <command role="hg-ext-patchbomb">email</command>.
-</para>
-
-<para>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">-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">-n</option> option removed.
-</para>
-
-<para>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>
-<para>  hg email -n 7:tip
-</para>
-</programlisting>
-<para>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">-b</option> option), this will constrain the
-revisions sent.
-</para>
-
-<para>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>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>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 behaviour of patchbombs</title>
-
-<para>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>You can write a subject for the introductory message on the
-  command line using the <option role="hg-ext-patchbomb-cmd-email-opt">-s</option> option.  This
-  takes one argument, the text of the subject to use.
-</para>
-</listitem>
-<listitem><para>To change the email address from which the messages originate,
-  use the <option role="hg-ext-patchbomb-cmd-email-opt">-f</option> option.  This takes one
-  argument, the email address to use.
-</para>
-</listitem>
-<listitem><para>The default behaviour is to send unified diffs (see
-  section <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">-b</option> option.
-</para>
-</listitem>
-<listitem><para>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">--plain</option> option.
-</para>
-</listitem>
-<listitem><para>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">-a</option> option.
-</para>
-</listitem>
-<listitem><para>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">-m</option> option.  That option takes one
-  argument, the name of the file to write to.
-</para>
-</listitem>
-<listitem><para>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">-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 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:
--->
\ No newline at end of file
+-->