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 ...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
     1
<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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
     2
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
     3
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
     4
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
     5
    well takes a top-notch revision control system.  In this chapter,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
     6
    we'll discuss some of the techniques you can use when you find
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
     7
    that a problem has crept into your project.  Mercurial has some
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
     8
    highly capable features that will help you to isolate the sources
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
     9
    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    10
	rather more quickly than I can think, which sometimes results
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    11
	in me committing a changeset that is either incomplete or
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    12
	plain wrong.  In my case, the usual kind of incomplete
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    13
	changeset is one in which I've created a new source file, but
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    14
	forgotten to <span class="command"><strong>hg add</strong></span> it.  A
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    15
	“<span class="quote">plain wrong</span>” changeset is not as common, but no
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    16
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    17
	mentioned that Mercurial treats each modification of a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    18
	repository as a <span class="emphasis"><em>transaction</em></span>.  Every time
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    19
	you commit a changeset or pull changes from another
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    20
	repository, Mercurial remembers what you did.  You can undo,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    21
	or <span class="emphasis"><em>roll back</em></span>, exactly one of these
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    22
	actions using the <span class="command"><strong>hg rollback</strong></span>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    23
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    24
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    25
	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:
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    26
	committing a change in which I've created a new file, but
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    27
	forgotten to <span class="command"><strong>hg add</strong></span>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    28
	it.</p><pre id="id390839" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    29
M a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    30
<code class="prompt">$</code> <strong class="userinput"><code>echo b &gt; b</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    31
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    32
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'Add file b'</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    33
</pre><p id="x_d6"><a name="x_d6"></a>Looking at the output of <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    34
	  status</strong></span> after the commit immediately confirms the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    35
	error.</p><pre id="id390541" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    36
