changeset 809:ef53d025f410

Mention qdelete and qimport -r.
author Bryan O'Sullivan <bos@serpentine.com>
date Thu, 23 Apr 2009 22:24:02 -0700
parents 557552d4699f
children 1a0a78e197c3
files en/ch09-hook.xml en/ch10-template.xml en/ch11-mq.xml en/examples/auto-snippets.xml en/examples/ch11/qdelete
diffstat 5 files changed, 164 insertions(+), 198 deletions(-) [+]
line wrap: on
line diff
--- a/en/ch09-hook.xml	Tue Apr 21 23:51:47 2009 -0700
+++ b/en/ch09-hook.xml	Thu Apr 23 22:24:02 2009 -0700
@@ -147,8 +147,8 @@
 	  incoming</command>), remember that it is the other
 	repository's hooks you should be checking, not your own.
       </para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Hooks do not propagate</title>
 
@@ -178,8 +178,8 @@
 	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>
     <sect2>
       <title>Hooks can be overridden</title>
 
@@ -193,8 +193,8 @@
 	hooks, you should thus understand that your users can disable
 	or override those hooks.
       </para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Ensuring that critical hooks are run</title>
 
@@ -232,116 +232,7 @@
 
     </sect2>
   </sect1>
-  <sect1>
-    <title>Care with <literal>pretxn</literal> hooks in a
-      shared-access repository</title>
 
-    <para id="x_206">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 id="x_207">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 id="x_208">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 id="x_209">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 id="x_20a">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 id="x_20b">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 id="x_20c">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 id="x_20d">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 id="x_20e">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 id="x_20f">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 id="x_210">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 id="x_211">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 id="sec:hook:simple">
     <title>A short tutorial on using hooks</title>
 
@@ -509,8 +400,8 @@
 	<literal>foo</literal>, while the environment variable for an
 	external hook will be named <literal>HG_FOO</literal>.
       </para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Hook return values and activity control</title>
 
@@ -526,8 +417,8 @@
 	zero/false means <quote>allow</quote>, while
 	non-zero/true/exception means <quote>deny</quote>.
       </para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Writing an external hook</title>
 
@@ -555,8 +446,8 @@
 	should not rely on environment variables being set to the
 	values you have in your environment when testing the hook.
       </para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Telling Mercurial to use an in-process hook</title>
 
@@ -585,8 +476,8 @@
 	for the callable object named <literal>myhook</literal>, and
 	calls it.
       </para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Writing an in-process hook</title>
 
@@ -622,8 +513,8 @@
       </para>
 
 &interaction.hook.msglen.go;
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Checking for trailing whitespace</title>
 
@@ -838,8 +729,8 @@
 	  forbidding pushes from specific users.
 	</para>
 
-      </sect3>
-    </sect2>
+      </sect3>    </sect2>
+
     <sect2>
       <title><literal
 	  role="hg-ext">bugzilla</literal>&emdash;integration with
@@ -1144,8 +1035,8 @@
 	  a valid Bugzilla user name.
 	</para>
 
-      </sect3>
-    </sect2>
+      </sect3>    </sect2>
+
     <sect2>
       <title><literal role="hg-ext">notify</literal>&emdash;send email
 	notifications</title>
@@ -1344,8 +1235,8 @@
 	APIs normally use.  To convert a hash from hex to binary, use
 	the <literal>bin</literal> function.
       </para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>External hook execution</title>
 
@@ -1382,8 +1273,8 @@
 	have succeeded.  If it exits with a non-zero status, it is
 	considered to have failed.
       </para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Finding out where changesets come from</title>
 
@@ -1425,8 +1316,8 @@
 	      being transferred to or from a bundle.
 	    </para>
 	  </listitem></itemizedlist>
+      </sect3>
 
-      </sect3>
       <sect3 id="sec:hook:url">
 	<title>Where changes are going&emdash;remote repository
 	  URLs</title>
@@ -1462,7 +1353,6 @@
 	      discovered about the remote client.
 	    </para>
 	  </listitem></itemizedlist>
-
       </sect3>
     </sect2>
   </sect1>
@@ -1520,8 +1410,8 @@
 	  role="hook">pretxnchangegroup</literal> (<xref
 	  linkend="sec:hook:pretxnchangegroup"/>)
       </para>
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:hook:commit">
       <title><literal role="hook">commit</literal>&emdash;after a new
 	changeset is created</title>
@@ -1553,8 +1443,8 @@
 	  role="hook">pretxncommit</literal> (<xref
 	  linkend="sec:hook:pretxncommit"/>)
       </para>
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:hook:incoming">
       <title><literal role="hook">incoming</literal>&emdash;after one
 	remote changeset is added</title>
