SEESenv/web/html/backup/abcd.html
author amit@thunder
Fri, 12 Feb 2010 01:11:21 +0530
changeset 2 52d12eb31c30
parent 0 web/html/backup/abcd.html@8083d21c0020
permissions -rwxr-xr-x
Virtual enviroment for SEES-hacks added ...

<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>