web/html/backup/abcd.html
changeset 0 8083d21c0020
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/html/backup/abcd.html	Mon Jan 25 18:56:45 2010 +0530
@@ -0,0 +1,929 @@
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Chapter 9. Finding and fixing mistakes</title><link rel="stylesheet" href="/support/styles.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.74.3"><link rel="home" href="index.html" title="Mercurial: The Definitive Guide"><link rel="up" href="index.html" title="Mercurial: The Definitive Guide"><link rel="prev" href="managing-releases-and-branchy-development.html" title="Chapter 8. Managing releases and branchy development"><link rel="next" href="handling-repository-events-with-hooks.html" title="Chapter 10. Handling repository events with hooks"><link rel="alternate" type="application/atom+xml" title="Comments" href="/feeds/comments/"><link rel="shortcut icon" type="image/png" href="/support/figs/favicon.png"><script type="text/javascript" src="/support/jquery-min.js"></script><script type="text/javascript" src="/support/form.js"></script><script type="text/javascript" src="/support/hsbook.js"></script></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><h2 class="booktitle"><a href="/">Mercurial: The Definitive Guide</a><span class="authors">by Bryan O'Sullivan</span></h2></div><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 9. Finding and fixing mistakes</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="managing-releases-and-branchy-development.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="handling-repository-events-with-hooks.html">Next</a></td></tr></table></div><div class="chapter" lang="en" id="chap:undo"><div class="titlepage"><div><div><h2 class="title">Chapter 9. Finding and fixing mistakes</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="finding-and-fixing-mistakes.html#id390081">Erasing local history</a></span></dt><dd><dl><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id390087">The accidental commit</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#sec:undo:rollback">Rolling back a transaction</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id390858">The erroneous pull</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#sec:undo:rollback-after-push">Rolling back is useless once you've pushed</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id391000">You can only roll back once</a></span></dt></dl></dd><dt><span class="sect1"><a href="finding-and-fixing-mistakes.html#id391367">Reverting the mistaken change</a></span></dt><dd><dl><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#sec:undo:mgmt">File management errors</a></span></dt></dl></dd><dt><span class="sect1"><a href="finding-and-fixing-mistakes.html#id392218">Dealing with committed changes</a></span></dt><dd><dl><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id392287">Backing out a changeset</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id392424">Backing out the tip changeset</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id392766">Backing out a non-tip change</a></span></dt><dd><dl><dt><span class="sect3"><a href="finding-and-fixing-mistakes.html#id392990">Always use the --merge option</a></span></dt></dl></dd><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id393181">Gaining more control of the backout process</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id393814">Why hg backout works as
+	it does</a></span></dt></dl></dd><dt><span class="sect1"><a href="finding-and-fixing-mistakes.html#sec:undo:aaaiiieee">Changes that should never have been</a></span></dt><dd><dl><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id394303">Backing out a merge</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id394612">Protect yourself from escaped
+	changes</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id394667">What to do about sensitive changes that escape</a></span></dt></dl></dd><dt><span class="sect1"><a href="finding-and-fixing-mistakes.html#sec:undo:bisect">Finding the source of a bug</a></span></dt><dd><dl><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id394992">Using the hg bisect
+	command</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id396541">Cleaning up after your search</a></span></dt></dl></dd><dt><span class="sect1"><a href="finding-and-fixing-mistakes.html#id396622">Tips for finding bugs effectively</a></span></dt><dd><dl><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id396628">Give consistent input</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id396884">Automate as much as possible</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id396713">Check your results</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id396770">Beware interference between bugs</a></span></dt><dt><span class="sect2"><a href="finding-and-fixing-mistakes.html#id396856">Bracket your search lazily</a></span></dt></dl></dd></dl></div><p id="x_d2"><a name="x_d2"></a>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.</p><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id390081">Erasing local history</h2></div></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id390087">The accidental commit</h3></div></div></div><p id="x_d3"><a name="x_d3"></a>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 <span class="command"><strong>hg add</strong></span> it.  A
+	“<span class="quote">plain wrong</span>” changeset is not as common, but no
+	less annoying.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="sec:undo:rollback">Rolling back a transaction</h3></div></div></div><p id="x_d4"><a name="x_d4"></a>In <a class="xref" href="behind-the-scenes.html#sec:concepts:txn" title="Safe operation">the section called “Safe operation”</a>, I
+	mentioned that Mercurial treats each modification of a
+	repository as a <span class="emphasis"><em>transaction</em></span>.  Every time
+	you commit a changeset or pull changes from another
+	repository, Mercurial remembers what you did.  You can undo,
+	or <span class="emphasis"><em>roll back</em></span>, exactly one of these
+	actions using the <span class="command"><strong>hg rollback</strong></span>
+
+	command.  (See <a class="xref" href="finding-and-fixing-mistakes.html#sec:undo:rollback-after-push" title="Rolling back is useless once you've pushed">the section called “Rolling back is useless once you've pushed”</a>
+	for an important caveat about the use of this command.)</p><p id="x_d5"><a name="x_d5"></a>Here's a mistake that I often find myself making:
+	committing a change in which I've created a new file, but
+	forgotten to <span class="command"><strong>hg add</strong></span>
+	it.</p><pre id="id390839" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
+M a
+<code class="prompt">$</code> <strong class="userinput"><code>echo b &gt; b</code></strong>
+
+<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'Add file b'</code></strong>
+</pre><p id="x_d6"><a name="x_d6"></a>Looking at the output of <span class="command"><strong>hg
+	  status</strong></span> after the commit immediately confirms the
+	error.</p><pre id="id390541" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
+? b
+<code class="prompt">$</code> <strong class="userinput"><code>hg tip</code></strong>
+
+changeset:   1:f2db1de2ba4f
+tag:         tip
+user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
+date:        Tue May 05 06:55:44 2009 +0000
+summary:     Add file b
+
+</pre><p id="x_d7"><a name="x_d7"></a>The commit captured the changes to the file
+	<code class="filename">a</code>, but not the new file
+	<code class="filename">b</code>.  If I were to push this changeset to a
+	repository that I shared with a colleague, the chances are
+	high that something in <code class="filename">a</code> would refer to
+	<code class="filename">b</code>, which would not be present in their
+	repository when they pulled my changes.  I would thus become
+	the object of some indignation.</p><p id="x_d8"><a name="x_d8"></a>However, luck is with me—I've caught my error
+	before I pushed the changeset.  I use the <span class="command"><strong>hg rollback</strong></span> command, and Mercurial
+	makes that last changeset vanish.</p><pre id="id391066" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg rollback</code></strong>
+
+rolling back last transaction
+<code class="prompt">$</code> <strong class="userinput"><code>hg tip</code></strong>
+changeset:   0:cde70bc943e1
+tag:         tip
+user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
+date:        Tue May 05 06:55:44 2009 +0000
+summary:     First commit
+
+<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
+M a
+? b
+</pre><p id="x_d9"><a name="x_d9"></a>Notice that the changeset is no longer present in the
+	repository's history, and the working directory once again
+	thinks that the file <code class="filename">a</code> 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 <span class="command"><strong>hg
+	  add</strong></span> the file <code class="filename">b</code>, and rerun my
+	commit.</p><pre id="id391024" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg add b</code></strong>
+
+<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'Add file b, this time for real'</code></strong>
+</pre></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id390858">The erroneous pull</h3></div></div></div><p id="x_da"><a name="x_da"></a>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 “<span class="quote">0.9</span>” release, and another,
+	containing different changes, for the “<span class="quote">1.0</span>”
+	release.</p><p id="x_db"><a name="x_db"></a>Given this, you can imagine that the consequences could be
+	messy if you had a local “<span class="quote">0.9</span>” repository, and
+	accidentally pulled changes from the shared “<span class="quote">1.0</span>”
+	repository into it.  At worst, you could be paying
+	insufficient attention, and push those changes into the shared
+	“<span class="quote">0.9</span>” 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.</p><p id="x_dc"><a name="x_dc"></a>The <span class="command"><strong>hg rollback</strong></span> command
+	will work nicely to expunge all of the changesets that you
+	just pulled.  Mercurial groups all changes from one <span class="command"><strong>hg pull</strong></span> into a single transaction,
+	so one <span class="command"><strong>hg rollback</strong></span> is all you
+	need to undo this mistake.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="sec:undo:rollback-after-push">Rolling back is useless once you've pushed</h3></div></div></div><p id="x_dd"><a name="x_dd"></a>The value of the <span class="command"><strong>hg
+	  rollback</strong></span> command drops to zero once you've pushed
+	your changes to another repository.  Rolling back a change
+	makes it disappear entirely, but <span class="emphasis"><em>only</em></span> in
+	the repository in which you perform the <span class="command"><strong>hg rollback</strong></span>.  Because a rollback
+	eliminates history, there's no way for the disappearance of a
+	change to propagate between repositories.</p><p id="x_de"><a name="x_de"></a>If you've pushed a change to another
+	repository—particularly if it's a shared
+	repository—it has essentially “<span class="quote">escaped into the
+	  wild,</span>” 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.</p><p id="x_df"><a name="x_df"></a>(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, <span class="emphasis"><em>and</em></span> 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.)</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id391000">You can only roll back once</h3></div></div></div><p id="x_e0"><a name="x_e0"></a>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.</p><pre id="id391424" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg rollback</code></strong>
+
+rolling back last transaction
+<code class="prompt">$</code> <strong class="userinput"><code>hg rollback</code></strong>
+no rollback information available
+</pre><p id="x_e1"><a name="x_e1"></a>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.</p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id391367">Reverting the mistaken change</h2></div></div></div><p id="x_e2"><a name="x_e2"></a>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 <span class="command"><strong>hg
+	revert</strong></span> 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.)</p><p id="x_e3"><a name="x_e3"></a>Let's illustrate how the <span class="command"><strong>hg
+	revert</strong></span> command works with yet another small example.
+      We'll begin by modifying a file that Mercurial is already
+      tracking.</p><pre id="id391316" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cat file</code></strong>
+
+original content
+<code class="prompt">$</code> <strong class="userinput"><code>echo unwanted change &gt;&gt; file</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg diff file</code></strong>
+diff -r b52afd4afc59 file
+--- a/file	Tue May 05 06:55:32 2009 +0000
++++ b/file	Tue May 05 06:55:32 2009 +0000
+@@ -1,1 +1,2 @@
+ original content
++unwanted change
+</pre><p id="x_e4"><a name="x_e4"></a>If we don't
+      want that change, we can simply <span class="command"><strong>hg
+	revert</strong></span> the file.</p><pre id="id391251" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
+
+M file
+<code class="prompt">$</code> <strong class="userinput"><code>hg revert file</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>cat file</code></strong>
+original content
+</pre><p id="x_e5"><a name="x_e5"></a>The <span class="command"><strong>hg revert</strong></span> command
+      provides us with an extra degree of safety by saving our
+      modified file with a <code class="filename">.orig</code>
+      extension.</p><pre id="id391767" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
+
+? file.orig
+<code class="prompt">$</code> <strong class="userinput"><code>cat file.orig</code></strong>
+original content
+unwanted change
+</pre><div class="tip"><table border="0" summary="Tip: Be careful with .orig files"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="/support/figs/tip.png"></td><th align="left">Be careful with .orig files</th></tr><tr><td align="left" valign="top"><p id="x_6b8"><a name="x_6b8"></a>It's extremely unlikely that you are either using
+	Mercurial to manage files with <code class="filename">.orig</code>
+	extensions or that you even care about the contents of such
+	files.  Just in case, though, it's useful to remember that
+	<span class="command"><strong>hg revert</strong></span> will
+	unconditionally overwrite an existing file with a
+	<code class="filename">.orig</code> extension. For instance, if you
+	already have a file named <code class="filename">foo.orig</code> when
+	you revert <code class="filename">foo</code>, the contents of
+	<code class="filename">foo.orig</code> will be clobbered.</p></td></tr></table></div><p id="x_e6"><a name="x_e6"></a>Here is a summary of the cases that the <span class="command"><strong>hg revert</strong></span> command can deal with.  We
+      will describe each of these in more detail in the section that
+      follows.</p><div class="itemizedlist"><ul type="disc"><li><p id="x_e7"><a name="x_e7"></a>If you modify a file, it will restore the file
+	  to its unmodified state.</p></li><li><p id="x_e8"><a name="x_e8"></a>If you <span class="command"><strong>hg add</strong></span> a
+	  file, it will undo the “<span class="quote">added</span>” state of the
+	  file, but leave the file itself untouched.</p></li><li><p id="x_e9"><a name="x_e9"></a>If you delete a file without telling Mercurial,
+	  it will restore the file to its unmodified contents.</p></li><li><p id="x_ea"><a name="x_ea"></a>If you use the <span class="command"><strong>hg
+	    remove</strong></span> command to remove a file, it will undo
+	  the “<span class="quote">removed</span>” state of the file, and restore
+	  the file to its unmodified contents.</p></li></ul></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="sec:undo:mgmt">File management errors</h3></div></div></div><p id="x_eb"><a name="x_eb"></a>The <span class="command"><strong>hg revert</strong></span> command is
+	useful for more than just modified files.  It lets you reverse
+	the results of all of Mercurial's file management
+	commands—<span class="command"><strong>hg add</strong></span>,
+	<span class="command"><strong>hg remove</strong></span>, and so on.</p><p id="x_ec"><a name="x_ec"></a>If you <span class="command"><strong>hg add</strong></span> a file,
+	then decide that in fact you don't want Mercurial to track it,
+	use <span class="command"><strong>hg revert</strong></span> to undo the
+	add.  Don't worry; Mercurial will not modify the file in any
+	way.  It will just “<span class="quote">unmark</span>” the file.</p><pre id="id391756" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>echo oops &gt; oops</code></strong>
+
+<code class="prompt">$</code> <strong class="userinput"><code>hg add oops</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg status oops</code></strong>
+A oops
+<code class="prompt">$</code> <strong class="userinput"><code>hg revert oops</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
+
+? oops
+</pre><p id="x_ed"><a name="x_ed"></a>Similarly, if you ask Mercurial to <span class="command"><strong>hg remove</strong></span> a file, you can use
+	<span class="command"><strong>hg revert</strong></span> to restore it to
+	the contents it had as of the parent of the working directory.
+	
+</p><pre id="id392036" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg remove file</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
+R file
+
+<code class="prompt">$</code> <strong class="userinput"><code>hg revert file</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>ls file</code></strong>
+file
+</pre><p>
+
+ 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 “<span class="quote">missing</span>”).</p><pre id="id391954" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>rm file</code></strong>
+
+<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
+! file
+<code class="prompt">$</code> <strong class="userinput"><code>hg revert file</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>ls file</code></strong>
+file
+</pre><p id="x_ee"><a name="x_ee"></a>If you revert a <span class="command"><strong>hg copy</strong></span>,
+	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.</p><pre id="id392181" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg copy file new-file</code></strong>
+
+<code class="prompt">$</code> <strong class="userinput"><code>hg revert new-file</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
+? new-file
+</pre></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id392218">Dealing with committed changes</h2></div></div></div><p id="x_f5"><a name="x_f5"></a>Consider a case where you have committed a change
+      <span class="emphasis"><em>a</em></span>, and another change
+      <span class="emphasis"><em>b</em></span> on top of it; you then realise that
+      change <span class="emphasis"><em>a</em></span> was incorrect.  Mercurial lets you
+      “<span class="quote">back out</span>” an entire changeset automatically, and
+      building blocks that let you reverse part of a changeset by
+      hand.</p><p id="x_f6"><a name="x_f6"></a>Before you read this section, here's something to
+      keep in mind: the <span class="command"><strong>hg backout</strong></span>
+
+      command undoes the effect of a change by
+      <span class="emphasis"><em>adding</em></span> 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
+      <a class="xref" href="finding-and-fixing-mistakes.html#sec:undo:aaaiiieee" title="Changes that should never have been">the section called “Changes that should never have been”</a>.</p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id392287">Backing out a changeset</h3></div></div></div><p id="x_f7"><a name="x_f7"></a>The <span class="command"><strong>hg backout</strong></span> command
+	lets you “<span class="quote">undo</span>” the effects of an entire
+	changeset in an automated fashion.  Because Mercurial's
+	history is immutable, this command <span class="emphasis"><em>does
+	  not</em></span> get rid of the changeset you want to undo.
+	Instead, it creates a new changeset that
+	<span class="emphasis"><em>reverses</em></span> the effect of the to-be-undone
+	changeset.</p><p id="x_f8"><a name="x_f8"></a>The operation of the <span class="command"><strong>hg
+	  backout</strong></span> command is a little intricate, so let's
+	illustrate it with some examples.  First, we'll create a
+	repository with some simple changes.</p><pre id="id392685" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg init myrepo</code></strong>
+
+<code class="prompt">$</code> <strong class="userinput"><code>cd myrepo</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>echo first change &gt;&gt; myfile</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg add myfile</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'first change'</code></strong>
+
+<code class="prompt">$</code> <strong class="userinput"><code>echo second change &gt;&gt; myfile</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'second change'</code></strong>
+</pre><p id="x_f9"><a name="x_f9"></a>The <span class="command"><strong>hg backout</strong></span> command
+	takes a single changeset ID as its argument; this is the
+	changeset to back out.  Normally, <span class="command"><strong>hg
+	  backout</strong></span> 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 <code class="option">-m</code> option.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id392424">Backing out the tip changeset</h3></div></div></div><p id="x_fa"><a name="x_fa"></a>We're going to start by backing out the last changeset we
+	committed.</p><pre id="id392577" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg backout -m 'back out second change' tip</code></strong>
+
+reverting myfile
+changeset 2:01adc4672142 backs out changeset 1:7e341ee3be7a
+<code class="prompt">$</code> <strong class="userinput"><code>cat myfile</code></strong>
+first change
+</pre><p id="x_fb"><a name="x_fb"></a>You can see that the second line from
+	<code class="filename">myfile</code> is no longer present.  Taking a
+	look at the output of <span class="command"><strong>hg log</strong></span>
+	gives us an idea of what the <span class="command"><strong>hg
+	  backout</strong></span> command has done.
+	
+
+</p><pre id="id392554" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg log --style compact</code></strong>
+2[tip]   01adc4672142   2009-05-05 06:55 +0000   bos
+  back out second change
+
+1   7e341ee3be7a   2009-05-05 06:55 +0000   bos
+  second change
+
+0   56b97fc928f2   2009-05-05 06:55 +0000   bos
+  first change
+
+</pre><p>
+
+ Notice that the new changeset
+	that <span class="command"><strong>hg backout</strong></span> has created
+	is a child of the changeset we backed out.  It's easier to see
+	this in <a class="xref" href="finding-and-fixing-mistakes.html#fig:undo:backout" title="Figure 9.1. Backing out a change using the hg backout command">Figure 9.1, “Backing out a change using the hg backout command”</a>, which presents a
+	graphical view of the change history.  As you can see, the
+	history is nice and linear.</p><div class="figure"><a name="fig:undo:backout"></a><p class="title"><b>Figure 9.1. Backing out a change using the <span class="command">hg backout</span> command</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/undo-simple.png" alt="XXX add text"></div></div></div><br class="figure-break"></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id392766">Backing out a non-tip change</h3></div></div></div><p id="x_fd"><a name="x_fd"></a>If you want to back out a change other than the last one
+	you committed, pass the <code class="option">--merge</code> option to the
+	<span class="command"><strong>hg backout</strong></span> command.</p><pre id="id393141" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cd ..</code></strong>
+
+<code class="prompt">$</code> <strong class="userinput"><code>hg clone -r1 myrepo non-tip-repo</code></strong>
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 2 changesets with 2 changes to 1 files
+updating working directory
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+<code class="prompt">$</code> <strong class="userinput"><code>cd non-tip-repo</code></strong>
+</pre><p id="x_fe"><a name="x_fe"></a>This makes backing out any changeset a
+	“<span class="quote">one-shot</span>” operation that's usually simple and
+	fast.</p><pre id="id392845" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>echo third change &gt;&gt; myfile</code></strong>
+
+<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'third change'</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg backout --merge -m 'back out second change' 1</code></strong>
+reverting myfile
+created new head
+changeset 3:abc7fd860049 backs out changeset 1:7e341ee3be7a
+merging with changeset 3:abc7fd860049
+merging myfile
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+</pre><p id="x_ff"><a name="x_ff"></a>If you take a look at the contents of
+	<code class="filename">myfile</code> after the backout finishes, you'll
+	see that the first and third changes are present, but not the
+	second.</p><pre id="id392886" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cat myfile</code></strong>
+
+first change
+third change
+</pre><p id="x_100"><a name="x_100"></a>As the graphical history in <a class="xref" href="finding-and-fixing-mistakes.html#fig:undo:backout-non-tip" title="Figure 9.2. Automated backout of a non-tip change using the hg backout command">Figure 9.2, “Automated backout of a non-tip change using the
+	  hg backout command”</a> 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 <span class="emphasis"><em>does not
+	  commit</em></span> the result of the merge.  The repository
+	now contains two heads, and the working directory is in a
+	merge state.</p><div class="figure"><a name="fig:undo:backout-non-tip"></a><p class="title"><b>Figure 9.2. Automated backout of a non-tip change using the
+	  <span class="command">hg backout</span> command</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/undo-non-tip.png" alt="XXX add text"></div></div></div><br class="figure-break"><p id="x_103"><a name="x_103"></a>The result is that you end up “<span class="quote">back where you
+	  were</span>”, only with some extra history that undoes the
+	effect of the changeset you wanted to back out.</p><p id="x_6b9"><a name="x_6b9"></a>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, <span class="emphasis"><em>then</em></span> commit
+	it.</p><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title" id="id392990">Always use the <code class="option">--merge</code> option</h4></div></div></div><p id="x_104"><a name="x_104"></a>In fact, since the <code class="option">--merge</code> option will do the
+	  “<span class="quote">right thing</span>” 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
+	  <span class="emphasis"><em>always</em></span> use this option when you run the
+	  <span class="command"><strong>hg backout</strong></span> command.</p></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id393181">Gaining more control of the backout process</h3></div></div></div><p id="x_105"><a name="x_105"></a>While I've recommended that you always use the <code class="option">--merge</code> option when backing
+	out a change, the <span class="command"><strong>hg backout</strong></span>
+
+	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 <span class="command"><strong>hg backout</strong></span> command
+	is doing for you automatically.  To illustrate this, let's
+	clone our first repository, but omit the backout change that
+	it contains.</p><pre id="id393568" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cd ..</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg clone -r1 myrepo newrepo</code></strong>
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 2 changesets with 2 changes to 1 files
+updating working directory
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+<code class="prompt">$</code> <strong class="userinput"><code>cd newrepo</code></strong>
+
+</pre><p id="x_106"><a name="x_106"></a>As with our
+	earlier example, We'll commit a third changeset, then back out
+	its parent, and see what happens.</p><pre id="id393553" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>echo third change &gt;&gt; myfile</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'third change'</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>hg backout -m 'back out second change' 1</code></strong>
+reverting myfile
+created new head
+changeset 3:abc7fd860049 backs out changeset 1:7e341ee3be7a
+the backout changeset is a new head - do not forget to merge
+(use "backout --merge" if you want to auto-merge)
+</pre><p id="x_107"><a name="x_107"></a>Our new changeset is again a descendant of the changeset
+	we backout out; it's thus a new head, <span class="emphasis"><em>not</em></span>
+
+	a descendant of the changeset that was the tip.  The <span class="command"><strong>hg backout</strong></span> command was quite
+	explicit in telling us this.</p><pre id="id393314" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg log --style compact</code></strong>
+3[tip]:1   abc7fd860049   2009-05-05 06:55 +0000   bos
+  back out second change
+
+2   bae4005ddac4   2009-05-05 06:55 +0000   bos
+  third change
+
+1   7e341ee3be7a   2009-05-05 06:55 +0000   bos
+  second change
+
+0   56b97fc928f2   2009-05-05 06:55 +0000   bos
+  first change
+
+</pre><p id="x_108"><a name="x_108"></a>Again, it's easier to see what has happened by looking at
+	a graph of the revision history, in <a class="xref" href="finding-and-fixing-mistakes.html#fig:undo:backout-manual" title="Figure 9.3. Backing out a change using the hg backout command">Figure 9.3, “Backing out a change using the hg backout command”</a>.  This makes it clear
+	that when we use <span class="command"><strong>hg backout</strong></span>
+	to back out a change other than the tip, Mercurial adds a new
+	head to the repository (the change it committed is
+	box-shaped).</p><div class="figure"><a name="fig:undo:backout-manual"></a><p class="title"><b>Figure 9.3. Backing out a change using the <span class="command">hg backout</span> command</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/undo-manual.png" alt="XXX add text"></div></div></div><br class="figure-break"><p id="x_10a"><a name="x_10a"></a>After the <span class="command"><strong>hg backout</strong></span>
+
+	command has completed, it leaves the new
+	“<span class="quote">backout</span>” changeset as the parent of the working
+	directory.</p><pre id="id393912" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg parents</code></strong>
+changeset:   2:bae4005ddac4
+user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
+date:        Tue May 05 06:55:12 2009 +0000
+summary:     third change
+
+</pre><p id="x_10b"><a name="x_10b"></a>Now we have two isolated sets of changes.</p><pre id="id393905" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg heads</code></strong>
+
+changeset:   3:abc7fd860049
+tag:         tip
+parent:      1:7e341ee3be7a
+user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
+date:        Tue May 05 06:55:12 2009 +0000
+summary:     back out second change
+
+changeset:   2:bae4005ddac4
+user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
+date:        Tue May 05 06:55:12 2009 +0000
+summary:     third change
+
+</pre><p id="x_10c"><a name="x_10c"></a>Let's think about what we expect to see as the contents of
+	<code class="filename">myfile</code> 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 <span class="emphasis"><em>don't</em></span> expect to see the third change
+	present in <code class="filename">myfile</code>.</p><pre id="id393884" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cat myfile</code></strong>
+
+first change
+</pre><p id="x_10d"><a name="x_10d"></a>To get the third change back into the file, we just do a
+	normal merge of our two heads.</p><pre id="id393845" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg merge</code></strong>
+abort: outstanding uncommitted changes
+<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'merged backout with previous tip'</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>cat myfile</code></strong>
+first change
+</pre><p id="x_10e"><a name="x_10e"></a>Afterwards, the graphical history of our
+	repository looks like
+	<a class="xref" href="finding-and-fixing-mistakes.html#fig:undo:backout-manual-merge" title="Figure 9.4. Manually merging a backout change">Figure 9.4, “Manually merging a backout change”</a>.</p><div class="figure"><a name="fig:undo:backout-manual-merge"></a><p class="title"><b>Figure 9.4. Manually merging a backout change</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/undo-manual-merge.png" alt="XXX add text"></div></div></div><br class="figure-break"></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id393814">Why <span class="command"><strong>hg backout</strong></span> works as
+	it does</h3></div></div></div><p id="x_110"><a name="x_110"></a>Here's a brief description of how the <span class="command"><strong>hg backout</strong></span> command works.</p><div class="orderedlist"><ol type="1"><li><p id="x_111"><a name="x_111"></a>It ensures that the working directory is
+	    “<span class="quote">clean</span>”, i.e. that the output of <span class="command"><strong>hg status</strong></span> would be empty.</p></li><li><p id="x_112"><a name="x_112"></a>It remembers the current parent of the working
+	    directory.  Let's call this changeset
+	    <code class="literal">orig</code>.</p></li><li><p id="x_113"><a name="x_113"></a>It does the equivalent of a <span class="command"><strong>hg update</strong></span> to sync the working
+	    directory to the changeset you want to back out.  Let's
+	    call this changeset <code class="literal">backout</code>.</p></li><li><p id="x_114"><a name="x_114"></a>It finds the parent of that changeset.  Let's
+	    call that changeset <code class="literal">parent</code>.</p></li><li><p id="x_115"><a name="x_115"></a>For each file that the
+	    <code class="literal">backout</code> changeset affected, it does the
+	    equivalent of a <span class="command"><strong>hg revert -r
+	      parent</strong></span> on that file, to restore it to the
+	    contents it had before that changeset was
+	    committed.</p></li><li><p id="x_116"><a name="x_116"></a>It commits the result as a new changeset.
+	    This changeset has <code class="literal">backout</code> as its
+	    parent.</p></li><li><p id="x_117"><a name="x_117"></a>If you specify <code class="option">--merge</code> on the command
+	    line, it merges with <code class="literal">orig</code>, and commits
+	    the result of the merge.</p></li></ol></div><p id="x_118"><a name="x_118"></a>An alternative way to implement the <span class="command"><strong>hg backout</strong></span> command would be to
+	<span class="command"><strong>hg export</strong></span> the
+	to-be-backed-out changeset as a diff, then use the <code class="option">--reverse</code> option to the
+	<span class="command"><strong>patch</strong></span> 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.</p><p id="x_119"><a name="x_119"></a>The reason that <span class="command"><strong>hg
+	  backout</strong></span> 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
+	<span class="emphasis"><em>between</em></span> the change you're backing out and
+	the current tip.</p><p id="x_11a"><a name="x_11a"></a>If you're backing out a changeset that's 100 revisions
+	back in your project's history, the chances that the
+	<span class="command"><strong>patch</strong></span> command will be able to apply a
+	reverse diff cleanly are not good, because intervening changes
+	are likely to have “<span class="quote">broken the context</span>” that
+	<span class="command"><strong>patch</strong></span> uses to determine whether it can
+	apply a patch (if this sounds like gibberish, see <a class="xref" href="managing-change-with-mercurial-queues.html#sec:mq:patch" title="Understanding patches">the section called “Understanding patches”</a> for a
+	discussion of the <span class="command"><strong>patch</strong></span> command).  Also,
+	Mercurial's merge machinery will handle files and directories
+	being renamed, permission changes, and modifications to binary
+	files, none of which <span class="command"><strong>patch</strong></span> can deal
+	with.</p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="sec:undo:aaaiiieee">Changes that should never have been</h2></div></div></div><p id="x_11b"><a name="x_11b"></a>Most of the time, the <span class="command"><strong>hg
+	backout</strong></span> 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.</p><p id="x_11c"><a name="x_11c"></a>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 <span class="emphasis"><em>big</em></span>,
+      so they increase the size of the repository and the amount of
+      time it takes to clone or pull changes.</p><p id="x_11d"><a name="x_11d"></a>Before I discuss the options that you have if you commit a
+      “<span class="quote">brown paper bag</span>” 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.</p><p id="x_11e"><a name="x_11e"></a>Since Mercurial treats history as
+      accumulative—every change builds on top of all changes
+      that preceded it—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 <span class="command"><strong>hg rollback</strong></span> command, as I detailed in
+      <a class="xref" href="finding-and-fixing-mistakes.html#sec:undo:rollback" title="Rolling back a transaction">the section called “Rolling back a transaction”</a>.</p><p id="x_11f"><a name="x_11f"></a>After you've pushed a bad change to another repository, you
+      <span class="emphasis"><em>could</em></span> still use <span class="command"><strong>hg
+	rollback</strong></span> 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.</p><p id="x_120"><a name="x_120"></a>If a situation like this arises, and you know which
+      repositories your bad change has propagated into, you can
+      <span class="emphasis"><em>try</em></span> to get rid of the change from
+      <span class="emphasis"><em>every</em></span> 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
+      “<span class="quote">in the wild</span>”, and could propagate further.</p><p id="x_121"><a name="x_121"></a>If you've committed one or more changes
+      <span class="emphasis"><em>after</em></span> the change that you'd like to see
+      disappear, your options are further reduced. Mercurial doesn't
+      provide a way to “<span class="quote">punch a hole</span>” in history, leaving
+      changesets intact.</p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id394303">Backing out a merge</h3></div></div></div><p id="x_6ba"><a name="x_6ba"></a>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.</p><p id="x_6bb"><a name="x_6bb"></a>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 <span class="command"><strong>hg backout</strong></span> command may help in
+	making the cleanup easier. It offers a <code class="option">--parent</code> option, which lets
+	you specify which parent to revert to when backing out a
+	merge.</p><div class="figure"><a name="fig:undo:bad-merge-1"></a><p class="title"><b>Figure 9.5. A bad merge</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/bad-merge-1.png" alt="XXX add text"></div></div></div><br class="figure-break"><p id="x_6bc"><a name="x_6bc"></a>Suppose we have a revision graph like that in <a class="xref" href="finding-and-fixing-mistakes.html#fig:undo:bad-merge-1" title="Figure 9.5. A bad merge">Figure 9.5, “A bad merge”</a>.  What we'd like is to
+	<span class="emphasis"><em>redo</em></span> the merge of revisions 2 and
+	3.</p><p id="x_6bd"><a name="x_6bd"></a>One way to do so would be as follows.</p><div class="orderedlist"><ol type="1"><li><p id="x_6be"><a name="x_6be"></a>Call <span class="command"><strong>hg backout --rev=4
+	      --parent=2</strong></span>.  This tells <span class="command"><strong>hg backout</strong></span> 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 <a class="xref" href="finding-and-fixing-mistakes.html#fig:undo:bad-merge-2" title="Figure 9.6. Backing out the merge, favoring one parent">Figure 9.6, “Backing out the merge, favoring one parent”</a>.</p><div class="figure"><a name="fig:undo:bad-merge-2"></a><p class="title"><b>Figure 9.6. Backing out the merge, favoring one parent</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/bad-merge-2.png" alt="XXX add text"></div></div></div><br class="figure-break"></li><li><p id="x_6bf"><a name="x_6bf"></a>Call <span class="command"><strong>hg backout --rev=4
+	      --parent=3</strong></span>.  This tells <span class="command"><strong>hg backout</strong></span> to back out revision
+	    4 again, but this time to choose parent 3, the other
+	    parent of the merge.  The result is visible in <a class="xref" href="finding-and-fixing-mistakes.html#fig:undo:bad-merge-3" title="Figure 9.7. Backing out the merge, favoring the other parent">Figure 9.7, “Backing out the merge, favoring the other
+	      parent”</a>, in which the repository
+	    now contains three heads.</p><div class="figure"><a name="fig:undo:bad-merge-3"></a><p class="title"><b>Figure 9.7. Backing out the merge, favoring the other
+	      parent</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/bad-merge-3.png" alt="XXX add text"></div></div></div><br class="figure-break"></li><li><p id="x_6c0"><a name="x_6c0"></a>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 <a class="xref" href="finding-and-fixing-mistakes.html#fig:undo:bad-merge-4" title="Figure 9.8. Merging the backouts">Figure 9.8, “Merging the backouts”</a>.</p><div class="figure"><a name="fig:undo:bad-merge-4"></a><p class="title"><b>Figure 9.8. Merging the backouts</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/bad-merge-4.png" alt="XXX add text"></div></div></div><br class="figure-break"></li><li><p id="x_6c1"><a name="x_6c1"></a>Merge with the commit that was made after the bad
+	    merge, as shown in <a class="xref" href="finding-and-fixing-mistakes.html#fig:undo:bad-merge-5" title="Figure 9.9. Merging the backouts">Figure 9.9, “Merging the backouts”</a>.</p><div class="figure"><a name="fig:undo:bad-merge-5"></a><p class="title"><b>Figure 9.9. Merging the backouts</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/bad-merge-5.png" alt="XXX add text"></div></div></div><br class="figure-break"></li></ol></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id394612">Protect yourself from “<span class="quote">escaped</span>”
+	changes</h3></div></div></div><p id="x_123"><a name="x_123"></a>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.</p><p id="x_124"><a name="x_124"></a>By configuring some hooks on that repository to validate
+	incoming changesets (see chapter <a class="xref" href="handling-repository-events-with-hooks.html" title="Chapter 10. Handling repository events with hooks">Chapter 10, <i>Handling repository events with hooks</i></a>),
+	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 “<span class="quote">die out</span>” because they can't
+	propagate into the central repository.  Better yet, this
+	happens without any need for explicit intervention.</p><p id="x_125"><a name="x_125"></a>For instance, an incoming change hook that
+	verifies that a changeset will actually compile can prevent
+	people from inadvertently “<span class="quote">breaking the
+	  build</span>”.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id394667">What to do about sensitive changes that escape</h3></div></div></div><p id="x_6c2"><a name="x_6c2"></a>Even a carefully run project can suffer an unfortunate
+	event such as the committing and uncontrolled propagation of a
+	file that contains important passwords.</p><p id="x_6c3"><a name="x_6c3"></a>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.</p><p id="x_6c4"><a name="x_6c4"></a>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.</p><p id="x_6c5"><a name="x_6c5"></a>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.</p><p id="x_6c6"><a name="x_6c6"></a>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 “<span class="quote">make this file
+	  disappear</span>” 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.</p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="sec:undo:bisect">Finding the source of a bug</h2></div></div></div><p id="x_126"><a name="x_126"></a>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 <span class="command"><strong>hg bisect</strong></span>, that
+      helps you to automate this process and accomplish it very
+      efficiently.</p><p id="x_127"><a name="x_127"></a>The idea behind the <span class="command"><strong>hg
+	bisect</strong></span> 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 <span class="command"><strong>hg bisect</strong></span> command uses your
+      test to direct its search for the changeset that introduced the
+      code that caused the bug.</p><p id="x_128"><a name="x_128"></a>Here are a few scenarios to help you understand how you
+      might apply this command.</p><div class="itemizedlist"><ul type="disc"><li><p id="x_129"><a name="x_129"></a>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.</p></li><li><p id="x_12a"><a name="x_12a"></a>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.</p></li><li><p id="x_12b"><a name="x_12b"></a>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 “<span class="quote">fast</span>” or
+	  “<span class="quote">slow</span>”.</p></li><li><p id="x_12c"><a name="x_12c"></a>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.</p></li></ul></div><p id="x_12d"><a name="x_12d"></a>From these examples, it should be clear that the <span class="command"><strong>hg bisect</strong></span> command is not useful only
+      for finding the sources of bugs.  You can use it to find any
+      “<span class="quote">emergent property</span>” 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.</p><p id="x_12e"><a name="x_12e"></a>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
+      <span class="emphasis"><em>test</em></span> is something that
+      <span class="emphasis"><em>you</em></span> run when <span class="command"><strong>hg
+	bisect</strong></span> chooses a changeset.  A
+      <span class="emphasis"><em>probe</em></span> is what <span class="command"><strong>hg
+	bisect</strong></span> runs to tell whether a revision is good.
+      Finally, we'll use the word “<span class="quote">bisect</span>”, as both a
+      noun and a verb, to stand in for the phrase “<span class="quote">search using
+	the <span class="command"><strong>hg bisect</strong></span>
+
+	command</span>”.</p><p id="x_12f"><a name="x_12f"></a>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 <span class="emphasis"><em>days</em></span> 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.</p><p id="x_130"><a name="x_130"></a>What the <span class="command"><strong>hg bisect</strong></span> command
+      does is use its knowledge of the “<span class="quote">shape</span>” of your
+      project's revision history to perform a search in time
+      proportional to the <span class="emphasis"><em>logarithm</em></span> 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).</p><p id="x_131"><a name="x_131"></a>The <span class="command"><strong>hg bisect</strong></span> command is
+      aware of the “<span class="quote">branchy</span>” 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.</p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id394992">Using the <span class="command"><strong>hg bisect</strong></span>
+
+	command</h3></div></div></div><p id="x_132"><a name="x_132"></a>Here's an example of <span class="command"><strong>hg
+	  bisect</strong></span> in action.</p><div class="note"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="/support/figs/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p id="x_133"><a name="x_133"></a>  In versions 0.9.5 and earlier of Mercurial, <span class="command"><strong>hg bisect</strong></span> was not a core command:
+	  it was distributed with Mercurial as an extension. This
+	  section describes the built-in command, not the old
+	  extension.</p></td></tr></table></div><p id="x_134"><a name="x_134"></a>Now let's create a repository, so that we can try out the
+	<span class="command"><strong>hg bisect</strong></span> command in
+	isolation.</p><pre id="id395406" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg init mybug</code></strong>
+
+<code class="prompt">$</code> <strong class="userinput"><code>cd mybug</code></strong>
+</pre><p id="x_135"><a name="x_135"></a>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
+	“<span class="quote">bug</span>”.  This loop creates 35 changesets, each
+	adding a single file to the repository. We'll represent our
+	“<span class="quote">bug</span>” with a file that contains the text “<span class="quote">i
+	  have a gub</span>”.</p><pre id="id395397" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>buggy_change=22</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>for (( i = 0; i &lt; 35; i++ )); do</code></strong>
+
+<code class="prompt">&gt;</code> <strong class="userinput"><code>  if [[ $i = $buggy_change ]]; then</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>    echo 'i have a gub' &gt; myfile$i</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>    hg commit -q -A -m 'buggy changeset'</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>  else</code></strong>
+
+<code class="prompt">&gt;</code> <strong class="userinput"><code>    echo 'nothing to see here, move along' &gt; myfile$i</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>    hg commit -q -A -m 'normal changeset'</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>  fi</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>done</code></strong>
+
+</pre><p id="x_136"><a name="x_136"></a>The next thing that we'd like to do is figure out how to
+	use the <span class="command"><strong>hg bisect</strong></span> command.
+	We can use Mercurial's normal built-in help mechanism for
+	this.</p><pre id="id395535" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg help bisect</code></strong>
+hg bisect [-gbsr] [-c CMD] [REV]
+
+subdivision search of changesets
+
+    This command helps to find changesets which introduce problems.
+    To use, mark the earliest changeset you know exhibits the problem
+    as bad, then mark the latest changeset which is free from the
+    problem as good. Bisect will update your working directory to a
+    revision for testing (unless the --noupdate option is specified).
+    Once you have performed tests, mark the working directory as bad
+    or good and bisect will either update to another candidate changeset
+    or announce that it has found the bad revision.
+
+    As a shortcut, you can also use the revision argument to mark a
+    revision as good or bad without checking it out first.
+
+    If you supply a command it will be used for automatic bisection. Its exit
+    status will be used as flag to mark revision as bad or good. In case exit
+    status is 0 the revision is marked as good, 125 - skipped, 127 (command not
+    found) - bisection will be aborted; any other status bigger than 0 will
+    mark revision as bad.
+
+options:
+
+ -r --reset     reset bisect state
+ -g --good      mark changeset good
+ -b --bad       mark changeset bad
+ -s --skip      skip testing changeset
+ -c --command   use command to check changeset state
+ -U --noupdate  do not update to target
+
+use "hg -v help bisect" to show global options
+</pre><p id="x_137"><a name="x_137"></a>The <span class="command"><strong>hg bisect</strong></span> command
+	works in steps.  Each step proceeds as follows.</p><div class="orderedlist"><ol type="1"><li><p id="x_138"><a name="x_138"></a>You run your binary test.</p><div class="itemizedlist"><ul type="disc"><li><p id="x_139"><a name="x_139"></a>If the test succeeded, you tell <span class="command"><strong>hg bisect</strong></span> by running the
+		<span class="command"><strong>hg bisect --good</strong></span>
+
+		command.</p></li><li><p id="x_13a"><a name="x_13a"></a>If it failed, run the <span class="command"><strong>hg bisect --bad</strong></span>
+		command.</p></li></ul></div></li><li><p id="x_13b"><a name="x_13b"></a>The command uses your information to decide
+	    which changeset to test next.</p></li><li><p id="x_13c"><a name="x_13c"></a>It updates the working directory to that
+	    changeset, and the process begins again.</p></li></ol></div><p id="x_13d"><a name="x_13d"></a>The process ends when <span class="command"><strong>hg
+	  bisect</strong></span> identifies a unique changeset that marks
+	the point where your test transitioned from
+	“<span class="quote">succeeding</span>” to “<span class="quote">failing</span>”.</p><p id="x_13e"><a name="x_13e"></a>To start the search, we must run the <span class="command"><strong>hg bisect --reset</strong></span> command.</p><pre id="id395968" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg bisect --reset</code></strong>
+
+</pre><p id="x_13f"><a name="x_13f"></a>In our case, the binary test we use is simple: we check to
+	see if any file in the repository contains the string “<span class="quote">i
+	  have a gub</span>”.  If it does, this changeset contains the
+	change that “<span class="quote">caused the bug</span>”.  By convention, a
+	changeset that has the property we're searching for is
+	“<span class="quote">bad</span>”, while one that doesn't is
+	“<span class="quote">good</span>”.</p><p id="x_140"><a name="x_140"></a>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
+	“<span class="quote">bad</span>”.</p><pre id="id396047" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg bisect --bad</code></strong>
+</pre><p id="x_141"><a name="x_141"></a>Our next task is to nominate a changeset that we know
+	<span class="emphasis"><em>doesn't</em></span> have the bug; the <span class="command"><strong>hg bisect</strong></span> command will
+	“<span class="quote">bracket</span>” 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 “<span class="quote">good</span>” changeset later.)</p><pre id="id396032" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg bisect --good 10</code></strong>
+
+Testing changeset 22:b8789808fc48 (24 changesets remaining, ~4 tests)
+0 files updated, 0 files merged, 12 files removed, 0 files unresolved
+</pre><p id="x_142"><a name="x_142"></a>Notice that this command printed some output.</p><div class="itemizedlist"><ul type="disc"><li><p id="x_143"><a name="x_143"></a>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.</p></li><li><p id="x_144"><a name="x_144"></a>It updated the working directory to the next
+	    changeset to test, and told us which changeset it's
+	    testing.</p></li></ul></div><p id="x_145"><a name="x_145"></a>We now run our test in the working directory.  We use the
+	<span class="command"><strong>grep</strong></span> command to see if our
+	“<span class="quote">bad</span>” file is present in the working directory.
+	If it is, this revision is bad; if not, this revision is good.
+	
+</p><pre id="id395911" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>if grep -q 'i have a gub' *</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>then</code></strong>
+
+<code class="prompt">&gt;</code> <strong class="userinput"><code>  result=bad</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>else</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>  result=good</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>fi</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>echo this revision is $result</code></strong>
+
+this revision is bad
+<code class="prompt">$</code> <strong class="userinput"><code>hg bisect --$result</code></strong>
+Testing changeset 16:e61fdddff53e (12 changesets remaining, ~3 tests)
+0 files updated, 0 files merged, 6 files removed, 0 files unresolved
+</pre><p>
+
+</p><p id="x_146"><a name="x_146"></a>This test looks like a perfect candidate for automation,
+	so let's turn it into a shell function.</p><pre id="id396435" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>mytest() {</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>  if grep -q 'i have a gub' *</code></strong>
+
+<code class="prompt">&gt;</code> <strong class="userinput"><code>  then</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>    result=bad</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>  else</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>    result=good</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>  fi</code></strong>
+
+<code class="prompt">&gt;</code> <strong class="userinput"><code>  echo this revision is $result</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>  hg bisect --$result</code></strong>
+<code class="prompt">&gt;</code> <strong class="userinput"><code>}</code></strong>
+</pre><p id="x_147"><a name="x_147"></a>We can now run an entire test step with a single command,
+	<code class="literal">mytest</code>.</p><pre id="id396403" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>mytest</code></strong>
+
+this revision is good
+Testing changeset 19:706df39b003b (6 changesets remaining, ~2 tests)
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+</pre><p id="x_148"><a name="x_148"></a>A few more invocations of our canned test step command,
+	and we're done.</p><pre id="id396344" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>mytest</code></strong>
+this revision is good
+Testing changeset 20:bf7ea9a054e6 (3 changesets remaining, ~1 tests)
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+<code class="prompt">$</code> <strong class="userinput"><code>mytest</code></strong>
+this revision is good
+Testing changeset 21:921391dd45c1 (2 changesets remaining, ~1 tests)
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+<code class="prompt">$</code> <strong class="userinput"><code>mytest</code></strong>
+this revision is good
+The first bad revision is:
+changeset:   22:b8789808fc48
+user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
+
+date:        Tue May 05 06:55:14 2009 +0000
+summary:     buggy changeset
+
+</pre><p id="x_149"><a name="x_149"></a>Even though we had 40 changesets to search through, the
+	<span class="command"><strong>hg bisect</strong></span> command let us find
+	the changeset that introduced our “<span class="quote">bug</span>” with only
+	five tests.  Because the number of tests that the <span class="command"><strong>hg bisect</strong></span> command performs grows
+	logarithmically with the number of changesets to search, the
+	advantage that it has over the “<span class="quote">brute force</span>”
+	search approach increases with every changeset you add.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id396541">Cleaning up after your search</h3></div></div></div><p id="x_14a"><a name="x_14a"></a>When you're finished using the <span class="command"><strong>hg
+	  bisect</strong></span> command in a repository, you can use the
+	<span class="command"><strong>hg bisect --reset</strong></span> 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, <span class="command"><strong>hg bisect</strong></span> won't let you start a new
+	search in that repository until you do a <span class="command"><strong>hg bisect --reset</strong></span>.</p><pre id="id396936" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg bisect --reset</code></strong>
+
+</pre></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id396622">Tips for finding bugs effectively</h2></div></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id396628">Give consistent input</h3></div></div></div><p id="x_14b"><a name="x_14b"></a>The <span class="command"><strong>hg bisect</strong></span> 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 <span class="emphasis"><em>might</em></span> 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.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id396884">Automate as much as possible</h3></div></div></div><p id="x_14c"><a name="x_14c"></a>When I started using the <span class="command"><strong>hg
+	  bisect</strong></span> 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.</p><p id="x_14d"><a name="x_14d"></a>My initial problems with driving the <span class="command"><strong>hg bisect</strong></span> 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 <span class="command"><strong>hg bisect</strong></span> 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.</p><p id="x_14e"><a name="x_14e"></a>The key to automated testing is twofold:</p><div class="itemizedlist"><ul type="disc"><li><p id="x_14f"><a name="x_14f"></a>always test for the same symptom, and</p></li><li><p id="x_150"><a name="x_150"></a>always feed consistent input to the <span class="command"><strong>hg bisect</strong></span> command.</p></li></ul></div><p id="x_151"><a name="x_151"></a>In my tutorial example above, the <span class="command"><strong>grep</strong></span>
+
+	command tests for the symptom, and the <code class="literal">if</code>
+	statement takes the result of this check and ensures that we
+	always feed the same input to the <span class="command"><strong>hg
+	  bisect</strong></span> command.  The <code class="literal">mytest</code>
+	function marries these together in a reproducible way, so that
+	every test is uniform and consistent.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id396713">Check your results</h3></div></div></div><p id="x_152"><a name="x_152"></a>Because the output of a <span class="command"><strong>hg
+	  bisect</strong></span> 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:</p><div class="itemizedlist"><ul type="disc"><li><p id="x_153"><a name="x_153"></a>The changeset that it reports as the first bad
+	    revision.  Your test should still report this as
+	    bad.</p></li><li><p id="x_154"><a name="x_154"></a>The parent of that changeset (either parent,
+	    if it's a merge). Your test should report this changeset
+	    as good.</p></li><li><p id="x_155"><a name="x_155"></a>A child of that changeset.  Your test should
+	    report this changeset as bad.</p></li></ul></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id396770">Beware interference between bugs</h3></div></div></div><p id="x_156"><a name="x_156"></a>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.</p><p id="x_157"><a name="x_157"></a>It is possible that this other bug completely
+	“<span class="quote">masks</span>” 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 <span class="command"><strong>hg
+	  bisect</strong></span> command cannot help you directly.  Instead,
+	you can mark a changeset as untested by running <span class="command"><strong>hg bisect --skip</strong></span>.</p><p id="x_158"><a name="x_158"></a>A different problem could arise if your test for a bug's
+	presence is not specific enough.  If you check for “<span class="quote">my
+	  program crashes</span>”, then both your crashing bug and an
+	unrelated crashing bug that masks it will look like the same
+	thing, and mislead <span class="command"><strong>hg
+	  bisect</strong></span>.</p><p id="x_159"><a name="x_159"></a>Another useful situation in which to use <span class="command"><strong>hg bisect --skip</strong></span> 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.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id396856">Bracket your search lazily</h3></div></div></div><p id="x_15a"><a name="x_15a"></a>Choosing the first “<span class="quote">good</span>” and
+	“<span class="quote">bad</span>” changesets that will mark the end points of
+	your search is often easy, but it bears a little discussion
+	nevertheless.  From the perspective of <span class="command"><strong>hg bisect</strong></span>, the “<span class="quote">newest</span>”
+	changeset is conventionally “<span class="quote">bad</span>”, and the older
+	changeset is “<span class="quote">good</span>”.</p><p id="x_15b"><a name="x_15b"></a>If you're having trouble remembering when a suitable
+	“<span class="quote">good</span>” change was, so that you can tell <span class="command"><strong>hg bisect</strong></span>, 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).</p><p id="x_15c"><a name="x_15c"></a>Even if you end up “<span class="quote">early</span>” by thousands of
+	changesets or months of history, you will only add a handful
+	of tests to the total number that <span class="command"><strong>hg
+	  bisect</strong></span> must perform, thanks to its logarithmic
+	behavior.</p></div></div></div><div class="hgfooter"><p><img src="/support/figs/rss.png"> Want to stay up to date? Subscribe to the comment feed for <a id="chapterfeed" class="feed" href="/feeds/comments/">this chapter</a>, or the <a class="feed" href="/feeds/comments/">entire book</a>.</p><p>Copyright 2006, 2007, 2008, 2009 Bryan O'Sullivan.
+      Icons by <a href="mailto:mattahan@gmail.com">Paul Davey</a> aka <a href="http://mattahan.deviantart.com/">Mattahan</a>.</p></div><div class="navfooter"><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="managing-releases-and-branchy-development.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="handling-repository-events-with-hooks.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 8. Managing releases and branchy development </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 10. Handling repository events with hooks</td></tr></table></div><script type="text/javascript">
+    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+    document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+    </script><script type="text/javascript">
+    try {
+    var pageTracker = _gat._getTracker("UA-1805907-5");
+    pageTracker._trackPageview();
+    } catch(err) {}</script></body></html>
+