@@ -1599,8 +1489,8 @@
 	  role="hook">pretxnchangegroup</literal> (<xref
 	  linkend="sec:hook:pretxnchangegroup"/>)
       </para>
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:hook:outgoing">
       <title><literal role="hook">outgoing</literal>&emdash;after
 	changesets are propagated</title>
@@ -1646,8 +1536,8 @@
 	  role="hook">preoutgoing</literal> (<xref
 	  linkend="sec:hook:preoutgoing"/>)
       </para>
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:hook:prechangegroup">
       <title><literal
 	  role="hook">prechangegroup</literal>&emdash;before starting
@@ -1692,8 +1582,8 @@
 	  role="hook">pretxnchangegroup</literal> (<xref
 	  linkend="sec:hook:pretxnchangegroup"/>)
       </para>
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:hook:precommit">
       <title><literal role="hook">precommit</literal>&emdash;before
 	starting to commit a changeset</title>
@@ -1732,8 +1622,8 @@
 	  role="hook">pretxncommit</literal> (<xref
 	  linkend="sec:hook:pretxncommit"/>)
       </para>
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:hook:preoutgoing">
       <title><literal role="hook">preoutgoing</literal>&emdash;before
 	starting to propagate changesets</title>
@@ -1769,8 +1659,8 @@
 	  role="hook">outgoing</literal> (<xref
 	  linkend="sec:hook:outgoing"/>)
       </para>
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:hook:pretag">
       <title><literal role="hook">pretag</literal>&emdash;before
 	tagging a changeset</title>
@@ -1811,6 +1701,7 @@
 	(<xref linkend="sec:hook:tag"/>)
       </para>
     </sect2>
+
     <sect2 id="sec:hook:pretxnchangegroup">
       <title><literal
 	  role="hook">pretxnchangegroup</literal>&emdash;before
@@ -1875,8 +1766,8 @@
 	  role="hook">prechangegroup</literal> (<xref
 	  linkend="sec:hook:prechangegroup"/>)
       </para>
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:hook:pretxncommit">
       <title><literal role="hook">pretxncommit</literal>&emdash;before
 	completing commit of new changeset</title>
@@ -1901,8 +1792,8 @@
 	race conditions if you do not take steps to avoid them.
       </para>
 
-      <para id="x_2d2">Parameters to this hook:
-      </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.
@@ -1923,8 +1814,8 @@
 	  role="hook">precommit</literal> (<xref
 	  linkend="sec:hook:precommit"/>)
       </para>
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:hook:preupdate">
       <title><literal role="hook">preupdate</literal>&emdash;before
 	updating or merging working directory</title>
@@ -1955,8 +1846,8 @@
 
       <para id="x_2db">See also: <literal role="hook">update</literal>
 	(<xref linkend="sec:hook:update"/>)</para>
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:hook:tag">
       <title><literal role="hook">tag</literal>&emdash;after tagging a
 	changeset</title>
@@ -1992,8 +1883,8 @@
       <para id="x_2e2">See also: <literal role="hook">pretag</literal>
 	(<xref linkend="sec:hook:pretag"/>)
       </para>
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:hook:update">
       <title><literal role="hook">update</literal>&emdash;after
 	updating or merging working directory</title>
--- a/en/ch10-template.xml	Tue Apr 21 23:51:47 2009 -0700
+++ b/en/ch10-template.xml	Thu Apr 23 22:24:02 2009 -0700
@@ -56,9 +56,9 @@
 	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>
 
@@ -125,8 +125,8 @@
       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>
   <sect1 id="sec:template:keyword">
     <title>Common template keywords</title>
 
@@ -199,8 +199,8 @@
       in <xref linkend="sec:template:filter"/>.</para>
 
     &interaction.template.simple.datekeyword;
+  </sect1>
 
-  </sect1>
   <sect1 id="sec:template:escape">
     <title>Escape sequences</title>
 
