Mercurial > hgbook
changeset 282:7a6bd93174bd
Update bisect docs
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Mon, 31 Dec 2007 20:06:58 -0800 |
parents | a880d07f2d29 |
children | 4ed483f08e33 |
files | en/examples/bisect en/examples/bisect.commits.out en/examples/bisect.help.out en/examples/bisect.init.out en/examples/bisect.search.bad-init.out en/examples/bisect.search.good-init.out en/examples/bisect.search.init.out en/examples/bisect.search.reset.out en/examples/bisect.search.rest.out en/examples/bisect.search.step1.out en/examples/bisect.search.step2.out en/hgext.tex en/mq.tex en/undo.tex |
diffstat | 14 files changed, 131 insertions(+), 81 deletions(-) [+] |
line wrap: on
line diff
--- a/en/examples/bisect Mon Dec 17 23:16:59 2007 -0500 +++ b/en/examples/bisect Mon Dec 31 20:06:58 2007 -0800 @@ -30,19 +30,18 @@ #$ name: help hg help bisect -hg bisect help #$ name: search.init -hg bisect init +hg bisect --init #$ name: search.bad-init -hg bisect bad +hg bisect --bad #$ name: search.good-init -hg bisect good 10 +hg bisect --good 10 #$ name: search.step1 @@ -54,7 +53,7 @@ fi echo this revision is $result -hg bisect $result +hg bisect --$result #$ name: search.mytest @@ -67,7 +66,7 @@ fi echo this revision is $result - hg bisect $result + hg bisect --$result } #$ name: search.step2 @@ -82,7 +81,7 @@ #$ name: search.reset -hg bisect reset +hg bisect --reset #$ name:
--- a/en/examples/bisect.commits.out Mon Dec 17 23:16:59 2007 -0500 +++ b/en/examples/bisect.commits.out Mon Dec 31 20:06:58 2007 -0800 @@ -1,3 +1,16 @@ + + + + + + + + + + + + + @@ -8,3 +21,25 @@ + + + + + + + + + + + + + + + + + + + + + +
--- a/en/examples/bisect.help.out Mon Dec 17 23:16:59 2007 -0500 +++ b/en/examples/bisect.help.out Mon Dec 31 20:06:58 2007 -0800 @@ -24,6 +24,3 @@ - - -
--- a/en/examples/bisect.init.out Mon Dec 17 23:16:59 2007 -0500 +++ b/en/examples/bisect.init.out Mon Dec 31 20:06:58 2007 -0800 @@ -1,2 +1,3 @@ +
--- a/en/examples/bisect.search.bad-init.out Mon Dec 17 23:16:59 2007 -0500 +++ b/en/examples/bisect.search.bad-init.out Mon Dec 31 20:06:58 2007 -0800 @@ -1,1 +1,2 @@ +
--- a/en/examples/bisect.search.good-init.out Mon Dec 17 23:16:59 2007 -0500 +++ b/en/examples/bisect.search.good-init.out Mon Dec 31 20:06:58 2007 -0800 @@ -1,3 +1,4 @@ +
--- a/en/examples/bisect.search.init.out Mon Dec 17 23:16:59 2007 -0500 +++ b/en/examples/bisect.search.init.out Mon Dec 31 20:06:58 2007 -0800 @@ -1,3 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + +
--- a/en/examples/bisect.search.reset.out Mon Dec 17 23:16:59 2007 -0500 +++ b/en/examples/bisect.search.reset.out Mon Dec 31 20:06:58 2007 -0800 @@ -1,1 +1,2 @@ +
--- a/en/examples/bisect.search.rest.out Mon Dec 17 23:16:59 2007 -0500 +++ b/en/examples/bisect.search.rest.out Mon Dec 31 20:06:58 2007 -0800 @@ -14,3 +14,6 @@ + + +
--- a/en/examples/bisect.search.step1.out Mon Dec 17 23:16:59 2007 -0500 +++ b/en/examples/bisect.search.step1.out Mon Dec 31 20:06:58 2007 -0800 @@ -9,3 +9,4 @@ +
--- a/en/examples/bisect.search.step2.out Mon Dec 17 23:16:59 2007 -0500 +++ b/en/examples/bisect.search.step2.out Mon Dec 31 20:06:58 2007 -0800 @@ -2,3 +2,4 @@ +
--- a/en/hgext.tex Mon Dec 17 23:16:59 2007 -0500 +++ b/en/hgext.tex Mon Dec 31 20:06:58 2007 -0800 @@ -14,9 +14,6 @@ \item Section~\ref{sec:tour-merge:fetch} covers the \hgext{fetch} extension; this combines pulling new changes and merging them with local changes into a single command, \hgxcmd{fetch}{fetch}. -\item The \hgext{bisect} extension adds an efficient pruning search - for changes that introduced bugs, and we documented it in - chapter~\ref{sec:undo:bisect}. \item In chapter~\ref{chap:hook}, we covered several extensions that are useful for hook-related functionality: \hgext{acl} adds access control lists; \hgext{bugzilla} adds integration with the Bugzilla
--- a/en/mq.tex Mon Dec 17 23:16:59 2007 -0500 +++ b/en/mq.tex Mon Dec 31 20:06:58 2007 -0800 @@ -146,7 +146,7 @@ interplay with the code they're based on---\emph{enormously} easier. Since every applied patch has an associated changeset, you can use \hgcmdargs{log}{\emph{filename}} to see which changesets and patches -affected a file. You can use the \hgext{bisect} extension to +affected a file. You can use the \hgext{bisect} command to binary-search through all changesets and applied patches to see where a bug got introduced or fixed. You can use the \hgcmd{annotate} command to see which changeset or patch modified a particular line of
--- a/en/undo.tex Mon Dec 17 23:16:59 2007 -0500 +++ b/en/undo.tex Mon Dec 31 20:06:58 2007 -0800 @@ -482,19 +482,19 @@ While it's all very well to be able to back out a changeset that introduced a bug, this requires that you know which changeset to back -out. Mercurial provides an invaluable extension, called -\hgext{bisect}, that helps you to automate this process and accomplish +out. Mercurial provides an invaluable command, called +\hgcmd{bisect}, that helps you to automate this process and accomplish it very efficiently. -The idea behind the \hgext{bisect} extension is that a changeset has +The idea behind the \hgcmd{bisect} command is that a changeset has introduced some change of behaviour that you can identify with a simple binary test. You don't know which piece of code introduced the change, but you know how to test for the presence of the bug. The -\hgext{bisect} extension uses your test to direct its search for the +\hgcmd{bisect} command uses your test to direct its search for the changeset that introduced the code that caused the bug. -Here are a few scenarios to help you understand how you might apply this -extension. +Here are a few scenarios to help you understand how you might apply +this command. \begin{itemize} \item The most recent version of your software has a bug that you remember wasn't present a few weeks ago, but you don't know when it @@ -515,8 +515,8 @@ you build your project. \end{itemize} -From these examples, it should be clear that the \hgext{bisect} -extension is not useful only for finding the sources of bugs. You can +From these examples, it should be clear that the \hgcmd{bisect} +command is not useful only for finding the sources of bugs. You can use it to find any ``emergent property'' of a repository (anything that you can't find from a simple text search of the files in the tree) for which you can write a binary test. @@ -524,10 +524,10 @@ We'll introduce a little bit of terminology here, just to make it clear which parts of the search process are your responsibility, and which are Mercurial's. A \emph{test} is something that \emph{you} run -when \hgext{bisect} chooses a changeset. A \emph{probe} is what -\hgext{bisect} runs to tell whether a revision is good. Finally, +when \hgcmd{bisect} chooses a changeset. A \emph{probe} is what +\hgcmd{bisect} runs to tell whether a revision is good. Finally, we'll use the word ``bisect'', as both a noun and a verb, to stand in -for the phrase ``search using the \hgext{bisect} extension''. +for the phrase ``search using the \hgcmd{bisect} command. One simple way to automate the searching process would be simply to probe every changeset. However, this scales poorly. If it took ten @@ -538,47 +538,33 @@ and limited your search to those, you'd still be looking at over 40 hours to find the changeset that introduced your bug. -What the \emph{bisect} extension does is use its knowledge of the +What the \hgcmd{bisect} command does is use its knowledge of the ``shape'' of your project's revision history to perform a search in time proportional to the \emph{logarithm} of the number of changesets to check (the kind of search it performs is called a dichotomic search). With this approach, searching through 10,000 changesets will -take less than two hours, even at ten minutes per test. Limit your -search to the last 500 changesets, and it will take less than an hour. +take less than three hours, even at ten minutes per test (the search +will require about 14 tests). Limit your search to the last hundred +changesets, and it will take only about an hour (roughly seven tests). -The \hgext{bisect} extension is aware of the ``branchy'' nature of a +The \hgcmd{bisect} command is aware of the ``branchy'' nature of a Mercurial project's revision history, so it has no problems dealing with branches, merges, or multiple heads in a repoository. It can prune entire branches of history with a single probe, which is how it operates so efficiently. -\subsection{Using the \hgext{bisect} extension} +\subsection{Using the \hgcmd{bisect} command} + +Here's an example of \hgcmd{bisect} in action. -Here's an example of \hgext{bisect} in action. To keep the core of -Mercurial simple, \hgext{bisect} is packaged as an extension; this -means that it won't be present unless you explicitly enable it. To do -this, edit your \hgrc\ and add the following section header (if it's -not already present): -\begin{codesample2} - [extensions] -\end{codesample2} -Then add a line to this section to enable the extension: -\begin{codesample2} - hbisect = -\end{codesample2} \begin{note} - That's right, there's a ``\texttt{h}'' at the front of the name of - the \hgext{bisect} extension. The reason is that Mercurial is - written in Python, and uses a standard Python package called - \texttt{bisect}. If you omit the ``\texttt{h}'' from the name - ``\texttt{hbisect}'', Mercurial will erroneously find the standard - Python \texttt{bisect} package, and try to use it as a Mercurial - extension. This won't work, and Mercurial will crash repeatedly - until you fix the spelling in your \hgrc. Ugh. + In versions 0.9.5 and earlier of Mercurial, \hgcmd{bisect} was not a + core command: it was distributed with Mercurial as an extension. + This section describes the built-in command, not the old extension. \end{note} Now let's create a repository, so that we can try out the -\hgext{bisect} extension in isolation. +\hgcmd{bisect} command in isolation. \interaction{bisect.init} We'll simulate a project that has a bug in it in a simple-minded way: create trivial changes in a loop, and nominate one specific change @@ -588,29 +574,28 @@ \interaction{bisect.commits} The next thing that we'd like to do is figure out how to use the -\hgext{bisect} extension. We can use Mercurial's normal built-in help +\hgcmd{bisect} command. We can use Mercurial's normal built-in help mechanism for this. \interaction{bisect.help} -The \hgext{bisect} extension works in steps. Each step proceeds as follows. +The \hgcmd{bisect} command works in steps. Each step proceeds as follows. \begin{enumerate} \item You run your binary test. \begin{itemize} - \item If the test succeeded, you tell \hgext{bisect} by running the + \item If the test succeeded, you tell \hgcmd{bisect} by running the \hgcmdargs{bisect}{good} command. - \item If it failed, use the \hgcmdargs{bisect}{bad} command to let - the \hgext{bisect} extension know. + \item If it failed, run the \hgcmdargs{bisect}{--bad} command. \end{itemize} -\item The extension uses your information to decide which changeset to +\item The command uses your information to decide which changeset to test next. \item It updates the working directory to that changeset, and the process begins again. \end{enumerate} -The process ends when \hgext{bisect} identifies a unique changeset +The process ends when \hgcmd{bisect} identifies a unique changeset that marks the point where your test transitioned from ``succeeding'' to ``failing''. -To start the search, we must run the \hgcmdargs{bisect}{init} command. +To start the search, we must run the \hgcmdargs{bisect}{--reset} command. \interaction{bisect.search.init} In our case, the binary test we use is simple: we check to see if any @@ -625,7 +610,7 @@ \interaction{bisect.search.bad-init} Our next task is to nominate a changeset that we know \emph{doesn't} -have the bug; the \hgext{bisect} extension will ``bracket'' its search +have the bug; the \hgcmd{bisect} command will ``bracket'' its search between the first pair of good and bad changesets. In our case, we know that revision~10 didn't have the bug. (I'll have more words about choosing the first ``good'' changeset later.) @@ -656,20 +641,20 @@ done. \interaction{bisect.search.rest} -Even though we had~40 changesets to search through, the \hgext{bisect} -extension let us find the changeset that introduced our ``bug'' with -only five tests. Because the number of tests that the \hgext{bisect} -extension grows logarithmically with the number of changesets to +Even though we had~40 changesets to search through, the \hgcmd{bisect} +command let us find the changeset that introduced our ``bug'' with +only five tests. Because the number of tests that the \hgcmd{bisect} +command grows logarithmically with the number of changesets to search, the advantage that it has over the ``brute force'' search approach increases with every changeset you add. \subsection{Cleaning up after your search} -When you're finished using the \hgext{bisect} extension in a +When you're finished using the \hgcmd{bisect} command in a repository, you can use the \hgcmdargs{bisect}{reset} command to drop -the information it was using to drive your search. The extension +the information it was using to drive your search. The command doesn't use much space, so it doesn't matter if you forget to run this -command. However, \hgext{bisect} won't let you start a new search in +command. However, \hgcmd{bisect} won't let you start a new search in that repository until you do a \hgcmdargs{bisect}{reset}. \interaction{bisect.search.reset} @@ -677,7 +662,7 @@ \subsection{Give consistent input} -The \hgext{bisect} extension requires that you correctly report the +The \hgcmd{bisect} command requires that you correctly report the result of every test you perform. If you tell it that a test failed when it really succeeded, it \emph{might} be able to detect the inconsistency. If it can identify an inconsistency in your reports, @@ -687,16 +672,16 @@ \subsection{Automate as much as possible} -When I started using the \hgext{bisect} extension, I tried a few times +When I started using the \hgcmd{bisect} command, I tried a few times to run my tests by hand, on the command line. This is an approach that I, at least, am not suited to. After a few tries, I found that I was making enough mistakes that I was having to restart my searches -several times before finally getting correct results. +several times before finally getting correct results. -My initial problems with driving the \hgext{bisect} extension by hand +My initial problems with driving the \hgcmd{bisect} command by hand occurred even with simple searches on small repositories; if the problem you're looking for is more subtle, or the number of tests that -\hgext{bisect} must perform increases, the likelihood of operator +\hgcmd{bisect} must perform increases, the likelihood of operator error ruining the search is much higher. Once I started automating my tests, I had much better results. @@ -713,7 +698,7 @@ \subsection{Check your results} -Because the output of a \hgext{bisect} search is only as good as the +Because the output of a \hgcmd{bisect} search is only as good as the input you give it, don't take the changeset it reports as the absolute truth. A simple way to cross-check its report is to manually run your test at each of the following changesets: @@ -739,26 +724,30 @@ is to say that it occurs before your bug has a chance to manifest itself. If you can't avoid that other bug (for example, it prevents your project from building), and so can't tell whether your bug is -present in a particular changeset, the \hgext{bisect} extension cannot -help you directly. Instead, you'll need to manually avoid the -changesets where that bug is present, and do separate searches -``around'' it. +present in a particular changeset, the \hgcmd{bisect} command cannot +help you directly. Instead, you can mark a changeset as untested by +running \hgcmdargs{bisect}{--skip}. A different problem could arise if your test for a bug's presence is not specific enough. If you check for ``my program crashes'', then both your crashing bug and an unrelated crashing bug that masks it -will look like the same thing, and mislead \hgext{bisect}. +will look like the same thing, and mislead \hgcmd{bisect}. + +Another useful situation in which to use \hgcmdargs{bisect}{--skip} is +if you can't test a revision because your project was in a broken and +hence untestable state at that revision, perhaps because someone +checked in a change that prevented the project from building. \subsection{Bracket your search lazily} Choosing the first ``good'' and ``bad'' changesets that will mark the end points of your search is often easy, but it bears a little -discussion nevertheless. From the perspective of \hgext{bisect}, the +discussion nevertheless. From the perspective of \hgcmd{bisect}, the ``newest'' changeset is conventionally ``bad'', and the older changeset is ``good''. If you're having trouble remembering when a suitable ``good'' change -was, so that you can tell \hgext{bisect}, you could do worse than +was, so that you can tell \hgcmd{bisect}, you could do worse than testing changesets at random. Just remember to eliminate contenders that can't possibly exhibit the bug (perhaps because the feature with the bug isn't present yet) and those where another problem masks the @@ -766,7 +755,7 @@ Even if you end up ``early'' by thousands of changesets or months of history, you will only add a handful of tests to the total number that -\hgext{bisect} must perform, thanks to its logarithmic behaviour. +\hgcmd{bisect} must perform, thanks to its logarithmic behaviour. %%% Local Variables: %%% mode: latex