? b
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    37
<code class="prompt">$</code> <strong class="userinput"><code>hg tip</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    38
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    39
changeset:   1:f2db1de2ba4f
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    40
tag:         tip
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    41
user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    42
date:        Tue May 05 06:55:44 2009 +0000
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    43
summary:     Add file b
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    44
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    45
</pre><p id="x_d7"><a name="x_d7"></a>The commit captured the changes to the file
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    46
	<code class="filename">a</code>, but not the new file
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    47
	<code class="filename">b</code>.  If I were to push this changeset to a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    48
	repository that I shared with a colleague, the chances are
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    49
	high that something in <code class="filename">a</code> would refer to
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    50
	<code class="filename">b</code>, which would not be present in their
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    51
	repository when they pulled my changes.  I would thus become
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    52
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    53
	before I pushed the changeset.  I use the <span class="command"><strong>hg rollback</strong></span> command, and Mercurial
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    54
	makes that last changeset vanish.</p><pre id="id391066" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg rollback</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    55
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    56
rolling back last transaction
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    57
<code class="prompt">$</code> <strong class="userinput"><code>hg tip</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    58
changeset:   0:cde70bc943e1
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    59
tag:         tip
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    60
user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    61
date:        Tue May 05 06:55:44 2009 +0000
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    62
summary:     First commit
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    63
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    64
<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    65
M a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    66
? b
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    67
</pre><p id="x_d9"><a name="x_d9"></a>Notice that the changeset is no longer present in the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    68
	repository's history, and the working directory once again
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    69
	thinks that the file <code class="filename">a</code> is modified.  The
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    70
	commit and rollback have left the working directory exactly as
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    71
	it was prior to the commit; the changeset has been completely
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    72
	erased.  I can now safely <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    73
	  add</strong></span> the file <code class="filename">b</code>, and rerun my
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    74
	commit.</p><pre id="id391024" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg add b</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    75
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    76
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'Add file b, this time for real'</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    77
</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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    78
	development branches of a project in different repositories.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    79
	Your development team might have one shared repository for
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    80
	your project's “<span class="quote">0.9</span>” release, and another,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    81
	containing different changes, for the “<span class="quote">1.0</span>”
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    82
	release.</p><p id="x_db"><a name="x_db"></a>Given this, you can imagine that the consequences could be
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    83
	messy if you had a local “<span class="quote">0.9</span>” repository, and
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    84
	accidentally pulled changes from the shared “<span class="quote">1.0</span>”
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    85
	repository into it.  At worst, you could be paying
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    86
	insufficient attention, and push those changes into the shared
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    87
	“<span class="quote">0.9</span>” tree, confusing your entire team (but don't
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    88
	worry, we'll return to this horror scenario later).  However,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    89
	it's more likely that you'll notice immediately, because
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    90
	Mercurial will display the URL it's pulling from, or you will
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    91
	see it pull a suspiciously large number of changes into the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    92
	repository.</p><p id="x_dc"><a name="x_dc"></a>The <span class="command"><strong>hg rollback</strong></span> command
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    93
	will work nicely to expunge all of the changesets that you
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    94
	just pulled.  Mercurial groups all changes from one <span class="command"><strong>hg pull</strong></span> into a single transaction,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    95
	so one <span class="command"><strong>hg rollback</strong></span> is all you
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    96
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    97
	  rollback</strong></span> command drops to zero once you've pushed
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    98
	your changes to another repository.  Rolling back a change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
    99
	makes it disappear entirely, but <span class="emphasis"><em>only</em></span> in
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   100
	the repository in which you perform the <span class="command"><strong>hg rollback</strong></span>.  Because a rollback
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   101
	eliminates history, there's no way for the disappearance of a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   102
	change to propagate between repositories.</p><p id="x_de"><a name="x_de"></a>If you've pushed a change to another
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   103
	repository—particularly if it's a shared
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   104
	repository—it has essentially “<span class="quote">escaped into the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   105
	  wild,</span>” and you'll have to recover from your mistake
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   106
	in a different way.  If you push a changeset somewhere, then
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   107
	roll it back, then pull from the repository you pushed to, the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   108
	changeset you thought you'd gotten rid of will simply reappear
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   109
	in your repository.</p><p id="x_df"><a name="x_df"></a>(If you absolutely know for sure that the change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   110
	you want to roll back is the most recent change in the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   111
	repository that you pushed to, <span class="emphasis"><em>and</em></span> you
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   112
	know that nobody else could have pulled it from that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   113
	repository, you can roll back the changeset there, too, but
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   114
	you really should not expect this to work reliably.  Sooner or
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   115
	later a change really will make it into a repository that you
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   116
	don't directly control (or have forgotten about), and come
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   117
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   118
	transaction log; that transaction is the most recent one that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   119
	occurred in the repository. This means that you can only roll
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   120
	back one transaction.  If you expect to be able to roll back
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   121
	one transaction, then its predecessor, this is not the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   122
	behavior you will get.</p><pre id="id391424" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg rollback</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   123
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   124
rolling back last transaction
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   125
<code class="prompt">$</code> <strong class="userinput"><code>hg rollback</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   126
no rollback information available
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   127
</pre><p id="x_e1"><a name="x_e1"></a>Once you've rolled back one transaction in a repository,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   128
	you can't roll back again in that repository until you perform
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   129
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   130
      really didn't want to change the file at all, and you haven't
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   131
      yet committed your changes, the <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   132
	revert</strong></span> command is the one you'll need.  It looks at
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   133
      the changeset that's the parent of the working directory, and
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   134
      restores the contents of the file to their state as of that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   135
      changeset. (That's a long-winded way of saying that, in the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   136
      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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   137
	revert</strong></span> command works with yet another small example.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   138
      We'll begin by modifying a file that Mercurial is already
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   139
      tracking.</p><pre id="id391316" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cat file</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   140
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   141
original content
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   142
<code class="prompt">$</code> <strong class="userinput"><code>echo unwanted change &gt;&gt; file</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   143
<code class="prompt">$</code> <strong class="userinput"><code>hg diff file</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   144
diff -r b52afd4afc59 file
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   145
--- a/file	Tue May 05 06:55:32 2009 +0000
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   146
+++ b/file	Tue May 05 06:55:32 2009 +0000
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   147
@@ -1,1 +1,2 @@
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   148
 original content
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   149
+unwanted change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   150
</pre><p id="x_e4"><a name="x_e4"></a>If we don't
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   151
      want that change, we can simply <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   152
	revert</strong></span> the file.</p><pre id="id391251" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   153
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   154
M file
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   155
<code class="prompt">$</code> <strong class="userinput"><code>hg revert file</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   156
<code class="prompt">$</code> <strong class="userinput"><code>cat file</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   157
original content
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   158
</pre><p id="x_e5"><a name="x_e5"></a>The <span class="command"><strong>hg revert</strong></span> command
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   159
      provides us with an extra degree of safety by saving our
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   160
      modified file with a <code class="filename">.orig</code>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   161
      extension.</p><pre id="id391767" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   162
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   163
? file.orig
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   164
<code class="prompt">$</code> <strong class="userinput"><code>cat file.orig</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   165
original content
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   166
unwanted change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   167
</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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   168
	Mercurial to manage files with <code class="filename">.orig</code>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   169
	extensions or that you even care about the contents of such
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   170
	files.  Just in case, though, it's useful to remember that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   171
	<span class="command"><strong>hg revert</strong></span> will
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   172
	unconditionally overwrite an existing file with a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   173
	<code class="filename">.orig</code> extension. For instance, if you
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   174
	already have a file named <code class="filename">foo.orig</code> when
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   175
	you revert <code class="filename">foo</code>, the contents of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   176
	<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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   177
      will describe each of these in more detail in the section that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   178
      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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   179
	  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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   180
	  file, it will undo the “<span class="quote">added</span>” state of the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   181
	  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,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   182
	  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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   183
	    remove</strong></span> command to remove a file, it will undo
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   184
	  the “<span class="quote">removed</span>” state of the file, and restore
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   185
	  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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   186
	useful for more than just modified files.  It lets you reverse
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   187
	the results of all of Mercurial's file management
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   188
	commands—<span class="command"><strong>hg add</strong></span>,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   189
	<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,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   190
	then decide that in fact you don't want Mercurial to track it,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   191
	use <span class="command"><strong>hg revert</strong></span> to undo the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   192
	add.  Don't worry; Mercurial will not modify the file in any
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   193
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   194
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   195
<code class="prompt">$</code> <strong class="userinput"><code>hg add oops</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   196
<code class="prompt">$</code> <strong class="userinput"><code>hg status oops</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   197
A oops
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   198
<code class="prompt">$</code> <strong class="userinput"><code>hg revert oops</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   199
<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   200
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   201
? oops
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   202
</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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   203
	<span class="command"><strong>hg revert</strong></span> to restore it to
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   204
	the contents it had as of the parent of the working directory.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   205
	
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   206
</p><pre id="id392036" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg remove file</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   207
<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   208
R file
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   209
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   210
<code class="prompt">$</code> <strong class="userinput"><code>hg revert file</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   211
<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   212
<code class="prompt">$</code> <strong class="userinput"><code>ls file</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   213
file
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   214
</pre><p>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   215
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   216
 This works just as
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   217
	well for a file that you deleted by hand, without telling
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   218
	Mercurial (recall that in Mercurial terminology, this kind of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   219
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   220
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   221
<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   222
! file
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   223
<code class="prompt">$</code> <strong class="userinput"><code>hg revert file</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   224
<code class="prompt">$</code> <strong class="userinput"><code>ls file</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   225
file
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   226
</pre><p id="x_ee"><a name="x_ee"></a>If you revert a <span class="command"><strong>hg copy</strong></span>,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   227
	the copied-to file remains in your working directory
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   228
	afterwards, untracked.  Since a copy doesn't affect the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   229
	copied-from file in any way, Mercurial doesn't do anything
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   230
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   231
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   232
<code class="prompt">$</code> <strong class="userinput"><code>hg revert new-file</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   233
<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   234
? new-file
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   235
</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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   236
      <span class="emphasis"><em>a</em></span>, and another change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   237
      <span class="emphasis"><em>b</em></span> on top of it; you then realise that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   238
      change <span class="emphasis"><em>a</em></span> was incorrect.  Mercurial lets you
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   239
      “<span class="quote">back out</span>” an entire changeset automatically, and
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   240
      building blocks that let you reverse part of a changeset by
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   241
      hand.</p><p id="x_f6"><a name="x_f6"></a>Before you read this section, here's something to
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   242
      keep in mind: the <span class="command"><strong>hg backout</strong></span>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   243
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   244
      command undoes the effect of a change by
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   245
      <span class="emphasis"><em>adding</em></span> to your repository's history, not by
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   246
      modifying or erasing it.  It's the right tool to use if you're
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   247
      fixing bugs, but not if you're trying to undo some change that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   248
      has catastrophic consequences.  To deal with those, see
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   249
      <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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   250
	lets you “<span class="quote">undo</span>” the effects of an entire
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   251
	changeset in an automated fashion.  Because Mercurial's
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   252
	history is immutable, this command <span class="emphasis"><em>does
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   253
	  not</em></span> get rid of the changeset you want to undo.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   254
	Instead, it creates a new changeset that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   255
	<span class="emphasis"><em>reverses</em></span> the effect of the to-be-undone
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   256
	changeset.</p><p id="x_f8"><a name="x_f8"></a>The operation of the <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   257
	  backout</strong></span> command is a little intricate, so let's
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   258
	illustrate it with some examples.  First, we'll create a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   259
	repository with some simple changes.</p><pre id="id392685" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg init myrepo</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   260
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   261
<code class="prompt">$</code> <strong class="userinput"><code>cd myrepo</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   262
<code class="prompt">$</code> <strong class="userinput"><code>echo first change &gt;&gt; myfile</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   263
<code class="prompt">$</code> <strong class="userinput"><code>hg add myfile</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   264
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'first change'</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   265
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   266
<code class="prompt">$</code> <strong class="userinput"><code>echo second change &gt;&gt; myfile</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   267
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'second change'</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   268
</pre><p id="x_f9"><a name="x_f9"></a>The <span class="command"><strong>hg backout</strong></span> command
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   269
	takes a single changeset ID as its argument; this is the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   270
	changeset to back out.  Normally, <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   271
	  backout</strong></span> will drop you into a text editor to write
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   272
	a commit message, so you can record why you're backing the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   273
	change out.  In this example, we provide a commit message on
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   274
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   275
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   276
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   277
reverting myfile
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   278
changeset 2:01adc4672142 backs out changeset 1:7e341ee3be7a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   279
<code class="prompt">$</code> <strong class="userinput"><code>cat myfile</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   280
first change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   281
</pre><p id="x_fb"><a name="x_fb"></a>You can see that the second line from
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   282
	<code class="filename">myfile</code> is no longer present.  Taking a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   283
	look at the output of <span class="command"><strong>hg log</strong></span>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   284
	gives us an idea of what the <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   285
	  backout</strong></span> command has done.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   286
	
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   287
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   288
</p><pre id="id392554" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg log --style compact</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   289
2[tip]   01adc4672142   2009-05-05 06:55 +0000   bos
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   290
  back out second change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   291
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   292
1   7e341ee3be7a   2009-05-05 06:55 +0000   bos
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   293
  second change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   294
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   295
0   56b97fc928f2   2009-05-05 06:55 +0000   bos
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   296
  first change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   297
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   298
</pre><p>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   299
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   300
 Notice that the new changeset
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   301
	that <span class="command"><strong>hg backout</strong></span> has created
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   302
	is a child of the changeset we backed out.  It's easier to see
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   303
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   304
	graphical view of the change history.  As you can see, the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   305
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   306
	you committed, pass the <code class="option">--merge</code> option to the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   307
	<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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   308
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   309
<code class="prompt">$</code> <strong class="userinput"><code>hg clone -r1 myrepo non-tip-repo</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   310
requesting all changes
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   311
adding changesets
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   312
adding manifests
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   313
adding file changes
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   314
added 2 changesets with 2 changes to 1 files
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   315
updating working directory
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   316
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   317
<code class="prompt">$</code> <strong class="userinput"><code>cd non-tip-repo</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   318
</pre><p id="x_fe"><a name="x_fe"></a>This makes backing out any changeset a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   319
	“<span class="quote">one-shot</span>” operation that's usually simple and
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   320
	fast.</p><pre id="id392845" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>echo third change &gt;&gt; myfile</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   321
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   322
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'third change'</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   323
<code class="prompt">$</code> <strong class="userinput"><code>hg backout --merge -m 'back out second change' 1</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   324
reverting myfile
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   325
created new head
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   326
changeset 3:abc7fd860049 backs out changeset 1:7e341ee3be7a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   327
merging with changeset 3:abc7fd860049
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   328
merging myfile
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   329
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   330
(branch merge, don't forget to commit)
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   331
</pre><p id="x_ff"><a name="x_ff"></a>If you take a look at the contents of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   332
	<code class="filename">myfile</code> after the backout finishes, you'll
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   333
	see that the first and third changes are present, but not the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   334
	second.</p><pre id="id392886" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cat myfile</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   335
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   336
first change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   337
third change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   338
</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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   339
	  hg backout command”</a> illustrates, Mercurial
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   340
	still commits one change in this kind of situation (the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   341
	box-shaped node is the ones that Mercurial commits
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   342
	automatically), but the revision graph now looks different.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   343
	Before Mercurial begins the backout process, it first
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   344
	remembers what the current parent of the working directory is.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   345
	It then backs out the target changeset, and commits that as a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   346
	changeset.  Finally, it merges back to the previous parent of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   347
	the working directory, but notice that it <span class="emphasis"><em>does not
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   348
	  commit</em></span> the result of the merge.  The repository
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   349
	now contains two heads, and the working directory is in a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   350
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   351
	  <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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   352
	  were</span>”, only with some extra history that undoes the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   353
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   354
	of the merge that it performed.  The reason lies in Mercurial
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   355
	behaving conservatively: a merge naturally has more scope for
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   356
	error than simply undoing the effect of the tip changeset,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   357
	so your work will be safest if you first inspect (and test!)
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   358
	the result of the merge, <span class="emphasis"><em>then</em></span> commit
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   359
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   360
	  “<span class="quote">right thing</span>” whether or not the changeset
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   361
	  you're backing out is the tip (i.e. it won't try to merge if
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   362
	  it's backing out the tip, since there's no need), you should
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   363
	  <span class="emphasis"><em>always</em></span> use this option when you run the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   364
	  <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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   365
	out a change, the <span class="command"><strong>hg backout</strong></span>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   366
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   367
	command lets you decide how to merge a backout changeset.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   368
	Taking control of the backout process by hand is something you
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   369
	will rarely need to do, but it can be useful to understand
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   370
	what the <span class="command"><strong>hg backout</strong></span> command
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   371
	is doing for you automatically.  To illustrate this, let's
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   372
	clone our first repository, but omit the backout change that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   373
	it contains.</p><pre id="id393568" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cd ..</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   374
<code class="prompt">$</code> <strong class="userinput"><code>hg clone -r1 myrepo newrepo</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   375
requesting all changes
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   376
adding changesets
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   377
adding manifests
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   378
adding file changes
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   379
added 2 changesets with 2 changes to 1 files
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   380
updating working directory
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   381
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   382
<code class="prompt">$</code> <strong class="userinput"><code>cd newrepo</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   383
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   384
</pre><p id="x_106"><a name="x_106"></a>As with our
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   385
	earlier example, We'll commit a third changeset, then back out
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   386
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   387
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'third change'</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   388
<code class="prompt">$</code> <strong class="userinput"><code>hg backout -m 'back out second change' 1</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   389
reverting myfile
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   390
created new head
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   391
changeset 3:abc7fd860049 backs out changeset 1:7e341ee3be7a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   392
the backout changeset is a new head - do not forget to merge
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   393
(use "backout --merge" if you want to auto-merge)
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   394
</pre><p id="x_107"><a name="x_107"></a>Our new changeset is again a descendant of the changeset
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   395
	we backout out; it's thus a new head, <span class="emphasis"><em>not</em></span>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   396
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   397
	a descendant of the changeset that was the tip.  The <span class="command"><strong>hg backout</strong></span> command was quite
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   398
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   399
3[tip]:1   abc7fd860049   2009-05-05 06:55 +0000   bos
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   400
  back out second change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   401
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   402
2   bae4005ddac4   2009-05-05 06:55 +0000   bos
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   403
  third change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   404
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   405
1   7e341ee3be7a   2009-05-05 06:55 +0000   bos
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   406
  second change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   407
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   408
0   56b97fc928f2   2009-05-05 06:55 +0000   bos
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   409
  first change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   410
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   411
</pre><p id="x_108"><a name="x_108"></a>Again, it's easier to see what has happened by looking at
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   412
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   413
	that when we use <span class="command"><strong>hg backout</strong></span>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   414
	to back out a change other than the tip, Mercurial adds a new
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   415
	head to the repository (the change it committed is
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   416
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   417
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   418
	command has completed, it leaves the new
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   419
	“<span class="quote">backout</span>” changeset as the parent of the working
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   420
	directory.</p><pre id="id393912" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg parents</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   421
changeset:   2:bae4005ddac4
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   422
user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   423
date:        Tue May 05 06:55:12 2009 +0000
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   424
summary:     third change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   425
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   426
</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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   427
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   428
changeset:   3:abc7fd860049
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   429
tag:         tip
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   430
parent:      1:7e341ee3be7a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   431
user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   432
date:        Tue May 05 06:55:12 2009 +0000
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   433
summary:     back out second change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   434
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   435
changeset:   2:bae4005ddac4
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   436
user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   437
date:        Tue May 05 06:55:12 2009 +0000
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   438
summary:     third change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   439
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   440
</pre><p id="x_10c"><a name="x_10c"></a>Let's think about what we expect to see as the contents of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   441
	<code class="filename">myfile</code> now.  The first change should be
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   442
	present, because we've never backed it out.  The second change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   443
	should be missing, as that's the change we backed out.  Since
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   444
	the history graph shows the third change as a separate head,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   445
	we <span class="emphasis"><em>don't</em></span> expect to see the third change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   446
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   447
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   448
first change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   449
</pre><p id="x_10d"><a name="x_10d"></a>To get the third change back into the file, we just do a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   450
	normal merge of our two heads.</p><pre id="id393845" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg merge</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   451
abort: outstanding uncommitted changes
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   452
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'merged backout with previous tip'</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   453
<code class="prompt">$</code> <strong class="userinput"><code>cat myfile</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   454
first change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   455
</pre><p id="x_10e"><a name="x_10e"></a>Afterwards, the graphical history of our
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   456
	repository looks like
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   457
	<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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   458
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   459
	    “<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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   460
	    directory.  Let's call this changeset
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   461
	    <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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   462
	    directory to the changeset you want to back out.  Let's
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   463
	    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   464
	    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   465
	    <code class="literal">backout</code> changeset affected, it does the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   466
	    equivalent of a <span class="command"><strong>hg revert -r
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   467
	      parent</strong></span> on that file, to restore it to the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   468
	    contents it had before that changeset was
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   469
	    committed.</p></li><li><p id="x_116"><a name="x_116"></a>It commits the result as a new changeset.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   470
	    This changeset has <code class="literal">backout</code> as its
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   471
	    parent.</p></li><li><p id="x_117"><a name="x_117"></a>If you specify <code class="option">--merge</code> on the command
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   472
	    line, it merges with <code class="literal">orig</code>, and commits
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   473
	    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   474
	<span class="command"><strong>hg export</strong></span> the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   475
	to-be-backed-out changeset as a diff, then use the <code class="option">--reverse</code> option to the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   476
	<span class="command"><strong>patch</strong></span> command to reverse the effect of the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   477
	change without fiddling with the working directory.  This
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   478
	sounds much simpler, but it would not work nearly as
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   479
	well.</p><p id="x_119"><a name="x_119"></a>The reason that <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   480
	  backout</strong></span> does an update, a commit, a merge, and
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   481
	another commit is to give the merge machinery the best chance
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   482
	to do a good job when dealing with all the changes
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   483
	<span class="emphasis"><em>between</em></span> the change you're backing out and
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   484
	the current tip.</p><p id="x_11a"><a name="x_11a"></a>If you're backing out a changeset that's 100 revisions
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   485
	back in your project's history, the chances that the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   486
	<span class="command"><strong>patch</strong></span> command will be able to apply a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   487
	reverse diff cleanly are not good, because intervening changes
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   488
	are likely to have “<span class="quote">broken the context</span>” that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   489
	<span class="command"><strong>patch</strong></span> uses to determine whether it can
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   490
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   491
	discussion of the <span class="command"><strong>patch</strong></span> command).  Also,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   492
	Mercurial's merge machinery will handle files and directories
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   493
	being renamed, permission changes, and modifications to binary
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   494
	files, none of which <span class="command"><strong>patch</strong></span> can deal
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   495
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   496
	backout</strong></span> command is exactly what you need if you want
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   497
      to undo the effects of a change.  It leaves a permanent record
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   498
      of exactly what you did, both when committing the original
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   499
      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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   500
      committed a change that really should not be present in the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   501
      repository at all.  For example, it would be very unusual, and
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   502
      usually considered a mistake, to commit a software project's
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   503
      object files as well as its source files.  Object files have
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   504
      almost no intrinsic value, and they're <span class="emphasis"><em>big</em></span>,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   505
      so they increase the size of the repository and the amount of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   506
      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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   507
      “<span class="quote">brown paper bag</span>” change (the kind that's so bad
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   508
      that you want to pull a brown paper bag over your head), let me
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   509
      first discuss some approaches that probably won't work.</p><p id="x_11e"><a name="x_11e"></a>Since Mercurial treats history as
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   510
      accumulative—every change builds on top of all changes
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   511
      that preceded it—you generally can't just make disastrous
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   512
      changes disappear.  The one exception is when you've just
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   513
      committed a change, and it hasn't been pushed or pulled into
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   514
      another repository.  That's when you can safely use the <span class="command"><strong>hg rollback</strong></span> command, as I detailed in
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   515
      <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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   516
      <span class="emphasis"><em>could</em></span> still use <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   517
	rollback</strong></span> to make your local copy of the change
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   518
      disappear, but it won't have the consequences you want.  The
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   519
      change will still be present in the remote repository, so it
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   520
      will reappear in your local repository the next time you
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   521
      pull.</p><p id="x_120"><a name="x_120"></a>If a situation like this arises, and you know which
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   522
      repositories your bad change has propagated into, you can
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   523
      <span class="emphasis"><em>try</em></span> to get rid of the change from
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   524
      <span class="emphasis"><em>every</em></span> one of those repositories.  This is,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   525
      of course, not a satisfactory solution: if you miss even a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   526
      single repository while you're expunging, the change is still
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   527
      “<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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   528
      <span class="emphasis"><em>after</em></span> the change that you'd like to see
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   529
      disappear, your options are further reduced. Mercurial doesn't
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   530
      provide a way to “<span class="quote">punch a hole</span>” in history, leaving
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   531
      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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   532
	for a merge to be mangled badly, but committed erroneously.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   533
	Mercurial provides an important safeguard against bad merges
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   534
	by refusing to commit unresolved files, but human ingenuity
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   535
	guarantees that it is still possible to mess a merge up and
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   536
	commit it.</p><p id="x_6bb"><a name="x_6bb"></a>Given a bad merge that has been committed, usually the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   537
	best way to approach it is to simply try to repair the damage
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   538
	by hand.  A complete disaster that cannot be easily fixed up
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   539
	by hand ought to be very rare, but the <span class="command"><strong>hg backout</strong></span> command may help in
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   540
	making the cleanup easier. It offers a <code class="option">--parent</code> option, which lets
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   541
	you specify which parent to revert to when backing out a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   542
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   543
	<span class="emphasis"><em>redo</em></span> the merge of revisions 2 and
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   544
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   545
	      --parent=2</strong></span>.  This tells <span class="command"><strong>hg backout</strong></span> to back out revision
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   546
	    4, which is the bad merge, and to when deciding which
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   547
	    revision to prefer, to choose parent 2, one of the parents
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   548
	    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   549
	      --parent=3</strong></span>.  This tells <span class="command"><strong>hg backout</strong></span> to back out revision
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   550
	    4 again, but this time to choose parent 3, the other
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   551
	    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   552
	      parent”</a>, in which the repository
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   553
	    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   554
	      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,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   555
	    which reduces the number of heads in the repository to
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   556
	    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   557
	    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>”
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   558
	changes</h3></div></div></div><p id="x_123"><a name="x_123"></a>If you've committed some changes to your local repository
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   559
	and they've been pushed or pulled somewhere else, this isn't
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   560
	necessarily a disaster.  You can protect yourself ahead of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   561
	time against some classes of bad changeset.  This is
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   562
	particularly easy if your team usually pulls changes from a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   563
	central repository.</p><p id="x_124"><a name="x_124"></a>By configuring some hooks on that repository to validate
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   564
	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>),
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   565
	you can
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   566
	automatically prevent some kinds of bad changeset from being
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   567
	pushed to the central repository at all.  With such a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   568
	configuration in place, some kinds of bad changeset will
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   569
	naturally tend to “<span class="quote">die out</span>” because they can't
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   570
	propagate into the central repository.  Better yet, this
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   571
	happens without any need for explicit intervention.</p><p id="x_125"><a name="x_125"></a>For instance, an incoming change hook that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   572
	verifies that a changeset will actually compile can prevent
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   573
	people from inadvertently “<span class="quote">breaking the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   574
	  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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   575
	event such as the committing and uncontrolled propagation of a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   576
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   577
	that gets accidentally propagated is truly sensitive, your
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   578
	first step should be to mitigate the effect of the leak
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   579
	without trying to control the leak itself. If you are not 100%
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   580
	certain that you know exactly who could have seen the changes,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   581
	you should immediately change passwords, cancel credit cards,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   582
	or find some other way to make sure that the information that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   583
	has leaked is no longer useful.  In other words, assume that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   584
	the change has propagated far and wide, and that there's
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   585
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   586
	use to either figure out who has seen a change or to erase the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   587
	change permanently everywhere, but there are good reasons why
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   588
	these are not possible.</p><p id="x_6c5"><a name="x_6c5"></a>Mercurial does not provide an audit trail of who has
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   589
	pulled changes from a repository, because it is usually either
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   590
	impossible to record such information or trivial to spoof it.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   591
	In a multi-user or networked environment, you should thus be
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   592
	extremely skeptical of yourself if you think that you have
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   593
	identified every place that a sensitive changeset has
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   594
	propagated to.  Don't forget that people can and will send
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   595
	bundles by email, have their backup software save data
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   596
	offsite, carry repositories on USB sticks, and find other
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   597
	completely innocent ways to confound your attempts to track
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   598
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   599
	changeset completely disappear from history, because there is
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   600
	no way to enforce its disappearance; someone could easily
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   601
	modify their copy of Mercurial to ignore such directives. In
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   602
	addition, even if Mercurial provided such a capability,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   603
	someone who simply hadn't pulled a “<span class="quote">make this file
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   604
	  disappear</span>” changeset wouldn't be affected by it, nor
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   605
	would web crawlers visiting at the wrong time, disk backups,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   606
	or other mechanisms.  Indeed, no distributed revision control
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   607
	system can make data reliably vanish. Providing the illusion
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   608
	of such control could easily give a false sense of security,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   609
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   610
      that introduced a bug, this requires that you know which
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   611
      changeset to back out.  Mercurial provides an invaluable
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   612
      command, called <span class="command"><strong>hg bisect</strong></span>, that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   613
      helps you to automate this process and accomplish it very
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   614
      efficiently.</p><p id="x_127"><a name="x_127"></a>The idea behind the <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   615
	bisect</strong></span> command is that a changeset has introduced
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   616
      some change of behavior that you can identify with a simple
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   617
      pass/fail test.  You don't know which piece of code introduced the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   618
      change, but you know how to test for the presence of the bug.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   619
      The <span class="command"><strong>hg bisect</strong></span> command uses your
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   620
      test to direct its search for the changeset that introduced the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   621
      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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   622
      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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   623
	  bug that you remember wasn't present a few weeks ago, but
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   624
	  you don't know when it was introduced.  Here, your binary
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   625
	  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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   626
	  close the entry in your team's bug database.  The bug
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   627
	  database requires a changeset ID when you close an entry,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   628
	  but you don't remember which changeset you fixed the bug in.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   629
	  Once again, your binary test checks for the presence of the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   630
	  bug.</p></li><li><p id="x_12b"><a name="x_12b"></a>Your software works correctly, but runs 15%
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   631
	  slower than the last time you measured it.  You want to know
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   632
	  which changeset introduced the performance regression.  In
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   633
	  this case, your binary test measures the performance of your
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   634
	  software, to see whether it's “<span class="quote">fast</span>” or
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   635
	  “<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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   636
	  you ship exploded recently, and you suspect that something
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   637
	  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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   638
      for finding the sources of bugs.  You can use it to find any
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   639
      “<span class="quote">emergent property</span>” of a repository (anything that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   640
      you can't find from a simple text search of the files in the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   641
      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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   642
      make it clear which parts of the search process are your
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   643
      responsibility, and which are Mercurial's.  A
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   644
      <span class="emphasis"><em>test</em></span> is something that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   645
      <span class="emphasis"><em>you</em></span> run when <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   646
	bisect</strong></span> chooses a changeset.  A
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   647
      <span class="emphasis"><em>probe</em></span> is what <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   648
	bisect</strong></span> runs to tell whether a revision is good.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   649
      Finally, we'll use the word “<span class="quote">bisect</span>”, as both a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   650
      noun and a verb, to stand in for the phrase “<span class="quote">search using
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   651
	the <span class="command"><strong>hg bisect</strong></span>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   652
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   653
	command</span>”.</p><p id="x_12f"><a name="x_12f"></a>One simple way to automate the searching process would be
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   654
      simply to probe every changeset.  However, this scales poorly.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   655
      If it took ten minutes to test a single changeset, and you had
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   656
      10,000 changesets in your repository, the exhaustive approach
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   657
      would take on average 35 <span class="emphasis"><em>days</em></span> to find the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   658
      changeset that introduced a bug.  Even if you knew that the bug
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   659
      was introduced by one of the last 500 changesets, and limited
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   660
      your search to those, you'd still be looking at over 40 hours to
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   661
      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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   662
      does is use its knowledge of the “<span class="quote">shape</span>” of your
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   663
      project's revision history to perform a search in time
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   664
      proportional to the <span class="emphasis"><em>logarithm</em></span> of the number
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   665
      of changesets to check (the kind of search it performs is called
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   666
      a dichotomic search).  With this approach, searching through
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   667
      10,000 changesets will take less than three hours, even at ten
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   668
      minutes per test (the search will require about 14 tests).
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   669
      Limit your search to the last hundred changesets, and it will
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   670
      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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   671
      aware of the “<span class="quote">branchy</span>” nature of a Mercurial
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   672
      project's revision history, so it has no problems dealing with
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   673
      branches, merges, or multiple heads in a repository.  It can
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   674
      prune entire branches of history with a single probe, which is
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   675
      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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   676
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   677
	command</h3></div></div></div><p id="x_132"><a name="x_132"></a>Here's an example of <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   678
	  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:
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   679
	  it was distributed with Mercurial as an extension. This
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   680
	  section describes the built-in command, not the old
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   681
	  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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   682
	<span class="command"><strong>hg bisect</strong></span> command in
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   683
	isolation.</p><pre id="id395406" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg init mybug</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   684
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   685
<code class="prompt">$</code> <strong class="userinput"><code>cd mybug</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   686
</pre><p id="x_135"><a name="x_135"></a>We'll simulate a project that has a bug in it in a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   687
	simple-minded way: create trivial changes in a loop, and
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   688
	nominate one specific change that will have the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   689
	“<span class="quote">bug</span>”.  This loop creates 35 changesets, each
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   690
	adding a single file to the repository. We'll represent our
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   691
	“<span class="quote">bug</span>” with a file that contains the text “<span class="quote">i
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   692
	  have a gub</span>”.</p><pre id="id395397" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>buggy_change=22</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   693
<code class="prompt">$</code> <strong class="userinput"><code>for (( i = 0; i &lt; 35; i++ )); do</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   694
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   695
<code class="prompt">&gt;</code> <strong class="userinput"><code>  if [[ $i = $buggy_change ]]; then</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   696
<code class="prompt">&gt;</code> <strong class="userinput"><code>    echo 'i have a gub' &gt; myfile$i</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   697
<code class="prompt">&gt;</code> <strong class="userinput"><code>    hg commit -q -A -m 'buggy changeset'</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   698
<code class="prompt">&gt;</code> <strong class="userinput"><code>  else</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   699
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   700
<code class="prompt">&gt;</code> <strong class="userinput"><code>    echo 'nothing to see here, move along' &gt; myfile$i</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   701
<code class="prompt">&gt;</code> <strong class="userinput"><code>    hg commit -q -A -m 'normal changeset'</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   702
<code class="prompt">&gt;</code> <strong class="userinput"><code>  fi</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   703
<code class="prompt">&gt;</code> <strong class="userinput"><code>done</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   704
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   705
</pre><p id="x_136"><a name="x_136"></a>The next thing that we'd like to do is figure out how to
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   706
	use the <span class="command"><strong>hg bisect</strong></span> command.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   707
	We can use Mercurial's normal built-in help mechanism for
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   708
	this.</p><pre id="id395535" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg help bisect</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   709
hg bisect [-gbsr] [-c CMD] [REV]
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   710
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   711
subdivision search of changesets
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   712
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   713
    This command helps to find changesets which introduce problems.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   714
    To use, mark the earliest changeset you know exhibits the problem
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   715
    as bad, then mark the latest changeset which is free from the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   716
    problem as good. Bisect will update your working directory to a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   717
    revision for testing (unless the --noupdate option is specified).
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   718
    Once you have performed tests, mark the working directory as bad
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   719
    or good and bisect will either update to another candidate changeset
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   720
    or announce that it has found the bad revision.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   721
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   722
    As a shortcut, you can also use the revision argument to mark a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   723
    revision as good or bad without checking it out first.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   724
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   725
    If you supply a command it will be used for automatic bisection. Its exit
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   726
    status will be used as flag to mark revision as bad or good. In case exit
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   727
    status is 0 the revision is marked as good, 125 - skipped, 127 (command not
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   728
    found) - bisection will be aborted; any other status bigger than 0 will
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   729
    mark revision as bad.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   730
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   731
options:
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   732
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   733
 -r --reset     reset bisect state
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   734
 -g --good      mark changeset good
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   735
 -b --bad       mark changeset bad
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   736
 -s --skip      skip testing changeset
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   737
 -c --command   use command to check changeset state
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   738
 -U --noupdate  do not update to target
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   739
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   740
use "hg -v help bisect" to show global options
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   741
</pre><p id="x_137"><a name="x_137"></a>The <span class="command"><strong>hg bisect</strong></span> command
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   742
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   743
		<span class="command"><strong>hg bisect --good</strong></span>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   744
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   745
		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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   746
		command.</p></li></ul></div></li><li><p id="x_13b"><a name="x_13b"></a>The command uses your information to decide
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   747
	    which changeset to test next.</p></li><li><p id="x_13c"><a name="x_13c"></a>It updates the working directory to that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   748
	    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   749
	  bisect</strong></span> identifies a unique changeset that marks
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   750
	the point where your test transitioned from
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   751
	“<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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   752
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   753
</pre><p id="x_13f"><a name="x_13f"></a>In our case, the binary test we use is simple: we check to
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   754
	see if any file in the repository contains the string “<span class="quote">i
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   755
	  have a gub</span>”.  If it does, this changeset contains the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   756
	change that “<span class="quote">caused the bug</span>”.  By convention, a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   757
	changeset that has the property we're searching for is
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   758
	“<span class="quote">bad</span>”, while one that doesn't is
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   759
	“<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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   760
	directory is synced (usually the tip) already exhibits the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   761
	problem introduced by the buggy change, so we'll mark it as
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   762
	“<span class="quote">bad</span>”.</p><pre id="id396047" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg bisect --bad</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   763
</pre><p id="x_141"><a name="x_141"></a>Our next task is to nominate a changeset that we know
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   764
	<span class="emphasis"><em>doesn't</em></span> have the bug; the <span class="command"><strong>hg bisect</strong></span> command will
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   765
	“<span class="quote">bracket</span>” its search between the first pair of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   766
	good and bad changesets.  In our case, we know that revision
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   767
	10 didn't have the bug.  (I'll have more words about choosing
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   768
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   769
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   770
Testing changeset 22:b8789808fc48 (24 changesets remaining, ~4 tests)
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   771
0 files updated, 0 files merged, 12 files removed, 0 files unresolved
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   772
</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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   773
	    consider before it can identify the one that introduced
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   774
	    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   775
	    changeset to test, and told us which changeset it's
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   776
	    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   777
	<span class="command"><strong>grep</strong></span> command to see if our
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   778
	“<span class="quote">bad</span>” file is present in the working directory.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   779
	If it is, this revision is bad; if not, this revision is good.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   780
	
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   781
</p><pre id="id395911" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>if grep -q 'i have a gub' *</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   782
<code class="prompt">&gt;</code> <strong class="userinput"><code>then</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   783
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   784
<code class="prompt">&gt;</code> <strong class="userinput"><code>  result=bad</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   785
<code class="prompt">&gt;</code> <strong class="userinput"><code>else</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   786
<code class="prompt">&gt;</code> <strong class="userinput"><code>  result=good</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   787
<code class="prompt">&gt;</code> <strong class="userinput"><code>fi</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   788
<code class="prompt">$</code> <strong class="userinput"><code>echo this revision is $result</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   789
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   790
this revision is bad
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   791
<code class="prompt">$</code> <strong class="userinput"><code>hg bisect --$result</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   792
Testing changeset 16:e61fdddff53e (12 changesets remaining, ~3 tests)
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   793
0 files updated, 0 files merged, 6 files removed, 0 files unresolved
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   794
</pre><p>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   795
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   796
</p><p id="x_146"><a name="x_146"></a>This test looks like a perfect candidate for automation,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   797
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   798
<code class="prompt">&gt;</code> <strong class="userinput"><code>  if grep -q 'i have a gub' *</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   799
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   800
<code class="prompt">&gt;</code> <strong class="userinput"><code>  then</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   801
<code class="prompt">&gt;</code> <strong class="userinput"><code>    result=bad</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   802
<code class="prompt">&gt;</code> <strong class="userinput"><code>  else</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   803
<code class="prompt">&gt;</code> <strong class="userinput"><code>    result=good</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   804
<code class="prompt">&gt;</code> <strong class="userinput"><code>  fi</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   805
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   806
<code class="prompt">&gt;</code> <strong class="userinput"><code>  echo this revision is $result</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   807
<code class="prompt">&gt;</code> <strong class="userinput"><code>  hg bisect --$result</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   808
<code class="prompt">&gt;</code> <strong class="userinput"><code>}</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   809
</pre><p id="x_147"><a name="x_147"></a>We can now run an entire test step with a single command,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   810
	<code class="literal">mytest</code>.</p><pre id="id396403" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>mytest</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   811
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   812
this revision is good
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   813
Testing changeset 19:706df39b003b (6 changesets remaining, ~2 tests)
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   814
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   815
</pre><p id="x_148"><a name="x_148"></a>A few more invocations of our canned test step command,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   816
	and we're done.</p><pre id="id396344" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>mytest</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   817
this revision is good
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   818
Testing changeset 20:bf7ea9a054e6 (3 changesets remaining, ~1 tests)
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   819
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   820
<code class="prompt">$</code> <strong class="userinput"><code>mytest</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   821
this revision is good
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   822
Testing changeset 21:921391dd45c1 (2 changesets remaining, ~1 tests)
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   823
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   824
<code class="prompt">$</code> <strong class="userinput"><code>mytest</code></strong>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   825
this revision is good
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   826
The first bad revision is:
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   827
changeset:   22:b8789808fc48
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   828
user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   829
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   830
date:        Tue May 05 06:55:14 2009 +0000
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   831
summary:     buggy changeset
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   832
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   833
</pre><p id="x_149"><a name="x_149"></a>Even though we had 40 changesets to search through, the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   834
	<span class="command"><strong>hg bisect</strong></span> command let us find
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   835
	the changeset that introduced our “<span class="quote">bug</span>” with only
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   836
	five tests.  Because the number of tests that the <span class="command"><strong>hg bisect</strong></span> command performs grows
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   837
	logarithmically with the number of changesets to search, the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   838
	advantage that it has over the “<span class="quote">brute force</span>”
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   839
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   840
	  bisect</strong></span> command in a repository, you can use the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   841
	<span class="command"><strong>hg bisect --reset</strong></span> command to
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   842
	drop the information it was using to drive your search.  The
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   843
	command doesn't use much space, so it doesn't matter if you
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   844
	forget to run this command.  However, <span class="command"><strong>hg bisect</strong></span> won't let you start a new
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   845
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   846
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   847
</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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   848
	requires that you correctly report the result of every test
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   849
	you perform.  If you tell it that a test failed when it really
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   850
	succeeded, it <span class="emphasis"><em>might</em></span> be able to detect the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   851
	inconsistency.  If it can identify an inconsistency in your
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   852
	reports, it will tell you that a particular changeset is both
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   853
	good and bad. However, it can't do this perfectly; it's about
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   854
	as likely to report the wrong changeset as the source of the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   855
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   856
	  bisect</strong></span> command, I tried a few times to run my
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   857
	tests by hand, on the command line.  This is an approach that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   858
	I, at least, am not suited to.  After a few tries, I found
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   859
	that I was making enough mistakes that I was having to restart
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   860
	my searches several times before finally getting correct
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   861
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   862
	even with simple searches on small repositories; if the
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   863
	problem you're looking for is more subtle, or the number of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   864
	tests that <span class="command"><strong>hg bisect</strong></span> must
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   865
	perform increases, the likelihood of operator error ruining
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   866
	the search is much higher.  Once I started automating my
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   867
	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>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   868
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   869
	command tests for the symptom, and the <code class="literal">if</code>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   870
	statement takes the result of this check and ensures that we
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   871
	always feed the same input to the <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   872
	  bisect</strong></span> command.  The <code class="literal">mytest</code>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   873
	function marries these together in a reproducible way, so that
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   874
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   875
	  bisect</strong></span> search is only as good as the input you
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   876
	give it, don't take the changeset it reports as the absolute
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   877
	truth.  A simple way to cross-check its report is to manually
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   878
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   879
	    revision.  Your test should still report this as
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   880
	    bad.</p></li><li><p id="x_154"><a name="x_154"></a>The parent of that changeset (either parent,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   881
	    if it's a merge). Your test should report this changeset
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   882
	    as good.</p></li><li><p id="x_155"><a name="x_155"></a>A child of that changeset.  Your test should
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   883
	    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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   884
	disrupted by the presence of another.  For example, let's say
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   885
	your software crashes at revision 100, and worked correctly at
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   886
	revision 50.  Unknown to you, someone else introduced a
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   887
	different crashing bug at revision 60, and fixed it at
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   888
	revision 80.  This could distort your results in one of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   889
	several ways.</p><p id="x_157"><a name="x_157"></a>It is possible that this other bug completely
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   890
	“<span class="quote">masks</span>” yours, which is to say that it occurs
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   891
	before your bug has a chance to manifest itself.  If you can't
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   892
	avoid that other bug (for example, it prevents your project
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   893
	from building), and so can't tell whether your bug is present
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   894
	in a particular changeset, the <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   895
	  bisect</strong></span> command cannot help you directly.  Instead,
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   896
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   897
	presence is not specific enough.  If you check for “<span class="quote">my
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   898
	  program crashes</span>”, then both your crashing bug and an
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   899
	unrelated crashing bug that masks it will look like the same
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   900
	thing, and mislead <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   901
	  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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   902
	test a revision because your project was in a broken and hence
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   903
	untestable state at that revision, perhaps because someone
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   904
	checked in a change that prevented the project from
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   905
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   906
	“<span class="quote">bad</span>” changesets that will mark the end points of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   907
	your search is often easy, but it bears a little discussion
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   908
	nevertheless.  From the perspective of <span class="command"><strong>hg bisect</strong></span>, the “<span class="quote">newest</span>”
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   909
	changeset is conventionally “<span class="quote">bad</span>”, and the older
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   910
	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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   911
	“<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
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   912
	testing changesets at random.  Just remember to eliminate
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   913
	contenders that can't possibly exhibit the bug (perhaps
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   914
	because the feature with the bug isn't present yet) and those
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   915
	where another problem masks the bug (as I discussed
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   916
	above).</p><p id="x_15c"><a name="x_15c"></a>Even if you end up “<span class="quote">early</span>” by thousands of
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   917
	changesets or months of history, you will only add a handful
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   918
	of tests to the total number that <span class="command"><strong>hg
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   919
	  bisect</strong></span> must perform, thanks to its logarithmic
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   920
	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.
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   921
      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">
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   922
    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   923
    document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   924
    </script><script type="text/javascript">
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   925
    try {
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   926
    var pageTracker = _gat._getTracker("UA-1805907-5");
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   927
    pageTracker._trackPageview();
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   928
    } catch(err) {}</script></body></html>
8083d21c0020 The first commit of all the required files for the review app
amit@thunder
parents:
diff changeset
   929