@@ -241,8 +241,8 @@
       <quote><literal>{</literal></quote>, or
       <quote><literal>{</literal></quote> character, you must escape
       it.</para>
+  </sect1>
 
-  </sect1>
   <sect1 id="sec:template:filter">
     <title>Filtering keywords to change their results</title>
 
@@ -410,7 +410,7 @@
 	  <quote><literal>bos</literal></quote>.</para>
       </listitem></itemizedlist>
 
-&interaction.template.simple.manyfilters;
+    &interaction.template.simple.manyfilters;
 
     <note>
       <para id="x_5b7">  If you try to apply a filter to a piece of data that it
@@ -445,10 +445,9 @@
 	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>
 
@@ -513,9 +512,9 @@
 	    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>
 
@@ -566,8 +565,8 @@
 	    is almost always trivial to visually inspect the offending
 	    line in the style file and see what is wrong.</para>
 	</listitem></itemizedlist>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Uniquely identifying a repository</title>
 
@@ -602,8 +601,8 @@
 	    or other activity, so that you can <quote>replay</quote>
 	    the build later if necessary.</para>
 	</listitem></itemizedlist>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Mimicking Subversion's output</title>
 
@@ -661,7 +660,6 @@
 	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>
--- a/en/ch11-mq.xml	Tue Apr 21 23:51:47 2009 -0700
+++ b/en/ch11-mq.xml	Thu Apr 23 22:24:02 2009 -0700
@@ -118,8 +118,8 @@
       <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>
     <sect2 id="sec:mq:quilt-mq">
       <title>From patchwork quilt to Mercurial Queues</title>
 
@@ -181,8 +181,8 @@
 	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>
   <sect1 id="sec:mq:patch">
     <title>Understanding patches</title>
 
@@ -244,8 +244,8 @@
       later (in <xref linkend="sec:mq:adv-patch"/>), but you
       should have
       enough information now to use MQ.</para>
+  </sect1>
 
-  </sect1>
   <sect1 id="sec:mq:start">
     <title>Getting started with Mercurial Queues</title>
 
@@ -265,14 +265,14 @@
       the <command role="hg-ext-mq">qinit</command> command is now
       available.</para>
 
-&interaction.mq.qinit-help.help;
+    &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;
+    &interaction.mq.tutorial.qinit;
 
     <para id="x_3cd">This command creates an empty directory called <filename
 	role="special" class="directory">.hg/patches</filename>, where
@@ -292,7 +292,7 @@
 	  class="directory">.hg/patches</filename> directory, as you
 	can see below.</para>
 
-&interaction.mq.tutorial.qnew;
+      &interaction.mq.tutorial.qnew;
 
       <para id="x_3d0">Also newly present in the <filename role="special"
 	  class="directory">.hg/patches</filename> directory are two
@@ -320,8 +320,8 @@
 	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>
     <sect2>
       <title>Refreshing a patch</title>
 
@@ -329,7 +329,7 @@
 	use the <command role="hg-ext-mq">qrefresh</command> command
 	to update the patch you are working on.</para>
 
-&interaction.mq.tutorial.qrefresh;
+      &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
@@ -342,9 +342,9 @@
 	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;
+      &interaction.mq.tutorial.qrefresh2;
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Stacking and tracking patches</title>
 
@@ -354,7 +354,8 @@
 	new patch. Mercurial will apply this patch on top of your
 	existing patch.</para>
 
-&interaction.mq.tutorial.qnew2;
+      &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
@@ -367,7 +368,7 @@
 	many commands that are easier to use when you are thinking
 	about patches, as illustrated below.</para>
 
-&interaction.mq.tutorial.qseries;
+      &interaction.mq.tutorial.qseries;
 
       <itemizedlist>
 	<listitem><para id="x_3d9">The <command
@@ -382,8 +383,8 @@
 	    repository, again from oldest to newest (most recently
 	    applied).</para>
 	</listitem></itemizedlist>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Manipulating the patch stack</title>
 
@@ -420,15 +421,16 @@
 	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;
+
+      &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>
     <sect2>
       <title>Pushing and popping many patches</title>
 
@@ -444,9 +446,9 @@
 	patches.  (For some more ways to push and pop many patches,
 	see <xref linkend="sec:mq:perf"/> below.)</para>
 
-&interaction.mq.tutorial.qpush-a;
+      &interaction.mq.tutorial.qpush-a;
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Safety checks, and overriding them</title>
 
@@ -460,7 +462,7 @@
 	case by the <command role="hg-cmd">hg add</command> of
 	<filename>file3</filename>.</para>
 
-&interaction.mq.tutorial.add;
+      &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
@@ -474,8 +476,8 @@
 	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>
     <sect2>
       <title>Working on several patches at once</title>
 
@@ -499,9 +501,9 @@
 	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>
 
@@ -580,6 +582,7 @@
 	  311</ulink> for details.
       </para>
     </sect2>
+
     <sect2>
       <title>Strategies for applying a patch</title>
 
@@ -623,8 +626,8 @@
 	<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>
     <sect2>
       <title>Some quirks of patch representation</title>
 
@@ -663,6 +666,7 @@
 	      tree</quote>.</para>
 	</listitem></itemizedlist>
     </sect2>
+
     <sect2>
       <title>Beware the fuzz</title>
 
@@ -686,8 +690,8 @@
 	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>
     <sect2>
       <title>Handling rejection</title>
 
@@ -707,15 +711,10 @@
 	the <filename role="special">.rej</filename> file and edit the
 	target file, applying the rejected hunks by hand.</para>
 
-      <para id="x_3fc">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 id="x_3fd">Another Linux kernel hacker, Chris Mason (the author of
-	Mercurial Queues), wrote a similar tool called
-	<command>mpatch</command> <citation>web:mpatch</citation>,
+      <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
@@ -736,24 +735,67 @@
 	    content than those currently present in the file.</para>
 	</listitem></itemizedlist>
 
-      <para id="x_402">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
+      <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>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>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>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 qdelete -r</command> command.  Pass a
+	revision to the <option>-r</option> option 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>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>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
-      <citation>web:europython</citation>.  I used as my data set the
+      gave at the 2006 EuroPython conference.  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
@@ -799,8 +841,8 @@
       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>
   <sect1 id="sec:mq:merge">
     <title>Updating your patches when the underlying code
       changes</title>
@@ -899,8 +941,8 @@
 	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>
   <sect1>
     <title>Identifying patches</title>
 
@@ -963,9 +1005,9 @@
       few normal Mercurial commands in use with applied
       patches.</para>
 
-&interaction.mq.id.output;
+    &interaction.mq.id.output;
+  </sect1>
 
-  </sect1>
   <sect1>
     <title>Useful things to know about</title>
 
@@ -991,8 +1033,8 @@
 	  this, it will appear to succeed, but MQ will become
 	  confused.</para>
       </listitem></itemizedlist>
+  </sect1>
 
-  </sect1>
   <sect1 id="sec:mq:repo">
     <title>Managing patches in a repository</title>
 
@@ -1077,8 +1119,8 @@
 
       <para id="x_42d">You can then issue commands of the form <command>mq
 	  pull</command> from the main repository.</para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>A few things to watch out for</title>
 
@@ -1216,8 +1258,8 @@
 	tree.</para>
 
       &interaction.mq.tarball.repush;
+    </sect2>
 
-    </sect2>
     <sect2 id="sec:mq:combine">
       <title>Combining entire patches</title>
 
@@ -1237,8 +1279,8 @@
 	you applied first <literal>foo</literal>, then
 	<literal>bar</literal>, followed by
 	<literal>quux</literal>.</para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Merging part of one patch into another</title>
 
--- a/en/examples/auto-snippets.xml	Tue Apr 21 23:51:47 2009 -0700
+++ b/en/examples/auto-snippets.xml	Thu Apr 23 22:24:02 2009 -0700
@@ -60,6 +60,9 @@
 <!ENTITY interaction.ch04-resolve.merge SYSTEM "results/ch04-resolve.merge.lxo">
 <!ENTITY interaction.ch04-resolve.pull SYSTEM "results/ch04-resolve.pull.lxo">
 <!ENTITY interaction.ch04-resolve.right SYSTEM "results/ch04-resolve.right.lxo">
+<!ENTITY interaction.ch11-qdelete.convert SYSTEM "results/ch11-qdelete.convert.lxo">
+<!ENTITY interaction.ch11-qdelete.go SYSTEM "results/ch11-qdelete.go.lxo">
+<!ENTITY interaction.ch11-qdelete.import SYSTEM "results/ch11-qdelete.import.lxo">
 <!ENTITY interaction.cmdref.diff-p SYSTEM "results/cmdref.diff-p.lxo">
 <!ENTITY interaction.daily.copy.after SYSTEM "results/daily.copy.after.lxo">
 <!ENTITY interaction.daily.copy.cat SYSTEM "results/daily.copy.cat.lxo">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/ch11/qdelete	Thu Apr 23 22:24:02 2009 -0700
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+echo '[extensions]' >> $HGRC
+echo 'hgext.mq =' >> $HGRC
+
+#$ name: go
+
+hg init myrepo
+cd myrepo
+hg qinit
+hg qnew bad.patch
+echo a > a
+hg add a
+hg qrefresh
+hg qdelete bad.patch
+hg qpop
+hg qdelete bad.patch
+
+#$ name: convert
+
+hg qnew good.patch
+echo a > a
+hg add a
+hg qrefresh -m 'Good change'
+hg qdelete -r tip
+hg qapplied
+hg tip --style=compact
+
+#$ name: import
+
+hg qimport -r tip
+hg qapplied