hgbook
diff fr/ch09-undo.xml @ 996:6f8c48362758
merge with trunk
author | Romain PELISSE <belaran@gmail.com> |
---|---|
date | Sat Sep 12 17:58:56 2009 +0200 (2009-09-12) |
parents | 6b680d569bb4 f0110009e946 |
children |
line diff
1.1 --- a/fr/ch09-undo.xml Sun Aug 16 04:58:01 2009 +0200 1.2 +++ b/fr/ch09-undo.xml Sat Sep 12 17:58:56 2009 +0200 1.3 @@ -1,963 +1,1201 @@ 1.4 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 1.5 1.6 -<chapter> 1.7 -<title>Finding and fixing your mistakes</title> 1.8 -<para>\label{chap:undo}</para> 1.9 - 1.10 -<para>To err might be human, but to really handle the consequences well 1.11 -takes a top-notch revision control system. In this chapter, we'll 1.12 -discuss some of the techniques you can use when you find that a 1.13 -problem has crept into your project. Mercurial has some highly 1.14 -capable features that will help you to isolate the sources of 1.15 -problems, and to handle them appropriately.</para> 1.16 - 1.17 -<sect1> 1.18 -<title>Erasing local history</title> 1.19 - 1.20 -<sect2> 1.21 -<title>The accidental commit</title> 1.22 - 1.23 -<para>I have the occasional but persistent problem of typing rather more 1.24 -quickly than I can think, which sometimes results in me committing a 1.25 -changeset that is either incomplete or plain wrong. In my case, the 1.26 -usual kind of incomplete changeset is one in which I've created a new 1.27 -source file, but forgotten to <command role="hg-cmd">hg add</command> it. A <quote>plain wrong</quote> 1.28 -changeset is not as common, but no less annoying.</para> 1.29 - 1.30 -</sect2> 1.31 -<sect2> 1.32 -<title>Rolling back a transaction</title> 1.33 -<para>\label{sec:undo:rollback}</para> 1.34 - 1.35 -<para>In section <xref linkend="sec:concepts:txn"/>, I mentioned that Mercurial treats 1.36 -each modification of a repository as a <emphasis>transaction</emphasis>. Every time 1.37 -you commit a changeset or pull changes from another repository, 1.38 -Mercurial remembers what you did. You can undo, or <emphasis>roll back</emphasis>, 1.39 -exactly one of these actions using the <command role="hg-cmd">hg rollback</command> command. (See 1.40 -section <xref linkend="sec:undo:rollback-after-push"/> for an important caveat 1.41 -about the use of this command.)</para> 1.42 - 1.43 -<para>Here's a mistake that I often find myself making: committing a change 1.44 -in which I've created a new file, but forgotten to <command role="hg-cmd">hg add</command> it. 1.45 -<!-- &interaction.rollback.commit; --> 1.46 -Looking at the output of <command role="hg-cmd">hg status</command> after the commit immediately 1.47 -confirms the error. 1.48 -<!-- &interaction.rollback.status; --> 1.49 -The commit captured the changes to the file <filename>a</filename>, but not the 1.50 -new file <filename>b</filename>. If I were to push this changeset to a 1.51 -repository that I shared with a colleague, the chances are high that 1.52 -something in <filename>a</filename> would refer to <filename>b</filename>, which would not 1.53 -be present in their repository when they pulled my changes. I would 1.54 -thus become the object of some indignation.</para> 1.55 - 1.56 -<para>However, luck is with me&emdash;I've caught my error before I pushed the 1.57 -changeset. I use the <command role="hg-cmd">hg rollback</command> command, and Mercurial makes 1.58 -that last changeset vanish. 1.59 -<!-- &interaction.rollback.rollback; --> 1.60 -Notice that the changeset is no longer present in the repository's 1.61 -history, and the working directory once again thinks that the file 1.62 -<filename>a</filename> is modified. The commit and rollback have left the 1.63 -working directory exactly as it was prior to the commit; the changeset 1.64 -has been completely erased. I can now safely <command role="hg-cmd">hg add</command> the file 1.65 -<filename>b</filename>, and rerun my commit. 1.66 -<!-- &interaction.rollback.add; --></para> 1.67 - 1.68 -</sect2> 1.69 -<sect2> 1.70 -<title>The erroneous pull</title> 1.71 - 1.72 -<para>It's common practice with Mercurial to maintain separate development 1.73 -branches of a project in different repositories. Your development 1.74 -team might have one shared repository for your project's <quote>0.9</quote> 1.75 -release, and another, containing different changes, for the <quote>1.0</quote> 1.76 -release.</para> 1.77 - 1.78 -<para>Given this, you can imagine that the consequences could be messy if 1.79 -you had a local <quote>0.9</quote> repository, and accidentally pulled changes 1.80 -from the shared <quote>1.0</quote> repository into it. At worst, you could be 1.81 -paying insufficient attention, and push those changes into the shared 1.82 -<quote>0.9</quote> tree, confusing your entire team (but don't worry, we'll 1.83 -return to this horror scenario later). However, it's more likely that 1.84 -you'll notice immediately, because Mercurial will display the URL it's 1.85 -pulling from, or you will see it pull a suspiciously large number of 1.86 -changes into the repository. 1.87 -</para> 1.88 - 1.89 -<para>The <command role="hg-cmd">hg rollback</command> command will work nicely to expunge all of the 1.90 -changesets that you just pulled. Mercurial groups all changes from 1.91 -one <command role="hg-cmd">hg pull</command> into a single transaction, so one <command role="hg-cmd">hg rollback</command> is 1.92 -all you need to undo this mistake. 1.93 -</para> 1.94 - 1.95 -</sect2> 1.96 -<sect2> 1.97 -<title>Rolling back is useless once you've pushed</title> 1.98 -<para>\label{sec:undo:rollback-after-push} 1.99 -</para> 1.100 - 1.101 -<para>The value of the <command role="hg-cmd">hg rollback</command> command drops to zero once you've 1.102 -pushed your changes to another repository. Rolling back a change 1.103 -makes it disappear entirely, but <emphasis>only</emphasis> in the repository in 1.104 -which you perform the <command role="hg-cmd">hg rollback</command>. Because a rollback eliminates 1.105 -history, there's no way for the disappearance of a change to propagate 1.106 -between repositories. 1.107 -</para> 1.108 - 1.109 -<para>If you've pushed a change to another repository&emdash;particularly if it's 1.110 -a shared repository&emdash;it has essentially <quote>escaped into the wild,</quote> 1.111 -and you'll have to recover from your mistake in a different way. What 1.112 -will happen if you push a changeset somewhere, then roll it back, then 1.113 -pull from the repository you pushed to, is that the changeset will 1.114 -reappear in your repository. 1.115 -</para> 1.116 - 1.117 -<para>(If you absolutely know for sure that the change you want to roll back 1.118 -is the most recent change in the repository that you pushed to, 1.119 -<emphasis>and</emphasis> you know that nobody else could have pulled it from that 1.120 -repository, you can roll back the changeset there, too, but you really 1.121 -should really not rely on this working reliably. If you do this, 1.122 -sooner or later a change really will make it into a repository that 1.123 -you don't directly control (or have forgotten about), and come back to 1.124 -bite you.) 1.125 -</para> 1.126 - 1.127 -</sect2> 1.128 -<sect2> 1.129 -<title>You can only roll back once</title> 1.130 - 1.131 -<para>Mercurial stores exactly one transaction in its transaction log; that 1.132 -transaction is the most recent one that occurred in the repository. 1.133 -This means that you can only roll back one transaction. If you expect 1.134 -to be able to roll back one transaction, then its predecessor, this is 1.135 -not the behaviour you will get. 1.136 -<!-- &interaction.rollback.twice; --> 1.137 -Once you've rolled back one transaction in a repository, you can't 1.138 -roll back again in that repository until you perform another commit or 1.139 -pull. 1.140 -</para> 1.141 - 1.142 -</sect2> 1.143 -</sect1> 1.144 -<sect1> 1.145 -<title>Reverting the mistaken change</title> 1.146 - 1.147 -<para>If you make a modification to a file, and decide that you really 1.148 -didn't want to change the file at all, and you haven't yet committed 1.149 -your changes, the <command role="hg-cmd">hg revert</command> command is the one you'll need. It 1.150 -looks at the changeset that's the parent of the working directory, and 1.151 -restores the contents of the file to their state as of that changeset. 1.152 -(That's a long-winded way of saying that, in the normal case, it 1.153 -undoes your modifications.) 1.154 -</para> 1.155 - 1.156 -<para>Let's illustrate how the <command role="hg-cmd">hg revert</command> command works with yet another 1.157 -small example. We'll begin by modifying a file that Mercurial is 1.158 -already tracking. 1.159 -<!-- &interaction.daily.revert.modify; --> 1.160 -If we don't want that change, we can simply <command role="hg-cmd">hg revert</command> the file. 1.161 -<!-- &interaction.daily.revert.unmodify; --> 1.162 -The <command role="hg-cmd">hg revert</command> command provides us with an extra degree of safety 1.163 -by saving our modified file with a <filename>.orig</filename> extension. 1.164 -<!-- &interaction.daily.revert.status; --> 1.165 -</para> 1.166 - 1.167 -<para>Here is a summary of the cases that the <command role="hg-cmd">hg revert</command> command can 1.168 -deal with. We will describe each of these in more detail in the 1.169 -section that follows. 1.170 -</para> 1.171 -<itemizedlist> 1.172 -<listitem><para>If you modify a file, it will restore the file to its unmodified 1.173 - state. 1.174 -</para> 1.175 -</listitem> 1.176 -<listitem><para>If you <command role="hg-cmd">hg add</command> a file, it will undo the <quote>added</quote> state of 1.177 - the file, but leave the file itself untouched. 1.178 -</para> 1.179 -</listitem> 1.180 -<listitem><para>If you delete a file without telling Mercurial, it will restore 1.181 - the file to its unmodified contents. 1.182 -</para> 1.183 -</listitem> 1.184 -<listitem><para>If you use the <command role="hg-cmd">hg remove</command> command to remove a file, it will 1.185 - undo the <quote>removed</quote> state of the file, and restore the file to its 1.186 - unmodified contents. 1.187 -</para> 1.188 -</listitem></itemizedlist> 1.189 - 1.190 -<sect2> 1.191 -<title>File management errors</title> 1.192 -<para>\label{sec:undo:mgmt} 1.193 -</para> 1.194 - 1.195 -<para>The <command role="hg-cmd">hg revert</command> command is useful for more than just modified 1.196 -files. It lets you reverse the results of all of Mercurial's file 1.197 -management commands&emdash;<command role="hg-cmd">hg add</command>, <command role="hg-cmd">hg remove</command>, and so on. 1.198 -</para> 1.199 - 1.200 -<para>If you <command role="hg-cmd">hg add</command> a file, then decide that in fact you don't want 1.201 -Mercurial to track it, use <command role="hg-cmd">hg revert</command> to undo the add. Don't 1.202 -worry; Mercurial will not modify the file in any way. It will just 1.203 -<quote>unmark</quote> the file. 1.204 -<!-- &interaction.daily.revert.add; --> 1.205 -</para> 1.206 - 1.207 -<para>Similarly, if you ask Mercurial to <command role="hg-cmd">hg remove</command> a file, you can use 1.208 -<command role="hg-cmd">hg revert</command> to restore it to the contents it had as of the parent 1.209 -of the working directory. 1.210 -<!-- &interaction.daily.revert.remove; --> 1.211 -This works just as well for a file that you deleted by hand, without 1.212 -telling Mercurial (recall that in Mercurial terminology, this kind of 1.213 -file is called <quote>missing</quote>). 1.214 -<!-- &interaction.daily.revert.missing; --> 1.215 -</para> 1.216 - 1.217 -<para>If you revert a <command role="hg-cmd">hg copy</command>, the copied-to file remains in your 1.218 -working directory afterwards, untracked. Since a copy doesn't affect 1.219 -the copied-from file in any way, Mercurial doesn't do anything with 1.220 -the copied-from file. 1.221 -<!-- &interaction.daily.revert.copy; --> 1.222 -</para> 1.223 - 1.224 -<sect3> 1.225 -<title>A slightly special case: reverting a rename</title> 1.226 - 1.227 -<para>If you <command role="hg-cmd">hg rename</command> a file, there is one small detail that 1.228 -you should remember. When you <command role="hg-cmd">hg revert</command> a rename, it's not 1.229 -enough to provide the name of the renamed-to file, as you can see 1.230 -here. 1.231 -<!-- &interaction.daily.revert.rename; --> 1.232 -As you can see from the output of <command role="hg-cmd">hg status</command>, the renamed-to file 1.233 -is no longer identified as added, but the renamed-<emphasis>from</emphasis> file is 1.234 -still removed! This is counter-intuitive (at least to me), but at 1.235 -least it's easy to deal with. 1.236 -<!-- &interaction.daily.revert.rename-orig; --> 1.237 -So remember, to revert a <command role="hg-cmd">hg rename</command>, you must provide <emphasis>both</emphasis> 1.238 -the source and destination names. 1.239 -</para> 1.240 - 1.241 -<para>% TODO: the output doesn't look like it will be removed! 1.242 -</para> 1.243 - 1.244 -<para>(By the way, if you rename a file, then modify the renamed-to file, 1.245 -then revert both components of the rename, when Mercurial restores the 1.246 -file that was removed as part of the rename, it will be unmodified. 1.247 -If you need the modifications in the renamed-to file to show up in the 1.248 -renamed-from file, don't forget to copy them over.) 1.249 -</para> 1.250 - 1.251 -<para>These fiddly aspects of reverting a rename arguably constitute a small 1.252 -bug in Mercurial. 1.253 -</para> 1.254 - 1.255 -</sect3> 1.256 -</sect2> 1.257 -</sect1> 1.258 -<sect1> 1.259 -<title>Dealing with committed changes</title> 1.260 - 1.261 -<para>Consider a case where you have committed a change $a$, and another 1.262 -change $b$ on top of it; you then realise that change $a$ was 1.263 -incorrect. Mercurial lets you <quote>back out</quote> an entire changeset 1.264 -automatically, and building blocks that let you reverse part of a 1.265 -changeset by hand. 1.266 -</para> 1.267 - 1.268 -<para>Before you read this section, here's something to keep in mind: the 1.269 -<command role="hg-cmd">hg backout</command> command undoes changes by <emphasis>adding</emphasis> history, not 1.270 -by modifying or erasing it. It's the right tool to use if you're 1.271 -fixing bugs, but not if you're trying to undo some change that has 1.272 -catastrophic consequences. To deal with those, see 1.273 -section <xref linkend="sec:undo:aaaiiieee"/>. 1.274 -</para> 1.275 - 1.276 -<sect2> 1.277 -<title>Backing out a changeset</title> 1.278 - 1.279 -<para>The <command role="hg-cmd">hg backout</command> command lets you <quote>undo</quote> the effects of an entire 1.280 -changeset in an automated fashion. Because Mercurial's history is 1.281 -immutable, this command <emphasis>does not</emphasis> get rid of the changeset you 1.282 -want to undo. Instead, it creates a new changeset that 1.283 -<emphasis>reverses</emphasis> the effect of the to-be-undone changeset. 1.284 -</para> 1.285 - 1.286 -<para>The operation of the <command role="hg-cmd">hg backout</command> command is a little intricate, so 1.287 -let's illustrate it with some examples. First, we'll create a 1.288 -repository with some simple changes. 1.289 -<!-- &interaction.backout.init; --> 1.290 -</para> 1.291 - 1.292 -<para>The <command role="hg-cmd">hg backout</command> command takes a single changeset ID as its 1.293 -argument; this is the changeset to back out. Normally, 1.294 -<command role="hg-cmd">hg backout</command> will drop you into a text editor to write a commit 1.295 -message, so you can record why you're backing the change out. In this 1.296 -example, we provide a commit message on the command line using the 1.297 -<option role="hg-opt-backout">-m</option> option. 1.298 -</para> 1.299 - 1.300 -</sect2> 1.301 -<sect2> 1.302 -<title>Backing out the tip changeset</title> 1.303 - 1.304 -<para>We're going to start by backing out the last changeset we committed. 1.305 -<!-- &interaction.backout.simple; --> 1.306 -You can see that the second line from <filename>myfile</filename> is no longer 1.307 -present. Taking a look at the output of <command role="hg-cmd">hg log</command> gives us an idea 1.308 -of what the <command role="hg-cmd">hg backout</command> command has done. 1.309 -<!-- &interaction.backout.simple.log; --> 1.310 -Notice that the new changeset that <command role="hg-cmd">hg backout</command> has created is a 1.311 -child of the changeset we backed out. It's easier to see this in 1.312 -figure <xref linkend="fig:undo:backout"/>, which presents a graphical view of the 1.313 -change history. As you can see, the history is nice and linear. 1.314 -</para> 1.315 - 1.316 -<informalfigure> 1.317 - 1.318 -<para> <mediaobject><imageobject><imagedata fileref="undo-simple"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject> 1.319 - <caption><para>Backing out a change using the <command role="hg-cmd">hg backout</command> command</para></caption> 1.320 - \label{fig:undo:backout} 1.321 -</para> 1.322 -</informalfigure> 1.323 - 1.324 -</sect2> 1.325 -<sect2> 1.326 -<title>Backing out a non-tip change</title> 1.327 - 1.328 -<para>If you want to back out a change other than the last one you 1.329 -committed, pass the <option role="hg-opt-backout">--merge</option> option to the 1.330 -<command role="hg-cmd">hg backout</command> command. 1.331 -<!-- &interaction.backout.non-tip.clone; --> 1.332 -This makes backing out any changeset a <quote>one-shot</quote> operation that's 1.333 -usually simple and fast. 1.334 -<!-- &interaction.backout.non-tip.backout; --> 1.335 -</para> 1.336 - 1.337 -<para>If you take a look at the contents of <filename>myfile</filename> after the 1.338 -backout finishes, you'll see that the first and third changes are 1.339 -present, but not the second. 1.340 -<!-- &interaction.backout.non-tip.cat; --> 1.341 -</para> 1.342 - 1.343 -<para>As the graphical history in figure <xref linkend="fig:undo:backout-non-tip"/> 1.344 -illustrates, Mercurial actually commits <emphasis>two</emphasis> changes in this 1.345 -kind of situation (the box-shaped nodes are the ones that Mercurial 1.346 -commits automatically). Before Mercurial begins the backout process, 1.347 -it first remembers what the current parent of the working directory 1.348 -is. It then backs out the target changeset, and commits that as a 1.349 -changeset. Finally, it merges back to the previous parent of the 1.350 -working directory, and commits the result of the merge. 1.351 -</para> 1.352 - 1.353 -<para>% TODO: to me it looks like mercurial doesn't commit the second merge automatically! 1.354 -</para> 1.355 - 1.356 -<informalfigure> 1.357 - 1.358 -<para> <mediaobject><imageobject><imagedata fileref="undo-non-tip"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject> 1.359 - <caption><para>Automated backout of a non-tip change using the <command role="hg-cmd">hg backout</command> command</para></caption> 1.360 - \label{fig:undo:backout-non-tip} 1.361 -</para> 1.362 -</informalfigure> 1.363 - 1.364 -<para>The result is that you end up <quote>back where you were</quote>, only with some 1.365 -extra history that undoes the effect of the changeset you wanted to 1.366 -back out. 1.367 -</para> 1.368 - 1.369 -<sect3> 1.370 -<title>Always use the <option role="hg-opt-backout">--merge</option> option</title> 1.371 - 1.372 -<para>In fact, since the <option role="hg-opt-backout">--merge</option> option will do the <quote>right 1.373 -thing</quote> whether or not the changeset you're backing out is the tip 1.374 -(i.e. it won't try to merge if it's backing out the tip, since there's 1.375 -no need), you should <emphasis>always</emphasis> use this option when you run the 1.376 -<command role="hg-cmd">hg backout</command> command. 1.377 -</para> 1.378 - 1.379 -</sect3> 1.380 -</sect2> 1.381 -<sect2> 1.382 -<title>Gaining more control of the backout process</title> 1.383 - 1.384 -<para>While I've recommended that you always use the 1.385 -<option role="hg-opt-backout">--merge</option> option when backing out a change, the 1.386 -<command role="hg-cmd">hg backout</command> command lets you decide how to merge a backout 1.387 -changeset. Taking control of the backout process by hand is something 1.388 -you will rarely need to do, but it can be useful to understand what 1.389 -the <command role="hg-cmd">hg backout</command> command is doing for you automatically. To 1.390 -illustrate this, let's clone our first repository, but omit the 1.391 -backout change that it contains. 1.392 -</para> 1.393 - 1.394 -<para><!-- &interaction.backout.manual.clone; --> 1.395 -As with our earlier example, We'll commit a third changeset, then back 1.396 -out its parent, and see what happens. 1.397 -<!-- &interaction.backout.manual.backout; --> 1.398 -Our new changeset is again a descendant of the changeset we backout 1.399 -out; it's thus a new head, <emphasis>not</emphasis> a descendant of the changeset 1.400 -that was the tip. The <command role="hg-cmd">hg backout</command> command was quite explicit in 1.401 -telling us this. 1.402 -<!-- &interaction.backout.manual.log; --> 1.403 -</para> 1.404 - 1.405 -<para>Again, it's easier to see what has happened by looking at a graph of 1.406 -the revision history, in figure <xref linkend="fig:undo:backout-manual"/>. This 1.407 -makes it clear that when we use <command role="hg-cmd">hg backout</command> to back out a change 1.408 -other than the tip, Mercurial adds a new head to the repository (the 1.409 -change it committed is box-shaped). 1.410 -</para> 1.411 - 1.412 -<informalfigure> 1.413 - 1.414 -<para> <mediaobject><imageobject><imagedata fileref="undo-manual"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject> 1.415 - <caption><para>Backing out a change using the <command role="hg-cmd">hg backout</command> command</para></caption> 1.416 - \label{fig:undo:backout-manual} 1.417 -</para> 1.418 -</informalfigure> 1.419 - 1.420 -<para>After the <command role="hg-cmd">hg backout</command> command has completed, it leaves the new 1.421 -<quote>backout</quote> changeset as the parent of the working directory. 1.422 -<!-- &interaction.backout.manual.parents; --> 1.423 -Now we have two isolated sets of changes. 1.424 -<!-- &interaction.backout.manual.heads; --> 1.425 -</para> 1.426 - 1.427 -<para>Let's think about what we expect to see as the contents of 1.428 -<filename>myfile</filename> now. The first change should be present, because 1.429 -we've never backed it out. The second change should be missing, as 1.430 -that's the change we backed out. Since the history graph shows the 1.431 -third change as a separate head, we <emphasis>don't</emphasis> expect to see the 1.432 -third change present in <filename>myfile</filename>. 1.433 -<!-- &interaction.backout.manual.cat; --> 1.434 -To get the third change back into the file, we just do a normal merge 1.435 -of our two heads. 1.436 -<!-- &interaction.backout.manual.merge; --> 1.437 -Afterwards, the graphical history of our repository looks like 1.438 -figure <xref linkend="fig:undo:backout-manual-merge"/>. 1.439 -</para> 1.440 - 1.441 -<informalfigure> 1.442 - 1.443 -<para> <mediaobject><imageobject><imagedata fileref="undo-manual-merge"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject> 1.444 - <caption><para>Manually merging a backout change</para></caption> 1.445 - \label{fig:undo:backout-manual-merge} 1.446 -</para> 1.447 -</informalfigure> 1.448 - 1.449 -</sect2> 1.450 -<sect2> 1.451 -<title>Why <command role="hg-cmd">hg backout</command> works as it does</title> 1.452 - 1.453 -<para>Here's a brief description of how the <command role="hg-cmd">hg backout</command> command works. 1.454 -</para> 1.455 -<orderedlist> 1.456 -<listitem><para>It ensures that the working directory is <quote>clean</quote>, i.e. that 1.457 - the output of <command role="hg-cmd">hg status</command> would be empty. 1.458 -</para> 1.459 -</listitem> 1.460 -<listitem><para>It remembers the current parent of the working directory. Let's 1.461 - call this changeset <literal>orig</literal> 1.462 -</para> 1.463 -</listitem> 1.464 -<listitem><para>It does the equivalent of a <command role="hg-cmd">hg update</command> to sync the working 1.465 - directory to the changeset you want to back out. Let's call this 1.466 - changeset <literal>backout</literal> 1.467 -</para> 1.468 -</listitem> 1.469 -<listitem><para>It finds the parent of that changeset. Let's call that 1.470 - changeset <literal>parent</literal>. 1.471 -</para> 1.472 -</listitem> 1.473 -<listitem><para>For each file that the <literal>backout</literal> changeset affected, it 1.474 - does the equivalent of a <command role="hg-cmd">hg revert -r parent</command> on that file, 1.475 - to restore it to the contents it had before that changeset was 1.476 - committed. 1.477 -</para> 1.478 -</listitem> 1.479 -<listitem><para>It commits the result as a new changeset. This changeset has 1.480 - <literal>backout</literal> as its parent. 1.481 -</para> 1.482 -</listitem> 1.483 -<listitem><para>If you specify <option role="hg-opt-backout">--merge</option> on the command line, it 1.484 - merges with <literal>orig</literal>, and commits the result of the merge. 1.485 -</para> 1.486 -</listitem></orderedlist> 1.487 - 1.488 -<para>An alternative way to implement the <command role="hg-cmd">hg backout</command> command would be 1.489 -to <command role="hg-cmd">hg export</command> the to-be-backed-out changeset as a diff, then use 1.490 -the <option role="cmd-opt-patch">--reverse</option> option to the <command>patch</command> command to 1.491 -reverse the effect of the change without fiddling with the working 1.492 -directory. This sounds much simpler, but it would not work nearly as 1.493 -well. 1.494 -</para> 1.495 - 1.496 -<para>The reason that <command role="hg-cmd">hg backout</command> does an update, a commit, a merge, and 1.497 -another commit is to give the merge machinery the best chance to do a 1.498 -good job when dealing with all the changes <emphasis>between</emphasis> the change 1.499 -you're backing out and the current tip. 1.500 -</para> 1.501 - 1.502 -<para>If you're backing out a changeset that's 100 revisions back in your 1.503 -project's history, the chances that the <command>patch</command> command will 1.504 -be able to apply a reverse diff cleanly are not good, because 1.505 -intervening changes are likely to have <quote>broken the context</quote> that 1.506 -<command>patch</command> uses to determine whether it can apply a patch (if 1.507 -this sounds like gibberish, see <xref linkend="sec:mq:patch"/> for a 1.508 -discussion of the <command>patch</command> command). Also, Mercurial's merge 1.509 -machinery will handle files and directories being renamed, permission 1.510 -changes, and modifications to binary files, none of which 1.511 -<command>patch</command> can deal with. 1.512 -</para> 1.513 - 1.514 -</sect2> 1.515 -</sect1> 1.516 -<sect1> 1.517 -<title>Changes that should never have been</title> 1.518 -<para>\label{sec:undo:aaaiiieee} 1.519 -</para> 1.520 - 1.521 -<para>Most of the time, the <command role="hg-cmd">hg backout</command> command is exactly what you need 1.522 -if you want to undo the effects of a change. It leaves a permanent 1.523 -record of exactly what you did, both when committing the original 1.524 -changeset and when you cleaned up after it. 1.525 -</para> 1.526 - 1.527 -<para>On rare occasions, though, you may find that you've committed a change 1.528 -that really should not be present in the repository at all. For 1.529 -example, it would be very unusual, and usually considered a mistake, 1.530 -to commit a software project's object files as well as its source 1.531 -files. Object files have almost no intrinsic value, and they're 1.532 -<emphasis>big</emphasis>, so they increase the size of the repository and the amount 1.533 -of time it takes to clone or pull changes. 1.534 -</para> 1.535 - 1.536 -<para>Before I discuss the options that you have if you commit a <quote>brown 1.537 -paper bag</quote> change (the kind that's so bad that you want to pull a 1.538 -brown paper bag over your head), let me first discuss some approaches 1.539 -that probably won't work. 1.540 -</para> 1.541 - 1.542 -<para>Since Mercurial treats history as accumulative&emdash;every change builds 1.543 -on top of all changes that preceded it&emdash;you generally can't just make 1.544 -disastrous changes disappear. The one exception is when you've just 1.545 -committed a change, and it hasn't been pushed or pulled into another 1.546 -repository. That's when you can safely use the <command role="hg-cmd">hg rollback</command> 1.547 -command, as I detailed in section <xref linkend="sec:undo:rollback"/>. 1.548 -</para> 1.549 - 1.550 -<para>After you've pushed a bad change to another repository, you 1.551 -<emphasis>could</emphasis> still use <command role="hg-cmd">hg rollback</command> to make your local copy of the 1.552 -change disappear, but it won't have the consequences you want. The 1.553 -change will still be present in the remote repository, so it will 1.554 -reappear in your local repository the next time you pull. 1.555 -</para> 1.556 - 1.557 -<para>If a situation like this arises, and you know which repositories your 1.558 -bad change has propagated into, you can <emphasis>try</emphasis> to get rid of the 1.559 -changeefrom <emphasis>every</emphasis> one of those repositories. This is, of 1.560 -course, not a satisfactory solution: if you miss even a single 1.561 -repository while you're expunging, the change is still <quote>in the 1.562 -wild</quote>, and could propagate further. 1.563 -</para> 1.564 - 1.565 -<para>If you've committed one or more changes <emphasis>after</emphasis> the change that 1.566 -you'd like to see disappear, your options are further reduced. 1.567 -Mercurial doesn't provide a way to <quote>punch a hole</quote> in history, 1.568 -leaving changesets intact. 1.569 -</para> 1.570 - 1.571 -<para>XXX This needs filling out. The <literal>hg-replay</literal> script in the 1.572 -<literal>examples</literal> directory works, but doesn't handle merge 1.573 -changesets. Kind of an important omission. 1.574 -</para> 1.575 - 1.576 -<sect2> 1.577 -<title>Protect yourself from <quote>escaped</quote> changes</title> 1.578 - 1.579 -<para>If you've committed some changes to your local repository and they've 1.580 -been pushed or pulled somewhere else, this isn't necessarily a 1.581 -disaster. You can protect yourself ahead of time against some classes 1.582 -of bad changeset. This is particularly easy if your team usually 1.583 -pulls changes from a central repository. 1.584 -</para> 1.585 - 1.586 -<para>By configuring some hooks on that repository to validate incoming 1.587 -changesets (see chapter <xref linkend="chap:hook"/>), you can automatically 1.588 -prevent some kinds of bad changeset from being pushed to the central 1.589 -repository at all. With such a configuration in place, some kinds of 1.590 -bad changeset will naturally tend to <quote>die out</quote> because they can't 1.591 -propagate into the central repository. Better yet, this happens 1.592 -without any need for explicit intervention. 1.593 -</para> 1.594 - 1.595 -<para>For instance, an incoming change hook that verifies that a changeset 1.596 -will actually compile can prevent people from inadvertantly <quote>breaking 1.597 -the build</quote>. 1.598 -</para> 1.599 - 1.600 -</sect2> 1.601 -</sect1> 1.602 -<sect1> 1.603 -<title>Finding the source of a bug</title> 1.604 -<para>\label{sec:undo:bisect} 1.605 -</para> 1.606 - 1.607 -<para>While it's all very well to be able to back out a changeset that 1.608 -introduced a bug, this requires that you know which changeset to back 1.609 -out. Mercurial provides an invaluable command, called 1.610 -<command role="hg-cmd">hg bisect</command>, that helps you to automate this process and accomplish 1.611 -it very efficiently. 1.612 -</para> 1.613 - 1.614 -<para>The idea behind the <command role="hg-cmd">hg bisect</command> command is that a changeset has 1.615 -introduced some change of behaviour that you can identify with a 1.616 -simple binary test. You don't know which piece of code introduced the 1.617 -change, but you know how to test for the presence of the bug. The 1.618 -<command role="hg-cmd">hg bisect</command> command uses your test to direct its search for the 1.619 -changeset that introduced the code that caused the bug. 1.620 -</para> 1.621 - 1.622 -<para>Here are a few scenarios to help you understand how you might apply 1.623 -this command. 1.624 -</para> 1.625 -<itemizedlist> 1.626 -<listitem><para>The most recent version of your software has a bug that you 1.627 - remember wasn't present a few weeks ago, but you don't know when it 1.628 - was introduced. Here, your binary test checks for the presence of 1.629 - that bug. 1.630 -</para> 1.631 -</listitem> 1.632 -<listitem><para>You fixed a bug in a rush, and now it's time to close the entry 1.633 - in your team's bug database. The bug database requires a changeset 1.634 - ID when you close an entry, but you don't remember which changeset 1.635 - you fixed the bug in. Once again, your binary test checks for the 1.636 - presence of the bug. 1.637 -</para> 1.638 -</listitem> 1.639 -<listitem><para>Your software works correctly, but runs 15% slower than the 1.640 - last time you measured it. You want to know which changeset 1.641 - introduced the performance regression. In this case, your binary 1.642 - test measures the performance of your software, to see whether it's 1.643 - <quote>fast</quote> or <quote>slow</quote>. 1.644 -</para> 1.645 -</listitem> 1.646 -<listitem><para>The sizes of the components of your project that you ship 1.647 - exploded recently, and you suspect that something changed in the way 1.648 - you build your project. 1.649 -</para> 1.650 -</listitem></itemizedlist> 1.651 - 1.652 -<para>From these examples, it should be clear that the <command role="hg-cmd">hg bisect</command> 1.653 -command is not useful only for finding the sources of bugs. You can 1.654 -use it to find any <quote>emergent property</quote> of a repository (anything 1.655 -that you can't find from a simple text search of the files in the 1.656 -tree) for which you can write a binary test. 1.657 -</para> 1.658 - 1.659 -<para>We'll introduce a little bit of terminology here, just to make it 1.660 -clear which parts of the search process are your responsibility, and 1.661 -which are Mercurial's. A <emphasis>test</emphasis> is something that <emphasis>you</emphasis> run 1.662 -when <command role="hg-cmd">hg bisect</command> chooses a changeset. A <emphasis>probe</emphasis> is what 1.663 -<command role="hg-cmd">hg bisect</command> runs to tell whether a revision is good. Finally, 1.664 -we'll use the word <quote>bisect</quote>, as both a noun and a verb, to stand in 1.665 -for the phrase <quote>search using the <command role="hg-cmd">hg bisect</command> command. 1.666 -</para> 1.667 - 1.668 -<para>One simple way to automate the searching process would be simply to 1.669 -probe every changeset. However, this scales poorly. If it took ten 1.670 -minutes to test a single changeset, and you had 10,000 changesets in 1.671 -your repository, the exhaustive approach would take on average 35 1.672 -<emphasis>days</emphasis> to find the changeset that introduced a bug. Even if you 1.673 -knew that the bug was introduced by one of the last 500 changesets, 1.674 -and limited your search to those, you'd still be looking at over 40 1.675 -hours to find the changeset that introduced your bug. 1.676 -</para> 1.677 - 1.678 -<para>What the <command role="hg-cmd">hg bisect</command> command does is use its knowledge of the 1.679 -<quote>shape</quote> of your project's revision history to perform a search in 1.680 -time proportional to the <emphasis>logarithm</emphasis> of the number of changesets 1.681 -to check (the kind of search it performs is called a dichotomic 1.682 -search). With this approach, searching through 10,000 changesets will 1.683 -take less than three hours, even at ten minutes per test (the search 1.684 -will require about 14 tests). Limit your search to the last hundred 1.685 -changesets, and it will take only about an hour (roughly seven tests). 1.686 -</para> 1.687 - 1.688 -<para>The <command role="hg-cmd">hg bisect</command> command is aware of the <quote>branchy</quote> nature of a 1.689 -Mercurial project's revision history, so it has no problems dealing 1.690 -with branches, merges, or multiple heads in a repository. It can 1.691 -prune entire branches of history with a single probe, which is how it 1.692 -operates so efficiently. 1.693 -</para> 1.694 - 1.695 -<sect2> 1.696 -<title>Using the <command role="hg-cmd">hg bisect</command> command</title> 1.697 - 1.698 -<para>Here's an example of <command role="hg-cmd">hg bisect</command> in action. 1.699 -</para> 1.700 - 1.701 -<note> 1.702 -<para> In versions 0.9.5 and earlier of Mercurial, <command role="hg-cmd">hg bisect</command> was not a 1.703 - core command: it was distributed with Mercurial as an extension. 1.704 - This section describes the built-in command, not the old extension. 1.705 -</para> 1.706 -</note> 1.707 - 1.708 -<para>Now let's create a repository, so that we can try out the 1.709 -<command role="hg-cmd">hg bisect</command> command in isolation. 1.710 -<!-- &interaction.bisect.init; --> 1.711 -We'll simulate a project that has a bug in it in a simple-minded way: 1.712 -create trivial changes in a loop, and nominate one specific change 1.713 -that will have the <quote>bug</quote>. This loop creates 35 changesets, each 1.714 -adding a single file to the repository. We'll represent our <quote>bug</quote> 1.715 -with a file that contains the text <quote>i have a gub</quote>. 1.716 -<!-- &interaction.bisect.commits; --> 1.717 -</para> 1.718 - 1.719 -<para>The next thing that we'd like to do is figure out how to use the 1.720 -<command role="hg-cmd">hg bisect</command> command. We can use Mercurial's normal built-in help 1.721 -mechanism for this. 1.722 -<!-- &interaction.bisect.help; --> 1.723 -</para> 1.724 - 1.725 -<para>The <command role="hg-cmd">hg bisect</command> command works in steps. Each step proceeds as follows. 1.726 -</para> 1.727 -<orderedlist> 1.728 -<listitem><para>You run your binary test. 1.729 -</para> 1.730 -</listitem><itemizedlist> 1.731 -<listitem><para> \item If the test succeeded, you tell <command role="hg-cmd">hg bisect</command> by running the 1.732 - <command role="hg-cmd">hg bisect good</command> command. 1.733 - \item If it failed, run the <command role="hg-cmd">hg bisect --bad</command> command. 1.734 -</para> 1.735 -</listitem></itemizedlist> 1.736 -<listitem><para>The command uses your information to decide which changeset to 1.737 - test next. 1.738 -</para> 1.739 -</listitem> 1.740 -<listitem><para>It updates the working directory to that changeset, and the 1.741 - process begins again. 1.742 -</para> 1.743 -</listitem></orderedlist> 1.744 -<para>The process ends when <command role="hg-cmd">hg bisect</command> identifies a unique changeset 1.745 -that marks the point where your test transitioned from <quote>succeeding</quote> 1.746 -to <quote>failing</quote>. 1.747 -</para> 1.748 - 1.749 -<para>To start the search, we must run the <command role="hg-cmd">hg bisect --reset</command> command. 1.750 -<!-- &interaction.bisect.search.init; --> 1.751 -</para> 1.752 - 1.753 -<para>In our case, the binary test we use is simple: we check to see if any 1.754 -file in the repository contains the string <quote>i have a gub</quote>. If it 1.755 -does, this changeset contains the change that <quote>caused the bug</quote>. By 1.756 -convention, a changeset that has the property we're searching for is 1.757 -<quote>bad</quote>, while one that doesn't is <quote>good</quote>. 1.758 -</para> 1.759 - 1.760 -<para>Most of the time, the revision to which the working directory is 1.761 -synced (usually the tip) already exhibits the problem introduced by 1.762 -the buggy change, so we'll mark it as <quote>bad</quote>. 1.763 -<!-- &interaction.bisect.search.bad-init; --> 1.764 -</para> 1.765 - 1.766 -<para>Our next task is to nominate a changeset that we know <emphasis>doesn't</emphasis> 1.767 -have the bug; the <command role="hg-cmd">hg bisect</command> command will <quote>bracket</quote> its search 1.768 -between the first pair of good and bad changesets. In our case, we 1.769 -know that revision 10 didn't have the bug. (I'll have more words 1.770 -about choosing the first <quote>good</quote> changeset later.) 1.771 -<!-- &interaction.bisect.search.good-init; --> 1.772 -</para> 1.773 - 1.774 -<para>Notice that this command printed some output. 1.775 -</para> 1.776 -<itemizedlist> 1.777 -<listitem><para>It told us how many changesets it must consider before it can 1.778 - identify the one that introduced the bug, and how many tests that 1.779 - will require. 1.780 -</para> 1.781 -</listitem> 1.782 -<listitem><para>It updated the working directory to the next changeset to test, 1.783 - and told us which changeset it's testing. 1.784 -</para> 1.785 -</listitem></itemizedlist> 1.786 - 1.787 -<para>We now run our test in the working directory. We use the 1.788 -<command>grep</command> command to see if our <quote>bad</quote> file is present in the 1.789 -working directory. If it is, this revision is bad; if not, this 1.790 -revision is good. 1.791 -<!-- &interaction.bisect.search.step1; --> 1.792 -</para> 1.793 - 1.794 -<para>This test looks like a perfect candidate for automation, so let's turn 1.795 -it into a shell function. 1.796 -<!-- &interaction.bisect.search.mytest; --> 1.797 -We can now run an entire test step with a single command, 1.798 -<literal>mytest</literal>. 1.799 -<!-- &interaction.bisect.search.step2; --> 1.800 -A few more invocations of our canned test step command, and we're 1.801 -done. 1.802 -<!-- &interaction.bisect.search.rest; --> 1.803 -</para> 1.804 - 1.805 -<para>Even though we had 40 changesets to search through, the <command role="hg-cmd">hg bisect</command> 1.806 -command let us find the changeset that introduced our <quote>bug</quote> with 1.807 -only five tests. Because the number of tests that the <command role="hg-cmd">hg bisect</command> 1.808 -command performs grows logarithmically with the number of changesets to 1.809 -search, the advantage that it has over the <quote>brute force</quote> search 1.810 -approach increases with every changeset you add. 1.811 -</para> 1.812 - 1.813 -</sect2> 1.814 -<sect2> 1.815 -<title>Cleaning up after your search</title> 1.816 - 1.817 -<para>When you're finished using the <command role="hg-cmd">hg bisect</command> command in a 1.818 -repository, you can use the <command role="hg-cmd">hg bisect reset</command> command to drop 1.819 -the information it was using to drive your search. The command 1.820 -doesn't use much space, so it doesn't matter if you forget to run this 1.821 -command. However, <command role="hg-cmd">hg bisect</command> won't let you start a new search in 1.822 -that repository until you do a <command role="hg-cmd">hg bisect reset</command>. 1.823 -<!-- &interaction.bisect.search.reset; --> 1.824 -</para> 1.825 - 1.826 -</sect2> 1.827 -</sect1> 1.828 -<sect1> 1.829 -<title>Tips for finding bugs effectively</title> 1.830 - 1.831 -<sect2> 1.832 -<title>Give consistent input</title> 1.833 - 1.834 -<para>The <command role="hg-cmd">hg bisect</command> command requires that you correctly report the 1.835 -result of every test you perform. If you tell it that a test failed 1.836 -when it really succeeded, it <emphasis>might</emphasis> be able to detect the 1.837 -inconsistency. If it can identify an inconsistency in your reports, 1.838 -it will tell you that a particular changeset is both good and bad. 1.839 -However, it can't do this perfectly; it's about as likely to report 1.840 -the wrong changeset as the source of the bug. 1.841 -</para> 1.842 - 1.843 -</sect2> 1.844 -<sect2> 1.845 -<title>Automate as much as possible</title> 1.846 - 1.847 -<para>When I started using the <command role="hg-cmd">hg bisect</command> command, I tried a few times 1.848 -to run my tests by hand, on the command line. This is an approach 1.849 -that I, at least, am not suited to. After a few tries, I found that I 1.850 -was making enough mistakes that I was having to restart my searches 1.851 -several times before finally getting correct results. 1.852 -</para> 1.853 - 1.854 -<para>My initial problems with driving the <command role="hg-cmd">hg bisect</command> command by hand 1.855 -occurred even with simple searches on small repositories; if the 1.856 -problem you're looking for is more subtle, or the number of tests that 1.857 -<command role="hg-cmd">hg bisect</command> must perform increases, the likelihood of operator 1.858 -error ruining the search is much higher. Once I started automating my 1.859 -tests, I had much better results. 1.860 -</para> 1.861 - 1.862 -<para>The key to automated testing is twofold: 1.863 -</para> 1.864 -<itemizedlist> 1.865 -<listitem><para>always test for the same symptom, and 1.866 -</para> 1.867 -</listitem> 1.868 -<listitem><para>always feed consistent input to the <command role="hg-cmd">hg bisect</command> command. 1.869 -</para> 1.870 -</listitem></itemizedlist> 1.871 -<para>In my tutorial example above, the <command>grep</command> command tests for the 1.872 -symptom, and the <literal>if</literal> statement takes the result of this check 1.873 -and ensures that we always feed the same input to the <command role="hg-cmd">hg bisect</command> 1.874 -command. The <literal>mytest</literal> function marries these together in a 1.875 -reproducible way, so that every test is uniform and consistent. 1.876 -</para> 1.877 - 1.878 -</sect2> 1.879 -<sect2> 1.880 -<title>Check your results</title> 1.881 - 1.882 -<para>Because the output of a <command role="hg-cmd">hg bisect</command> search is only as good as the 1.883 -input you give it, don't take the changeset it reports as the 1.884 -absolute truth. A simple way to cross-check its report is to manually 1.885 -run your test at each of the following changesets: 1.886 -</para> 1.887 -<itemizedlist> 1.888 -<listitem><para>The changeset that it reports as the first bad revision. Your 1.889 - test should still report this as bad. 1.890 -</para> 1.891 -</listitem> 1.892 -<listitem><para>The parent of that changeset (either parent, if it's a merge). 1.893 - Your test should report this changeset as good. 1.894 -</para> 1.895 -</listitem> 1.896 -<listitem><para>A child of that changeset. Your test should report this 1.897 - changeset as bad. 1.898 -</para> 1.899 -</listitem></itemizedlist> 1.900 - 1.901 -</sect2> 1.902 -<sect2> 1.903 -<title>Beware interference between bugs</title> 1.904 - 1.905 -<para>It's possible that your search for one bug could be disrupted by the 1.906 -presence of another. For example, let's say your software crashes at 1.907 -revision 100, and worked correctly at revision 50. Unknown to you, 1.908 -someone else introduced a different crashing bug at revision 60, and 1.909 -fixed it at revision 80. This could distort your results in one of 1.910 -several ways. 1.911 -</para> 1.912 - 1.913 -<para>It is possible that this other bug completely <quote>masks</quote> yours, which 1.914 -is to say that it occurs before your bug has a chance to manifest 1.915 -itself. If you can't avoid that other bug (for example, it prevents 1.916 -your project from building), and so can't tell whether your bug is 1.917 -present in a particular changeset, the <command role="hg-cmd">hg bisect</command> command cannot 1.918 -help you directly. Instead, you can mark a changeset as untested by 1.919 -running <command role="hg-cmd">hg bisect --skip</command>. 1.920 -</para> 1.921 - 1.922 -<para>A different problem could arise if your test for a bug's presence is 1.923 -not specific enough. If you check for <quote>my program crashes</quote>, then 1.924 -both your crashing bug and an unrelated crashing bug that masks it 1.925 -will look like the same thing, and mislead <command role="hg-cmd">hg bisect</command>. 1.926 -</para> 1.927 - 1.928 -<para>Another useful situation in which to use <command role="hg-cmd">hg bisect --skip</command> is 1.929 -if you can't test a revision because your project was in a broken and 1.930 -hence untestable state at that revision, perhaps because someone 1.931 -checked in a change that prevented the project from building. 1.932 -</para> 1.933 - 1.934 -</sect2> 1.935 -<sect2> 1.936 -<title>Bracket your search lazily</title> 1.937 - 1.938 -<para>Choosing the first <quote>good</quote> and <quote>bad</quote> changesets that will mark the 1.939 -end points of your search is often easy, but it bears a little 1.940 -discussion nevertheless. From the perspective of <command role="hg-cmd">hg bisect</command>, the 1.941 -<quote>newest</quote> changeset is conventionally <quote>bad</quote>, and the older 1.942 -changeset is <quote>good</quote>. 1.943 -</para> 1.944 - 1.945 -<para>If you're having trouble remembering when a suitable <quote>good</quote> change 1.946 -was, so that you can tell <command role="hg-cmd">hg bisect</command>, you could do worse than 1.947 -testing changesets at random. Just remember to eliminate contenders 1.948 -that can't possibly exhibit the bug (perhaps because the feature with 1.949 -the bug isn't present yet) and those where another problem masks the 1.950 -bug (as I discussed above). 1.951 -</para> 1.952 - 1.953 -<para>Even if you end up <quote>early</quote> by thousands of changesets or months of 1.954 -history, you will only add a handful of tests to the total number that 1.955 -<command role="hg-cmd">hg bisect</command> must perform, thanks to its logarithmic behaviour. 1.956 -</para> 1.957 - 1.958 -</sect2> 1.959 -</sect1> 1.960 +<chapter id="chap:undo"> 1.961 + <?dbhtml filename="finding-and-fixing-mistakes.html"?> 1.962 + <title>Finding and fixing mistakes</title> 1.963 + 1.964 + <para id="x_d2">To err might be human, but to really handle the consequences 1.965 + well takes a top-notch revision control system. In this chapter, 1.966 + we'll discuss some of the techniques you can use when you find 1.967 + that a problem has crept into your project. Mercurial has some 1.968 + highly capable features that will help you to isolate the sources 1.969 + of problems, and to handle them appropriately.</para> 1.970 + 1.971 + <sect1> 1.972 + <title>Erasing local history</title> 1.973 + 1.974 + <sect2> 1.975 + <title>The accidental commit</title> 1.976 + 1.977 + <para id="x_d3">I have the occasional but persistent problem of typing 1.978 + rather more quickly than I can think, which sometimes results 1.979 + in me committing a changeset that is either incomplete or 1.980 + plain wrong. In my case, the usual kind of incomplete 1.981 + changeset is one in which I've created a new source file, but 1.982 + forgotten to <command role="hg-cmd">hg add</command> it. A 1.983 + <quote>plain wrong</quote> changeset is not as common, but no 1.984 + less annoying.</para> 1.985 + 1.986 + </sect2> 1.987 + <sect2 id="sec:undo:rollback"> 1.988 + <title>Rolling back a transaction</title> 1.989 + 1.990 + <para id="x_d4">In <xref linkend="sec:concepts:txn"/>, I 1.991 + mentioned that Mercurial treats each modification of a 1.992 + repository as a <emphasis>transaction</emphasis>. Every time 1.993 + you commit a changeset or pull changes from another 1.994 + repository, Mercurial remembers what you did. You can undo, 1.995 + or <emphasis>roll back</emphasis>, exactly one of these 1.996 + actions using the <command role="hg-cmd">hg rollback</command> 1.997 + command. (See <xref linkend="sec:undo:rollback-after-push"/> 1.998 + for an important caveat about the use of this command.)</para> 1.999 + 1.1000 + <para id="x_d5">Here's a mistake that I often find myself making: 1.1001 + committing a change in which I've created a new file, but 1.1002 + forgotten to <command role="hg-cmd">hg add</command> 1.1003 + it.</para> 1.1004 + 1.1005 + &interaction.rollback.commit; 1.1006 + 1.1007 + <para id="x_d6">Looking at the output of <command role="hg-cmd">hg 1.1008 + status</command> after the commit immediately confirms the 1.1009 + error.</para> 1.1010 + 1.1011 + &interaction.rollback.status; 1.1012 + 1.1013 + <para id="x_d7">The commit captured the changes to the file 1.1014 + <filename>a</filename>, but not the new file 1.1015 + <filename>b</filename>. If I were to push this changeset to a 1.1016 + repository that I shared with a colleague, the chances are 1.1017 + high that something in <filename>a</filename> would refer to 1.1018 + <filename>b</filename>, which would not be present in their 1.1019 + repository when they pulled my changes. I would thus become 1.1020 + the object of some indignation.</para> 1.1021 + 1.1022 + <para id="x_d8">However, luck is with me&emdash;I've caught my error 1.1023 + before I pushed the changeset. I use the <command 1.1024 + role="hg-cmd">hg rollback</command> command, and Mercurial 1.1025 + makes that last changeset vanish.</para> 1.1026 + 1.1027 + &interaction.rollback.rollback; 1.1028 + 1.1029 + <para id="x_d9">Notice that the changeset is no longer present in the 1.1030 + repository's history, and the working directory once again 1.1031 + thinks that the file <filename>a</filename> is modified. The 1.1032 + commit and rollback have left the working directory exactly as 1.1033 + it was prior to the commit; the changeset has been completely 1.1034 + erased. I can now safely <command role="hg-cmd">hg 1.1035 + add</command> the file <filename>b</filename>, and rerun my 1.1036 + commit.</para> 1.1037 + 1.1038 + &interaction.rollback.add; 1.1039 + 1.1040 + </sect2> 1.1041 + <sect2> 1.1042 + <title>The erroneous pull</title> 1.1043 + 1.1044 + <para id="x_da">It's common practice with Mercurial to maintain separate 1.1045 + development branches of a project in different repositories. 1.1046 + Your development team might have one shared repository for 1.1047 + your project's <quote>0.9</quote> release, and another, 1.1048 + containing different changes, for the <quote>1.0</quote> 1.1049 + release.</para> 1.1050 + 1.1051 + <para id="x_db">Given this, you can imagine that the consequences could be 1.1052 + messy if you had a local <quote>0.9</quote> repository, and 1.1053 + accidentally pulled changes from the shared <quote>1.0</quote> 1.1054 + repository into it. At worst, you could be paying 1.1055 + insufficient attention, and push those changes into the shared 1.1056 + <quote>0.9</quote> tree, confusing your entire team (but don't 1.1057 + worry, we'll return to this horror scenario later). However, 1.1058 + it's more likely that you'll notice immediately, because 1.1059 + Mercurial will display the URL it's pulling from, or you will 1.1060 + see it pull a suspiciously large number of changes into the 1.1061 + repository.</para> 1.1062 + 1.1063 + <para id="x_dc">The <command role="hg-cmd">hg rollback</command> command 1.1064 + will work nicely to expunge all of the changesets that you 1.1065 + just pulled. Mercurial groups all changes from one <command 1.1066 + role="hg-cmd">hg pull</command> into a single transaction, 1.1067 + so one <command role="hg-cmd">hg rollback</command> is all you 1.1068 + need to undo this mistake.</para> 1.1069 + 1.1070 + </sect2> 1.1071 + <sect2 id="sec:undo:rollback-after-push"> 1.1072 + <title>Rolling back is useless once you've pushed</title> 1.1073 + 1.1074 + <para id="x_dd">The value of the <command role="hg-cmd">hg 1.1075 + rollback</command> command drops to zero once you've pushed 1.1076 + your changes to another repository. Rolling back a change 1.1077 + makes it disappear entirely, but <emphasis>only</emphasis> in 1.1078 + the repository in which you perform the <command 1.1079 + role="hg-cmd">hg rollback</command>. Because a rollback 1.1080 + eliminates history, there's no way for the disappearance of a 1.1081 + change to propagate between repositories.</para> 1.1082 + 1.1083 + <para id="x_de">If you've pushed a change to another 1.1084 + repository&emdash;particularly if it's a shared 1.1085 + repository&emdash;it has essentially <quote>escaped into the 1.1086 + wild,</quote> and you'll have to recover from your mistake 1.1087 + in a different way. If you push a changeset somewhere, then 1.1088 + roll it back, then pull from the repository you pushed to, the 1.1089 + changeset you thought you'd gotten rid of will simply reappear 1.1090 + in your repository.</para> 1.1091 + 1.1092 + <para id="x_df">(If you absolutely know for sure that the change 1.1093 + you want to roll back is the most recent change in the 1.1094 + repository that you pushed to, <emphasis>and</emphasis> you 1.1095 + know that nobody else could have pulled it from that 1.1096 + repository, you can roll back the changeset there, too, but 1.1097 + you really should not expect this to work reliably. Sooner or 1.1098 + later a change really will make it into a repository that you 1.1099 + don't directly control (or have forgotten about), and come 1.1100 + back to bite you.)</para> 1.1101 + 1.1102 + </sect2> 1.1103 + <sect2> 1.1104 + <title>You can only roll back once</title> 1.1105 + 1.1106 + <para id="x_e0">Mercurial stores exactly one transaction in its 1.1107 + transaction log; that transaction is the most recent one that 1.1108 + occurred in the repository. This means that you can only roll 1.1109 + back one transaction. If you expect to be able to roll back 1.1110 + one transaction, then its predecessor, this is not the 1.1111 + behavior you will get.</para> 1.1112 + 1.1113 + &interaction.rollback.twice; 1.1114 + 1.1115 + <para id="x_e1">Once you've rolled back one transaction in a repository, 1.1116 + you can't roll back again in that repository until you perform 1.1117 + another commit or pull.</para> 1.1118 + 1.1119 + </sect2> 1.1120 + </sect1> 1.1121 + <sect1> 1.1122 + <title>Reverting the mistaken change</title> 1.1123 + 1.1124 + <para id="x_e2">If you make a modification to a file, and decide that you 1.1125 + really didn't want to change the file at all, and you haven't 1.1126 + yet committed your changes, the <command role="hg-cmd">hg 1.1127 + revert</command> command is the one you'll need. It looks at 1.1128 + the changeset that's the parent of the working directory, and 1.1129 + restores the contents of the file to their state as of that 1.1130 + changeset. (That's a long-winded way of saying that, in the 1.1131 + normal case, it undoes your modifications.)</para> 1.1132 + 1.1133 + <para id="x_e3">Let's illustrate how the <command role="hg-cmd">hg 1.1134 + revert</command> command works with yet another small example. 1.1135 + We'll begin by modifying a file that Mercurial is already 1.1136 + tracking.</para> 1.1137 + 1.1138 + &interaction.daily.revert.modify; 1.1139 + 1.1140 + <para id="x_e4">If we don't 1.1141 + want that change, we can simply <command role="hg-cmd">hg 1.1142 + revert</command> the file.</para> 1.1143 + 1.1144 + &interaction.daily.revert.unmodify; 1.1145 + 1.1146 + <para id="x_e5">The <command role="hg-cmd">hg revert</command> command 1.1147 + provides us with an extra degree of safety by saving our 1.1148 + modified file with a <filename>.orig</filename> 1.1149 + extension.</para> 1.1150 + 1.1151 + &interaction.daily.revert.status; 1.1152 + 1.1153 + <tip> 1.1154 + <title>Be careful with <filename>.orig</filename> files</title> 1.1155 + 1.1156 + <para id="x_6b8">It's extremely unlikely that you are either using 1.1157 + Mercurial to manage files with <filename>.orig</filename> 1.1158 + extensions or that you even care about the contents of such 1.1159 + files. Just in case, though, it's useful to remember that 1.1160 + <command role="hg-cmd">hg revert</command> will 1.1161 + unconditionally overwrite an existing file with a 1.1162 + <filename>.orig</filename> extension. For instance, if you 1.1163 + already have a file named <filename>foo.orig</filename> when 1.1164 + you revert <filename>foo</filename>, the contents of 1.1165 + <filename>foo.orig</filename> will be clobbered.</para> 1.1166 + </tip> 1.1167 + 1.1168 + <para id="x_e6">Here is a summary of the cases that the <command 1.1169 + role="hg-cmd">hg revert</command> command can deal with. We 1.1170 + will describe each of these in more detail in the section that 1.1171 + follows.</para> 1.1172 + <itemizedlist> 1.1173 + <listitem><para id="x_e7">If you modify a file, it will restore the file 1.1174 + to its unmodified state.</para> 1.1175 + </listitem> 1.1176 + <listitem><para id="x_e8">If you <command role="hg-cmd">hg add</command> a 1.1177 + file, it will undo the <quote>added</quote> state of the 1.1178 + file, but leave the file itself untouched.</para> 1.1179 + </listitem> 1.1180 + <listitem><para id="x_e9">If you delete a file without telling Mercurial, 1.1181 + it will restore the file to its unmodified contents.</para> 1.1182 + </listitem> 1.1183 + <listitem><para id="x_ea">If you use the <command role="hg-cmd">hg 1.1184 + remove</command> command to remove a file, it will undo 1.1185 + the <quote>removed</quote> state of the file, and restore 1.1186 + the file to its unmodified contents.</para> 1.1187 + </listitem></itemizedlist> 1.1188 + 1.1189 + <sect2 id="sec:undo:mgmt"> 1.1190 + <title>File management errors</title> 1.1191 + 1.1192 + <para id="x_eb">The <command role="hg-cmd">hg revert</command> command is 1.1193 + useful for more than just modified files. It lets you reverse 1.1194 + the results of all of Mercurial's file management 1.1195 + commands&emdash;<command role="hg-cmd">hg add</command>, 1.1196 + <command role="hg-cmd">hg remove</command>, and so on.</para> 1.1197 + 1.1198 + <para id="x_ec">If you <command role="hg-cmd">hg add</command> a file, 1.1199 + then decide that in fact you don't want Mercurial to track it, 1.1200 + use <command role="hg-cmd">hg revert</command> to undo the 1.1201 + add. Don't worry; Mercurial will not modify the file in any 1.1202 + way. It will just <quote>unmark</quote> the file.</para> 1.1203 + 1.1204 + &interaction.daily.revert.add; 1.1205 + 1.1206 + <para id="x_ed">Similarly, if you ask Mercurial to <command 1.1207 + role="hg-cmd">hg remove</command> a file, you can use 1.1208 + <command role="hg-cmd">hg revert</command> to restore it to 1.1209 + the contents it had as of the parent of the working directory. 1.1210 + &interaction.daily.revert.remove; This works just as 1.1211 + well for a file that you deleted by hand, without telling 1.1212 + Mercurial (recall that in Mercurial terminology, this kind of 1.1213 + file is called <quote>missing</quote>).</para> 1.1214 + 1.1215 + &interaction.daily.revert.missing; 1.1216 + 1.1217 + <para id="x_ee">If you revert a <command role="hg-cmd">hg copy</command>, 1.1218 + the copied-to file remains in your working directory 1.1219 + afterwards, untracked. Since a copy doesn't affect the 1.1220 + copied-from file in any way, Mercurial doesn't do anything 1.1221 + with the copied-from file.</para> 1.1222 + 1.1223 + &interaction.daily.revert.copy; 1.1224 + </sect2> 1.1225 + </sect1> 1.1226 + 1.1227 + <sect1> 1.1228 + <title>Dealing with committed changes</title> 1.1229 + 1.1230 + <para id="x_f5">Consider a case where you have committed a change 1.1231 + <emphasis>a</emphasis>, and another change 1.1232 + <emphasis>b</emphasis> on top of it; you then realise that 1.1233 + change <emphasis>a</emphasis> was incorrect. Mercurial lets you 1.1234 + <quote>back out</quote> an entire changeset automatically, and 1.1235 + building blocks that let you reverse part of a changeset by 1.1236 + hand.</para> 1.1237 + 1.1238 + <para id="x_f6">Before you read this section, here's something to 1.1239 + keep in mind: the <command role="hg-cmd">hg backout</command> 1.1240 + command undoes the effect of a change by 1.1241 + <emphasis>adding</emphasis> to your repository's history, not by 1.1242 + modifying or erasing it. It's the right tool to use if you're 1.1243 + fixing bugs, but not if you're trying to undo some change that 1.1244 + has catastrophic consequences. To deal with those, see 1.1245 + <xref linkend="sec:undo:aaaiiieee"/>.</para> 1.1246 + 1.1247 + <sect2> 1.1248 + <title>Backing out a changeset</title> 1.1249 + 1.1250 + <para id="x_f7">The <command role="hg-cmd">hg backout</command> command 1.1251 + lets you <quote>undo</quote> the effects of an entire 1.1252 + changeset in an automated fashion. Because Mercurial's 1.1253 + history is immutable, this command <emphasis>does 1.1254 + not</emphasis> get rid of the changeset you want to undo. 1.1255 + Instead, it creates a new changeset that 1.1256 + <emphasis>reverses</emphasis> the effect of the to-be-undone 1.1257 + changeset.</para> 1.1258 + 1.1259 + <para id="x_f8">The operation of the <command role="hg-cmd">hg 1.1260 + backout</command> command is a little intricate, so let's 1.1261 + illustrate it with some examples. First, we'll create a 1.1262 + repository with some simple changes.</para> 1.1263 + 1.1264 + &interaction.backout.init; 1.1265 + 1.1266 + <para id="x_f9">The <command role="hg-cmd">hg backout</command> command 1.1267 + takes a single changeset ID as its argument; this is the 1.1268 + changeset to back out. Normally, <command role="hg-cmd">hg 1.1269 + backout</command> will drop you into a text editor to write 1.1270 + a commit message, so you can record why you're backing the 1.1271 + change out. In this example, we provide a commit message on 1.1272 + the command line using the <option 1.1273 + role="hg-opt-backout">-m</option> option.</para> 1.1274 + 1.1275 + </sect2> 1.1276 + <sect2> 1.1277 + <title>Backing out the tip changeset</title> 1.1278 + 1.1279 + <para id="x_fa">We're going to start by backing out the last changeset we 1.1280 + committed.</para> 1.1281 + 1.1282 + &interaction.backout.simple; 1.1283 + 1.1284 + <para id="x_fb">You can see that the second line from 1.1285 + <filename>myfile</filename> is no longer present. Taking a 1.1286 + look at the output of <command role="hg-cmd">hg log</command> 1.1287 + gives us an idea of what the <command role="hg-cmd">hg 1.1288 + backout</command> command has done. 1.1289 + &interaction.backout.simple.log; Notice that the new changeset 1.1290 + that <command role="hg-cmd">hg backout</command> has created 1.1291 + is a child of the changeset we backed out. It's easier to see 1.1292 + this in <xref linkend="fig:undo:backout"/>, which presents a 1.1293 + graphical view of the change history. As you can see, the 1.1294 + history is nice and linear.</para> 1.1295 + 1.1296 + <figure id="fig:undo:backout"> 1.1297 + <title>Backing out a change using the <command 1.1298 + role="hg-cmd">hg backout</command> command</title> 1.1299 + <mediaobject> 1.1300 + <imageobject><imagedata fileref="figs/undo-simple.png"/></imageobject> 1.1301 + <textobject><phrase>XXX add text</phrase></textobject> 1.1302 + </mediaobject> 1.1303 + </figure> 1.1304 + 1.1305 + </sect2> 1.1306 + <sect2> 1.1307 + <title>Backing out a non-tip change</title> 1.1308 + 1.1309 + <para id="x_fd">If you want to back out a change other than the last one 1.1310 + you committed, pass the <option 1.1311 + role="hg-opt-backout">--merge</option> option to the 1.1312 + <command role="hg-cmd">hg backout</command> command.</para> 1.1313 + 1.1314 + &interaction.backout.non-tip.clone; 1.1315 + 1.1316 + <para id="x_fe">This makes backing out any changeset a 1.1317 + <quote>one-shot</quote> operation that's usually simple and 1.1318 + fast.</para> 1.1319 + 1.1320 + &interaction.backout.non-tip.backout; 1.1321 + 1.1322 + <para id="x_ff">If you take a look at the contents of 1.1323 + <filename>myfile</filename> after the backout finishes, you'll 1.1324 + see that the first and third changes are present, but not the 1.1325 + second.</para> 1.1326 + 1.1327 + &interaction.backout.non-tip.cat; 1.1328 + 1.1329 + <para id="x_100">As the graphical history in <xref 1.1330 + linkend="fig:undo:backout-non-tip"/> illustrates, Mercurial 1.1331 + still commits one change in this kind of situation (the 1.1332 + box-shaped node is the ones that Mercurial commits 1.1333 + automatically), but the revision graph now looks different. 1.1334 + Before Mercurial begins the backout process, it first 1.1335 + remembers what the current parent of the working directory is. 1.1336 + It then backs out the target changeset, and commits that as a 1.1337 + changeset. Finally, it merges back to the previous parent of 1.1338 + the working directory, but notice that it <emphasis>does not 1.1339 + commit</emphasis> the result of the merge. The repository 1.1340 + now contains two heads, and the working directory is in a 1.1341 + merge state.</para> 1.1342 + 1.1343 + <figure id="fig:undo:backout-non-tip"> 1.1344 + <title>Automated backout of a non-tip change using the 1.1345 + <command role="hg-cmd">hg backout</command> command</title> 1.1346 + <mediaobject> 1.1347 + <imageobject><imagedata fileref="figs/undo-non-tip.png"/></imageobject> 1.1348 + <textobject><phrase>XXX add text</phrase></textobject> 1.1349 + </mediaobject> 1.1350 + </figure> 1.1351 + 1.1352 + <para id="x_103">The result is that you end up <quote>back where you 1.1353 + were</quote>, only with some extra history that undoes the 1.1354 + effect of the changeset you wanted to back out.</para> 1.1355 + 1.1356 + <para id="x_6b9">You might wonder why Mercurial does not commit the result 1.1357 + of the merge that it performed. The reason lies in Mercurial 1.1358 + behaving conservatively: a merge naturally has more scope for 1.1359 + error than simply undoing the effect of the tip changeset, 1.1360 + so your work will be safest if you first inspect (and test!) 1.1361 + the result of the merge, <emphasis>then</emphasis> commit 1.1362 + it.</para> 1.1363 + 1.1364 + <sect3> 1.1365 + <title>Always use the <option 1.1366 + role="hg-opt-backout">--merge</option> option</title> 1.1367 + 1.1368 + <para id="x_104">In fact, since the <option 1.1369 + role="hg-opt-backout">--merge</option> option will do the 1.1370 + <quote>right thing</quote> whether or not the changeset 1.1371 + you're backing out is the tip (i.e. it won't try to merge if 1.1372 + it's backing out the tip, since there's no need), you should 1.1373 + <emphasis>always</emphasis> use this option when you run the 1.1374 + <command role="hg-cmd">hg backout</command> command.</para> 1.1375 + 1.1376 + </sect3> 1.1377 + </sect2> 1.1378 + <sect2> 1.1379 + <title>Gaining more control of the backout process</title> 1.1380 + 1.1381 + <para id="x_105">While I've recommended that you always use the <option 1.1382 + role="hg-opt-backout">--merge</option> option when backing 1.1383 + out a change, the <command role="hg-cmd">hg backout</command> 1.1384 + command lets you decide how to merge a backout changeset. 1.1385 + Taking control of the backout process by hand is something you 1.1386 + will rarely need to do, but it can be useful to understand 1.1387 + what the <command role="hg-cmd">hg backout</command> command 1.1388 + is doing for you automatically. To illustrate this, let's 1.1389 + clone our first repository, but omit the backout change that 1.1390 + it contains.</para> 1.1391 + 1.1392 + &interaction.backout.manual.clone; 1.1393 + 1.1394 + <para id="x_106">As with our 1.1395 + earlier example, We'll commit a third changeset, then back out 1.1396 + its parent, and see what happens.</para> 1.1397 + 1.1398 + &interaction.backout.manual.backout; 1.1399 + 1.1400 + <para id="x_107">Our new changeset is again a descendant of the changeset 1.1401 + we backout out; it's thus a new head, <emphasis>not</emphasis> 1.1402 + a descendant of the changeset that was the tip. The <command 1.1403 + role="hg-cmd">hg backout</command> command was quite 1.1404 + explicit in telling us this.</para> 1.1405 + 1.1406 + &interaction.backout.manual.log; 1.1407 + 1.1408 + <para id="x_108">Again, it's easier to see what has happened by looking at 1.1409 + a graph of the revision history, in <xref 1.1410 + linkend="fig:undo:backout-manual"/>. This makes it clear 1.1411 + that when we use <command role="hg-cmd">hg backout</command> 1.1412 + to back out a change other than the tip, Mercurial adds a new 1.1413 + head to the repository (the change it committed is 1.1414 + box-shaped).</para> 1.1415 + 1.1416 + <figure id="fig:undo:backout-manual"> 1.1417 + <title>Backing out a change using the <command 1.1418 + role="hg-cmd">hg backout</command> command</title> 1.1419 + <mediaobject> 1.1420 + <imageobject><imagedata fileref="figs/undo-manual.png"/></imageobject> 1.1421 + <textobject><phrase>XXX add text</phrase></textobject> 1.1422 + </mediaobject> 1.1423 + </figure> 1.1424 + 1.1425 + <para id="x_10a">After the <command role="hg-cmd">hg backout</command> 1.1426 + command has completed, it leaves the new 1.1427 + <quote>backout</quote> changeset as the parent of the working 1.1428 + directory.</para> 1.1429 + 1.1430 + &interaction.backout.manual.parents; 1.1431 + 1.1432 + <para id="x_10b">Now we have two isolated sets of changes.</para> 1.1433 + 1.1434 + &interaction.backout.manual.heads; 1.1435 + 1.1436 + <para id="x_10c">Let's think about what we expect to see as the contents of 1.1437 + <filename>myfile</filename> now. The first change should be 1.1438 + present, because we've never backed it out. The second change 1.1439 + should be missing, as that's the change we backed out. Since 1.1440 + the history graph shows the third change as a separate head, 1.1441 + we <emphasis>don't</emphasis> expect to see the third change 1.1442 + present in <filename>myfile</filename>.</para> 1.1443 + 1.1444 + &interaction.backout.manual.cat; 1.1445 + 1.1446 + <para id="x_10d">To get the third change back into the file, we just do a 1.1447 + normal merge of our two heads.</para> 1.1448 + 1.1449 + &interaction.backout.manual.merge; 1.1450 + 1.1451 + <para id="x_10e">Afterwards, the graphical history of our 1.1452 + repository looks like 1.1453 + <xref linkend="fig:undo:backout-manual-merge"/>.</para> 1.1454 + 1.1455 + <figure id="fig:undo:backout-manual-merge"> 1.1456 + <title>Manually merging a backout change</title> 1.1457 + <mediaobject> 1.1458 + <imageobject><imagedata fileref="figs/undo-manual-merge.png"/></imageobject> 1.1459 + <textobject><phrase>XXX add text</phrase></textobject> 1.1460 + </mediaobject> 1.1461 + </figure> 1.1462 + 1.1463 + </sect2> 1.1464 + <sect2> 1.1465 + <title>Why <command role="hg-cmd">hg backout</command> works as 1.1466 + it does</title> 1.1467 + 1.1468 + <para id="x_110">Here's a brief description of how the <command 1.1469 + role="hg-cmd">hg backout</command> command works.</para> 1.1470 + <orderedlist> 1.1471 + <listitem><para id="x_111">It ensures that the working directory is 1.1472 + <quote>clean</quote>, i.e. that the output of <command 1.1473 + role="hg-cmd">hg status</command> would be empty.</para> 1.1474 + </listitem> 1.1475 + <listitem><para id="x_112">It remembers the current parent of the working 1.1476 + directory. Let's call this changeset 1.1477 + <literal>orig</literal>.</para> 1.1478 + </listitem> 1.1479 + <listitem><para id="x_113">It does the equivalent of a <command 1.1480 + role="hg-cmd">hg update</command> to sync the working 1.1481 + directory to the changeset you want to back out. Let's 1.1482 + call this changeset <literal>backout</literal>.</para> 1.1483 + </listitem> 1.1484 + <listitem><para id="x_114">It finds the parent of that changeset. Let's 1.1485 + call that changeset <literal>parent</literal>.</para> 1.1486 + </listitem> 1.1487 + <listitem><para id="x_115">For each file that the 1.1488 + <literal>backout</literal> changeset affected, it does the 1.1489 + equivalent of a <command role="hg-cmd">hg revert -r 1.1490 + parent</command> on that file, to restore it to the 1.1491 + contents it had before that changeset was 1.1492 + committed.</para> 1.1493 + </listitem> 1.1494 + <listitem><para id="x_116">It commits the result as a new changeset. 1.1495 + This changeset has <literal>backout</literal> as its 1.1496 + parent.</para> 1.1497 + </listitem> 1.1498 + <listitem><para id="x_117">If you specify <option 1.1499 + role="hg-opt-backout">--merge</option> on the command 1.1500 + line, it merges with <literal>orig</literal>, and commits 1.1501 + the result of the merge.</para> 1.1502 + </listitem></orderedlist> 1.1503 + 1.1504 + <para id="x_118">An alternative way to implement the <command 1.1505 + role="hg-cmd">hg backout</command> command would be to 1.1506 + <command role="hg-cmd">hg export</command> the 1.1507 + to-be-backed-out changeset as a diff, then use the <option 1.1508 + role="cmd-opt-patch">--reverse</option> option to the 1.1509 + <command>patch</command> command to reverse the effect of the 1.1510 + change without fiddling with the working directory. This 1.1511 + sounds much simpler, but it would not work nearly as 1.1512 + well.</para> 1.1513 + 1.1514 + <para id="x_119">The reason that <command role="hg-cmd">hg 1.1515 + backout</command> does an update, a commit, a merge, and 1.1516 + another commit is to give the merge machinery the best chance 1.1517 + to do a good job when dealing with all the changes 1.1518 + <emphasis>between</emphasis> the change you're backing out and 1.1519 + the current tip.</para> 1.1520 + 1.1521 + <para id="x_11a">If you're backing out a changeset that's 100 revisions 1.1522 + back in your project's history, the chances that the 1.1523 + <command>patch</command> command will be able to apply a 1.1524 + reverse diff cleanly are not good, because intervening changes 1.1525 + are likely to have <quote>broken the context</quote> that 1.1526 + <command>patch</command> uses to determine whether it can 1.1527 + apply a patch (if this sounds like gibberish, see <xref 1.1528 + linkend="sec:mq:patch"/> for a 1.1529 + discussion of the <command>patch</command> command). Also, 1.1530 + Mercurial's merge machinery will handle files and directories 1.1531 + being renamed, permission changes, and modifications to binary 1.1532 + files, none of which <command>patch</command> can deal 1.1533 + with.</para> 1.1534 + 1.1535 + </sect2> 1.1536 + </sect1> 1.1537 + <sect1 id="sec:undo:aaaiiieee"> 1.1538 + <title>Changes that should never have been</title> 1.1539 + 1.1540 + <para id="x_11b">Most of the time, the <command role="hg-cmd">hg 1.1541 + backout</command> command is exactly what you need if you want 1.1542 + to undo the effects of a change. It leaves a permanent record 1.1543 + of exactly what you did, both when committing the original 1.1544 + changeset and when you cleaned up after it.</para> 1.1545 + 1.1546 + <para id="x_11c">On rare occasions, though, you may find that you've 1.1547 + committed a change that really should not be present in the 1.1548 + repository at all. For example, it would be very unusual, and 1.1549 + usually considered a mistake, to commit a software project's 1.1550 + object files as well as its source files. Object files have 1.1551 + almost no intrinsic value, and they're <emphasis>big</emphasis>, 1.1552 + so they increase the size of the repository and the amount of 1.1553 + time it takes to clone or pull changes.</para> 1.1554 + 1.1555 + <para id="x_11d">Before I discuss the options that you have if you commit a 1.1556 + <quote>brown paper bag</quote> change (the kind that's so bad 1.1557 + that you want to pull a brown paper bag over your head), let me 1.1558 + first discuss some approaches that probably won't work.</para> 1.1559 + 1.1560 + <para id="x_11e">Since Mercurial treats history as 1.1561 + accumulative&emdash;every change builds on top of all changes 1.1562 + that preceded it&emdash;you generally can't just make disastrous 1.1563 + changes disappear. The one exception is when you've just 1.1564 + committed a change, and it hasn't been pushed or pulled into 1.1565 + another repository. That's when you can safely use the <command 1.1566 + role="hg-cmd">hg rollback</command> command, as I detailed in 1.1567 + <xref linkend="sec:undo:rollback"/>.</para> 1.1568 + 1.1569 + <para id="x_11f">After you've pushed a bad change to another repository, you 1.1570 + <emphasis>could</emphasis> still use <command role="hg-cmd">hg 1.1571 + rollback</command> to make your local copy of the change 1.1572 + disappear, but it won't have the consequences you want. The 1.1573 + change will still be present in the remote repository, so it 1.1574 + will reappear in your local repository the next time you 1.1575 + pull.</para> 1.1576 + 1.1577 + <para id="x_120">If a situation like this arises, and you know which 1.1578 + repositories your bad change has propagated into, you can 1.1579 + <emphasis>try</emphasis> to get rid of the change from 1.1580 + <emphasis>every</emphasis> one of those repositories. This is, 1.1581 + of course, not a satisfactory solution: if you miss even a 1.1582 + single repository while you're expunging, the change is still 1.1583 + <quote>in the wild</quote>, and could propagate further.</para> 1.1584 + 1.1585 + <para id="x_121">If you've committed one or more changes 1.1586 + <emphasis>after</emphasis> the change that you'd like to see 1.1587 + disappear, your options are further reduced. Mercurial doesn't 1.1588 + provide a way to <quote>punch a hole</quote> in history, leaving 1.1589 + changesets intact.</para> 1.1590 + 1.1591 + <sect2> 1.1592 + <title>Backing out a merge</title> 1.1593 + 1.1594 + <para id="x_6ba">Since merges are often complicated, it is not unheard of 1.1595 + for a merge to be mangled badly, but committed erroneously. 1.1596 + Mercurial provides an important safeguard against bad merges 1.1597 + by refusing to commit unresolved files, but human ingenuity 1.1598 + guarantees that it is still possible to mess a merge up and 1.1599 + commit it.</para> 1.1600 + 1.1601 + <para id="x_6bb">Given a bad merge that has been committed, usually the 1.1602 + best way to approach it is to simply try to repair the damage 1.1603 + by hand. A complete disaster that cannot be easily fixed up 1.1604 + by hand ought to be very rare, but the <command 1.1605 + role="hg-cmd">hg backout</command> command may help in 1.1606 + making the cleanup easier. It offers a <option 1.1607 + role="hg-opt-backout">--parent</option> option, which lets 1.1608 + you specify which parent to revert to when backing out a 1.1609 + merge.</para> 1.1610 + 1.1611 + <figure id="fig:undo:bad-merge-1"> 1.1612 + <title>A bad merge</title> 1.1613 + <mediaobject> 1.1614 + <imageobject><imagedata fileref="figs/bad-merge-1.png"/></imageobject> 1.1615 + <textobject><phrase>XXX add text</phrase></textobject> 1.1616 + </mediaobject> 1.1617 + </figure> 1.1618 + 1.1619 + <para id="x_6bc">Suppose we have a revision graph like that in <xref 1.1620 + linkend="fig:undo:bad-merge-1"/>. What we'd like is to 1.1621 + <emphasis>redo</emphasis> the merge of revisions 2 and 1.1622 + 3.</para> 1.1623 + 1.1624 + <para id="x_6bd">One way to do so would be as follows.</para> 1.1625 + 1.1626 + <orderedlist> 1.1627 + <listitem> 1.1628 + <para id="x_6be">Call <command role="hg-cmd">hg backout --rev=4 1.1629 + --parent=2</command>. This tells <command 1.1630 + role="hg-cmd">hg backout</command> to back out revision 1.1631 + 4, which is the bad merge, and to when deciding which 1.1632 + revision to prefer, to choose parent 2, one of the parents 1.1633 + of the merge. The effect can be seen in <xref 1.1634 + linkend="fig:undo:bad-merge-2"/>.</para> 1.1635 + <figure id="fig:undo:bad-merge-2"> 1.1636 + <title>Backing out the merge, favoring one parent</title> 1.1637 + <mediaobject> 1.1638 + <imageobject><imagedata fileref="figs/bad-merge-2.png"/></imageobject> 1.1639 + <textobject><phrase>XXX add text</phrase></textobject> 1.1640 + </mediaobject> 1.1641 + </figure> 1.1642 + </listitem> 1.1643 + 1.1644 + <listitem> 1.1645 + <para id="x_6bf">Call <command role="hg-cmd">hg backout --rev=4 1.1646 + --parent=3</command>. This tells <command 1.1647 + role="hg-cmd">hg backout</command> to back out revision 1.1648 + 4 again, but this time to choose parent 3, the other 1.1649 + parent of the merge. The result is visible in <xref 1.1650 + linkend="fig:undo:bad-merge-3"/>, in which the repository 1.1651 + now contains three heads.</para> 1.1652 + <figure id="fig:undo:bad-merge-3"> 1.1653 + <title>Backing out the merge, favoring the other 1.1654 + parent</title> 1.1655 + <mediaobject> 1.1656 + <imageobject><imagedata fileref="figs/bad-merge-3.png"/></imageobject> 1.1657 + <textobject><phrase>XXX add text</phrase></textobject> 1.1658 + </mediaobject> 1.1659 + </figure> 1.1660 + </listitem> 1.1661 + 1.1662 + <listitem> 1.1663 + <para id="x_6c0">Redo the bad merge by merging the two backout heads, 1.1664 + which reduces the number of heads in the repository to 1.1665 + two, as can be seen in <xref 1.1666 + linkend="fig:undo:bad-merge-4"/>.</para> 1.1667 + <figure id="fig:undo:bad-merge-4"> 1.1668 + <title>Merging the backouts</title> 1.1669 + <mediaobject> 1.1670 + <imageobject><imagedata fileref="figs/bad-merge-4.png"/></imageobject> 1.1671 + <textobject><phrase>XXX add text</phrase></textobject> 1.1672 + </mediaobject> 1.1673 + </figure> 1.1674 + </listitem> 1.1675 + 1.1676 + <listitem> 1.1677 + <para id="x_6c1">Merge with the commit that was made after the bad 1.1678 + merge, as shown in <xref 1.1679 + linkend="fig:undo:bad-merge-5"/>.</para> 1.1680 + <figure id="fig:undo:bad-merge-5"> 1.1681 + <title>Merging the backouts</title> 1.1682 + <mediaobject> 1.1683 + <imageobject><imagedata fileref="figs/bad-merge-5.png"/></imageobject> 1.1684 + <textobject><phrase>XXX add text</phrase></textobject> 1.1685 + </mediaobject> 1.1686 + </figure> 1.1687 + </listitem> 1.1688 + </orderedlist> 1.1689 + </sect2> 1.1690 + 1.1691 + <sect2> 1.1692 + <title>Protect yourself from <quote>escaped</quote> 1.1693 + changes</title> 1.1694 + 1.1695 + <para id="x_123">If you've committed some changes to your local repository 1.1696 + and they've been pushed or pulled somewhere else, this isn't 1.1697 + necessarily a disaster. You can protect yourself ahead of 1.1698 + time against some classes of bad changeset. This is 1.1699 + particularly easy if your team usually pulls changes from a 1.1700 + central repository.</para> 1.1701 + 1.1702 + <para id="x_124">By configuring some hooks on that repository to validate 1.1703 + incoming changesets (see chapter <xref linkend="chap:hook"/>), 1.1704 + you can 1.1705 + automatically prevent some kinds of bad changeset from being 1.1706 + pushed to the central repository at all. With such a 1.1707 + configuration in place, some kinds of bad changeset will 1.1708 + naturally tend to <quote>die out</quote> because they can't 1.1709 + propagate into the central repository. Better yet, this 1.1710 + happens without any need for explicit intervention.</para> 1.1711 + 1.1712 + <para id="x_125">For instance, an incoming change hook that 1.1713 + verifies that a changeset will actually compile can prevent 1.1714 + people from inadvertently <quote>breaking the 1.1715 + build</quote>.</para> 1.1716 + </sect2> 1.1717 + 1.1718 + <sect2> 1.1719 + <title>What to do about sensitive changes that escape</title> 1.1720 + 1.1721 + <para id="x_6c2">Even a carefully run project can suffer an unfortunate 1.1722 + event such as the committing and uncontrolled propagation of a 1.1723 + file that contains important passwords.</para> 1.1724 + 1.1725 + <para id="x_6c3">If something like this happens to you, and the information 1.1726 + that gets accidentally propagated is truly sensitive, your 1.1727 + first step should be to mitigate the effect of the leak 1.1728 + without trying to control the leak itself. If you are not 100% 1.1729 + certain that you know exactly who could have seen the changes, 1.1730 + you should immediately change passwords, cancel credit cards, 1.1731 + or find some other way to make sure that the information that 1.1732 + has leaked is no longer useful. In other words, assume that 1.1733 + the change has propagated far and wide, and that there's 1.1734 + nothing more you can do.</para> 1.1735 + 1.1736 + <para id="x_6c4">You might hope that there would be mechanisms you could 1.1737 + use to either figure out who has seen a change or to erase the 1.1738 + change permanently everywhere, but there are good reasons why 1.1739 + these are not possible.</para> 1.1740 + 1.1741 + <para id="x_6c5">Mercurial does not provide an audit trail of who has 1.1742 + pulled changes from a repository, because it is usually either 1.1743 + impossible to record such information or trivial to spoof it. 1.1744 + In a multi-user or networked environment, you should thus be 1.1745 + extremely skeptical of yourself if you think that you have 1.1746 + identified every place that a sensitive changeset has 1.1747 + propagated to. Don't forget that people can and will send 1.1748 + bundles by email, have their backup software save data 1.1749 + offsite, carry repositories on USB sticks, and find other 1.1750 + completely innocent ways to confound your attempts to track 1.1751 + down every copy of a problematic change.</para> 1.1752 + 1.1753 + <para id="x_6c6">Mercurial also does not provide a way to make a file or 1.1754 + changeset completely disappear from history, because there is 1.1755 + no way to enforce its disappearance; someone could easily 1.1756 + modify their copy of Mercurial to ignore such directives. In 1.1757 + addition, even if Mercurial provided such a capability, 1.1758 + someone who simply hadn't pulled a <quote>make this file 1.1759 + disappear</quote> changeset wouldn't be affected by it, nor 1.1760 + would web crawlers visiting at the wrong time, disk backups, 1.1761 + or other mechanisms. Indeed, no distributed revision control 1.1762 + system can make data reliably vanish. Providing the illusion 1.1763 + of such control could easily give a false sense of security, 1.1764 + and be worse than not providing it at all.</para> 1.1765 + </sect2> 1.1766 + </sect1> 1.1767 + 1.1768 + <sect1 id="sec:undo:bisect"> 1.1769 + <title>Finding the source of a bug</title> 1.1770 + 1.1771 + <para id="x_126">While it's all very well to be able to back out a changeset 1.1772 + that introduced a bug, this requires that you know which 1.1773 + changeset to back out. Mercurial provides an invaluable 1.1774 + command, called <command role="hg-cmd">hg bisect</command>, that 1.1775 + helps you to automate this process and accomplish it very 1.1776 + efficiently.</para> 1.1777 + 1.1778 + <para id="x_127">The idea behind the <command role="hg-cmd">hg 1.1779 + bisect</command> command is that a changeset has introduced 1.1780 + some change of behavior that you can identify with a simple 1.1781 + pass/fail test. You don't know which piece of code introduced the 1.1782 + change, but you know how to test for the presence of the bug. 1.1783 + The <command role="hg-cmd">hg bisect</command> command uses your 1.1784 + test to direct its search for the changeset that introduced the 1.1785 + code that caused the bug.</para> 1.1786 + 1.1787 + <para id="x_128">Here are a few scenarios to help you understand how you 1.1788 + might apply this command.</para> 1.1789 + <itemizedlist> 1.1790 + <listitem><para id="x_129">The most recent version of your software has a 1.1791 + bug that you remember wasn't present a few weeks ago, but 1.1792 + you don't know when it was introduced. Here, your binary 1.1793 + test checks for the presence of that bug.</para> 1.1794 + </listitem> 1.1795 + <listitem><para id="x_12a">You fixed a bug in a rush, and now it's time to 1.1796 + close the entry in your team's bug database. The bug 1.1797 + database requires a changeset ID when you close an entry, 1.1798 + but you don't remember which changeset you fixed the bug in. 1.1799 + Once again, your binary test checks for the presence of the 1.1800 + bug.</para> 1.1801 + </listitem> 1.1802 + <listitem><para id="x_12b">Your software works correctly, but runs 15% 1.1803 + slower than the last time you measured it. You want to know 1.1804 + which changeset introduced the performance regression. In 1.1805 + this case, your binary test measures the performance of your 1.1806 + software, to see whether it's <quote>fast</quote> or 1.1807 + <quote>slow</quote>.</para> 1.1808 + </listitem> 1.1809 + <listitem><para id="x_12c">The sizes of the components of your project that 1.1810 + you ship exploded recently, and you suspect that something 1.1811 + changed in the way you build your project.</para> 1.1812 + </listitem></itemizedlist> 1.1813 + 1.1814 + <para id="x_12d">From these examples, it should be clear that the <command 1.1815 + role="hg-cmd">hg bisect</command> command is not useful only 1.1816 + for finding the sources of bugs. You can use it to find any 1.1817 + <quote>emergent property</quote> of a repository (anything that 1.1818 + you can't find from a simple text search of the files in the 1.1819 + tree) for which you can write a binary test.</para> 1.1820 + 1.1821 + <para id="x_12e">We'll introduce a little bit of terminology here, just to 1.1822 + make it clear which parts of the search process are your 1.1823 + responsibility, and which are Mercurial's. A 1.1824 + <emphasis>test</emphasis> is something that 1.1825 + <emphasis>you</emphasis> run when <command role="hg-cmd">hg 1.1826 + bisect</command> chooses a changeset. A 1.1827 + <emphasis>probe</emphasis> is what <command role="hg-cmd">hg 1.1828 + bisect</command> runs to tell whether a revision is good. 1.1829 + Finally, we'll use the word <quote>bisect</quote>, as both a 1.1830 + noun and a verb, to stand in for the phrase <quote>search using 1.1831 + the <command role="hg-cmd">hg bisect</command> 1.1832 + command</quote>.</para> 1.1833 + 1.1834 + <para id="x_12f">One simple way to automate the searching process would be 1.1835 + simply to probe every changeset. However, this scales poorly. 1.1836 + If it took ten minutes to test a single changeset, and you had 1.1837 + 10,000 changesets in your repository, the exhaustive approach 1.1838 + would take on average 35 <emphasis>days</emphasis> to find the 1.1839 + changeset that introduced a bug. Even if you knew that the bug 1.1840 + was introduced by one of the last 500 changesets, and limited 1.1841 + your search to those, you'd still be looking at over 40 hours to 1.1842 + find the changeset that introduced your bug.</para> 1.1843 + 1.1844 + <para id="x_130">What the <command role="hg-cmd">hg bisect</command> command 1.1845 + does is use its knowledge of the <quote>shape</quote> of your 1.1846 + project's revision history to perform a search in time 1.1847 + proportional to the <emphasis>logarithm</emphasis> of the number 1.1848 + of changesets to check (the kind of search it performs is called 1.1849 + a dichotomic search). With this approach, searching through 1.1850 + 10,000 changesets will take less than three hours, even at ten 1.1851 + minutes per test (the search will require about 14 tests). 1.1852 + Limit your search to the last hundred changesets, and it will 1.1853 + take only about an hour (roughly seven tests).</para> 1.1854 + 1.1855 + <para id="x_131">The <command role="hg-cmd">hg bisect</command> command is 1.1856 + aware of the <quote>branchy</quote> nature of a Mercurial 1.1857 + project's revision history, so it has no problems dealing with 1.1858 + branches, merges, or multiple heads in a repository. It can 1.1859 + prune entire branches of history with a single probe, which is 1.1860 + how it operates so efficiently.</para> 1.1861 + 1.1862 + <sect2> 1.1863 + <title>Using the <command role="hg-cmd">hg bisect</command> 1.1864 + command</title> 1.1865 + 1.1866 + <para id="x_132">Here's an example of <command role="hg-cmd">hg 1.1867 + bisect</command> in action.</para> 1.1868 + 1.1869 + <note> 1.1870 + <para id="x_133"> In versions 0.9.5 and earlier of Mercurial, <command 1.1871 + role="hg-cmd">hg bisect</command> was not a core command: 1.1872 + it was distributed with Mercurial as an extension. This 1.1873 + section describes the built-in command, not the old 1.1874 + extension.</para> 1.1875 + </note> 1.1876 + 1.1877 + <para id="x_134">Now let's create a repository, so that we can try out the 1.1878 + <command role="hg-cmd">hg bisect</command> command in 1.1879 + isolation.</para> 1.1880 + 1.1881 + &interaction.bisect.init; 1.1882 + 1.1883 + <para id="x_135">We'll simulate a project that has a bug in it in a 1.1884 + simple-minded way: create trivial changes in a loop, and 1.1885 + nominate one specific change that will have the 1.1886 + <quote>bug</quote>. This loop creates 35 changesets, each 1.1887 + adding a single file to the repository. We'll represent our 1.1888 + <quote>bug</quote> with a file that contains the text <quote>i 1.1889 + have a gub</quote>.</para> 1.1890 + 1.1891 + &interaction.bisect.commits; 1.1892 + 1.1893 + <para id="x_136">The next thing that we'd like to do is figure out how to 1.1894 + use the <command role="hg-cmd">hg bisect</command> command. 1.1895 + We can use Mercurial's normal built-in help mechanism for 1.1896 + this.</para> 1.1897 + 1.1898 + &interaction.bisect.help; 1.1899 + 1.1900 + <para id="x_137">The <command role="hg-cmd">hg bisect</command> command 1.1901 + works in steps. Each step proceeds as follows.</para> 1.1902 + <orderedlist> 1.1903 + <listitem><para id="x_138">You run your binary test.</para> 1.1904 + <itemizedlist> 1.1905 + <listitem><para id="x_139">If the test succeeded, you tell <command 1.1906 + role="hg-cmd">hg bisect</command> by running the 1.1907 + <command role="hg-cmd">hg bisect --good</command> 1.1908 + command.</para> 1.1909 + </listitem> 1.1910 + <listitem><para id="x_13a">If it failed, run the <command 1.1911 + role="hg-cmd">hg bisect --bad</command> 1.1912 + command.</para></listitem></itemizedlist> 1.1913 + </listitem> 1.1914 + <listitem><para id="x_13b">The command uses your information to decide 1.1915 + which changeset to test next.</para> 1.1916 + </listitem> 1.1917 + <listitem><para id="x_13c">It updates the working directory to that 1.1918 + changeset, and the process begins again.</para> 1.1919 + </listitem></orderedlist> 1.1920 + <para id="x_13d">The process ends when <command role="hg-cmd">hg 1.1921 + bisect</command> identifies a unique changeset that marks 1.1922 + the point where your test transitioned from 1.1923 + <quote>succeeding</quote> to <quote>failing</quote>.</para> 1.1924 + 1.1925 + <para id="x_13e">To start the search, we must run the <command 1.1926 + role="hg-cmd">hg bisect --reset</command> command.</para> 1.1927 + 1.1928 + &interaction.bisect.search.init; 1.1929 + 1.1930 + <para id="x_13f">In our case, the binary test we use is simple: we check to 1.1931 + see if any file in the repository contains the string <quote>i 1.1932 + have a gub</quote>. If it does, this changeset contains the 1.1933 + change that <quote>caused the bug</quote>. By convention, a 1.1934 + changeset that has the property we're searching for is 1.1935 + <quote>bad</quote>, while one that doesn't is 1.1936 + <quote>good</quote>.</para> 1.1937 + 1.1938 + <para id="x_140">Most of the time, the revision to which the working 1.1939 + directory is synced (usually the tip) already exhibits the 1.1940 + problem introduced by the buggy change, so we'll mark it as 1.1941 + <quote>bad</quote>.</para> 1.1942 + 1.1943 + &interaction.bisect.search.bad-init; 1.1944 + 1.1945 + <para id="x_141">Our next task is to nominate a changeset that we know 1.1946 + <emphasis>doesn't</emphasis> have the bug; the <command 1.1947 + role="hg-cmd">hg bisect</command> command will 1.1948 + <quote>bracket</quote> its search between the first pair of 1.1949 + good and bad changesets. In our case, we know that revision 1.1950 + 10 didn't have the bug. (I'll have more words about choosing 1.1951 + the first <quote>good</quote> changeset later.)</para> 1.1952 + 1.1953 + &interaction.bisect.search.good-init; 1.1954 + 1.1955 + <para id="x_142">Notice that this command printed some output.</para> 1.1956 + <itemizedlist> 1.1957 + <listitem><para id="x_143">It told us how many changesets it must 1.1958 + consider before it can identify the one that introduced 1.1959 + the bug, and how many tests that will require.</para> 1.1960 + </listitem> 1.1961 + <listitem><para id="x_144">It updated the working directory to the next 1.1962 + changeset to test, and told us which changeset it's 1.1963 + testing.</para> 1.1964 + </listitem></itemizedlist> 1.1965 + 1.1966 + <para id="x_145">We now run our test in the working directory. We use the 1.1967 + <command>grep</command> command to see if our 1.1968 + <quote>bad</quote> file is present in the working directory. 1.1969 + If it is, this revision is bad; if not, this revision is good. 1.1970 + &interaction.bisect.search.step1;</para> 1.1971 + 1.1972 + <para id="x_146">This test looks like a perfect candidate for automation, 1.1973 + so let's turn it into a shell function.</para> 1.1974 + &interaction.bisect.search.mytest; 1.1975 + 1.1976 + <para id="x_147">We can now run an entire test step with a single command, 1.1977 + <literal>mytest</literal>.</para> 1.1978 + 1.1979 + &interaction.bisect.search.step2; 1.1980 + 1.1981 + <para id="x_148">A few more invocations of our canned test step command, 1.1982 + and we're done.</para> 1.1983 + 1.1984 + &interaction.bisect.search.rest; 1.1985 + 1.1986 + <para id="x_149">Even though we had 40 changesets to search through, the 1.1987 + <command role="hg-cmd">hg bisect</command> command let us find 1.1988 + the changeset that introduced our <quote>bug</quote> with only 1.1989 + five tests. Because the number of tests that the <command 1.1990 + role="hg-cmd">hg bisect</command> command performs grows 1.1991 + logarithmically with the number of changesets to search, the 1.1992 + advantage that it has over the <quote>brute force</quote> 1.1993 + search approach increases with every changeset you add.</para> 1.1994 + 1.1995 + </sect2> 1.1996 + <sect2> 1.1997 + <title>Cleaning up after your search</title> 1.1998 + 1.1999 + <para id="x_14a">When you're finished using the <command role="hg-cmd">hg 1.2000 + bisect</command> command in a repository, you can use the 1.2001 + <command role="hg-cmd">hg bisect --reset</command> command to 1.2002 + drop the information it was using to drive your search. The 1.2003 + command doesn't use much space, so it doesn't matter if you 1.2004 + forget to run this command. However, <command 1.2005 + role="hg-cmd">hg bisect</command> won't let you start a new 1.2006 + search in that repository until you do a <command 1.2007 + role="hg-cmd">hg bisect --reset</command>.</para> 1.2008 + 1.2009 + &interaction.bisect.search.reset; 1.2010 + 1.2011 + </sect2> 1.2012 + </sect1> 1.2013 + <sect1> 1.2014 + <title>Tips for finding bugs effectively</title> 1.2015 + 1.2016 + <sect2> 1.2017 + <title>Give consistent input</title> 1.2018 + 1.2019 + <para id="x_14b">The <command role="hg-cmd">hg bisect</command> command 1.2020 + requires that you correctly report the result of every test 1.2021 + you perform. If you tell it that a test failed when it really 1.2022 + succeeded, it <emphasis>might</emphasis> be able to detect the 1.2023 + inconsistency. If it can identify an inconsistency in your 1.2024 + reports, it will tell you that a particular changeset is both 1.2025 + good and bad. However, it can't do this perfectly; it's about 1.2026 + as likely to report the wrong changeset as the source of the 1.2027 + bug.</para> 1.2028 + 1.2029 + </sect2> 1.2030 + <sect2> 1.2031 + <title>Automate as much as possible</title> 1.2032 + 1.2033 + <para id="x_14c">When I started using the <command role="hg-cmd">hg 1.2034 + bisect</command> command, I tried a few times to run my 1.2035 + tests by hand, on the command line. This is an approach that 1.2036 + I, at least, am not suited to. After a few tries, I found 1.2037 + that I was making enough mistakes that I was having to restart 1.2038 + my searches several times before finally getting correct 1.2039 + results.</para> 1.2040 + 1.2041 + <para id="x_14d">My initial problems with driving the <command 1.2042 + role="hg-cmd">hg bisect</command> command by hand occurred 1.2043 + even with simple searches on small repositories; if the 1.2044 + problem you're looking for is more subtle, or the number of 1.2045 + tests that <command role="hg-cmd">hg bisect</command> must 1.2046 + perform increases, the likelihood of operator error ruining 1.2047 + the search is much higher. Once I started automating my 1.2048 + tests, I had much better results.</para> 1.2049 + 1.2050 + <para id="x_14e">The key to automated testing is twofold:</para> 1.2051 + <itemizedlist> 1.2052 + <listitem><para id="x_14f">always test for the same symptom, and</para> 1.2053 + </listitem> 1.2054 + <listitem><para id="x_150">always feed consistent input to the <command 1.2055 + role="hg-cmd">hg bisect</command> command.</para> 1.2056 + </listitem></itemizedlist> 1.2057 + <para id="x_151">In my tutorial example above, the <command>grep</command> 1.2058 + command tests for the symptom, and the <literal>if</literal> 1.2059 + statement takes the result of this check and ensures that we 1.2060 + always feed the same input to the <command role="hg-cmd">hg 1.2061 + bisect</command> command. The <literal>mytest</literal> 1.2062 + function marries these together in a reproducible way, so that 1.2063 + every test is uniform and consistent.</para> 1.2064 + 1.2065 + </sect2> 1.2066 + <sect2> 1.2067 + <title>Check your results</title> 1.2068 + 1.2069 + <para id="x_152">Because the output of a <command role="hg-cmd">hg 1.2070 + bisect</command> search is only as good as the input you 1.2071 + give it, don't take the changeset it reports as the absolute 1.2072 + truth. A simple way to cross-check its report is to manually 1.2073 + run your test at each of the following changesets:</para> 1.2074 + <itemizedlist> 1.2075 + <listitem><para id="x_153">The changeset that it reports as the first bad 1.2076 + revision. Your test should still report this as 1.2077 + bad.</para> 1.2078 + </listitem> 1.2079 + <listitem><para id="x_154">The parent of that changeset (either parent, 1.2080 + if it's a merge). Your test should report this changeset 1.2081 + as good.</para> 1.2082 + </listitem> 1.2083 + <listitem><para id="x_155">A child of that changeset. Your test should 1.2084 + report this changeset as bad.</para> 1.2085 + </listitem></itemizedlist> 1.2086 + 1.2087 + </sect2> 1.2088 + <sect2> 1.2089 + <title>Beware interference between bugs</title> 1.2090 + 1.2091 + <para id="x_156">It's possible that your search for one bug could be 1.2092 + disrupted by the presence of another. For example, let's say 1.2093 + your software crashes at revision 100, and worked correctly at 1.2094 + revision 50. Unknown to you, someone else introduced a 1.2095 + different crashing bug at revision 60, and fixed it at 1.2096 + revision 80. This could distort your results in one of 1.2097 + several ways.</para> 1.2098 + 1.2099 + <para id="x_157">It is possible that this other bug completely 1.2100 + <quote>masks</quote> yours, which is to say that it occurs 1.2101 + before your bug has a chance to manifest itself. If you can't 1.2102 + avoid that other bug (for example, it prevents your project 1.2103 + from building), and so can't tell whether your bug is present 1.2104 + in a particular changeset, the <command role="hg-cmd">hg 1.2105 + bisect</command> command cannot help you directly. Instead, 1.2106 + you can mark a changeset as untested by running <command 1.2107 + role="hg-cmd">hg bisect --skip</command>.</para> 1.2108 + 1.2109 + <para id="x_158">A different problem could arise if your test for a bug's 1.2110 + presence is not specific enough. If you check for <quote>my 1.2111 + program crashes</quote>, then both your crashing bug and an 1.2112 + unrelated crashing bug that masks it will look like the same 1.2113 + thing, and mislead <command role="hg-cmd">hg 1.2114 + bisect</command>.</para> 1.2115 + 1.2116 + <para id="x_159">Another useful situation in which to use <command 1.2117 + role="hg-cmd">hg bisect --skip</command> is if you can't 1.2118 + test a revision because your project was in a broken and hence 1.2119 + untestable state at that revision, perhaps because someone 1.2120 + checked in a change that prevented the project from 1.2121 + building.</para> 1.2122 + 1.2123 + </sect2> 1.2124 + <sect2> 1.2125 + <title>Bracket your search lazily</title> 1.2126 + 1.2127 + <para id="x_15a">Choosing the first <quote>good</quote> and 1.2128 + <quote>bad</quote> changesets that will mark the end points of 1.2129 + your search is often easy, but it bears a little discussion 1.2130 + nevertheless. From the perspective of <command 1.2131 + role="hg-cmd">hg bisect</command>, the <quote>newest</quote> 1.2132 + changeset is conventionally <quote>bad</quote>, and the older 1.2133 + changeset is <quote>good</quote>.</para> 1.2134 + 1.2135 + <para id="x_15b">If you're having trouble remembering when a suitable 1.2136 + <quote>good</quote> change was, so that you can tell <command 1.2137 + role="hg-cmd">hg bisect</command>, you could do worse than 1.2138 + testing changesets at random. Just remember to eliminate 1.2139 + contenders that can't possibly exhibit the bug (perhaps 1.2140 + because the feature with the bug isn't present yet) and those 1.2141 + where another problem masks the bug (as I discussed 1.2142 + above).</para> 1.2143 + 1.2144 + <para id="x_15c">Even if you end up <quote>early</quote> by thousands of 1.2145 + changesets or months of history, you will only add a handful 1.2146 + of tests to the total number that <command role="hg-cmd">hg 1.2147 + bisect</command> must perform, thanks to its logarithmic 1.2148 + behavior.</para> 1.2149 + 1.2150 + </sect2> 1.2151 + </sect1> 1.2152 </chapter> 1.2153 1.2154 <!-- 1.2155 local variables: 1.2156 sgml-parent-document: ("00book.xml" "book" "chapter") 1.2157 end: 1.2158 ---> 1.2159 \ No newline at end of file 1.2160 +-->