[PATCH 1 of 1 Report bisect status] bisect: print current state of the bisection

Yann E. MORIN yann.morin.1998 at anciens.enib.fr
Thu Sep 15 11:56:05 CDT 2011


 mercurial/commands.py |  57 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 53 insertions(+), 4 deletions(-)


# HG changeset patch
# User "Yann E. MORIN" <yann.morin.1998 at anciens.enib.fr>
# Date 1316105758 -7200
# Node ID 1538635da29a21230eff455150c1a2b166f2375a
# Parent  edf7ae547b0e475936831fb8459c850d13b2d310
bisect: print current state of the bisection

When bisecting on wide ranges, and/or when the test command takes
a long time to run, the terminal history may get full, and it is
not possible to remember/recover what the current status of the
bisection is.

This patch adds a new option to the bisect command, --status, that
prints the current status of the bisection, and takes an argument, the
type of status to report. This patch implements two types of reports:

  'brief'   reports the last known good, current, and first known
            bad changesets
  'full'    reports all changesets between and including the first
            known good until the last kbnown bad

The output looks pretty much like the output of the 'log' command,
with a added information about the state of the changeset:
    changeset       --quiet     default or --verbose
    is:             prefix      preceding line
    ------------------------------------------------
    good            +           Good
    bad             -           Bad
    skipped         !           Skipped
    current         >           Current
    other          ' '(space)   Unknown

Signed-off-by: "Yann E. MORIN" <yann.morin.1998 at anciens.enib.fr>

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -464,11 +464,12 @@
     ('s', 'skip', False, _('skip testing changeset')),
     ('e', 'extend', False, _('extend the bisect range')),
     ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
-    ('U', 'noupdate', False, _('do not update to target'))],
-    _("[-gbsr] [-U] [-c CMD] [REV]"))
+    ('U', 'noupdate', False, _('do not update to target')),
+    ('S', 'status', '', _('print bisection status'), _('TYPE'))],
+    _("[-gbsr] [-S [TYPE]] [-U] [-c CMD] [REV]"))
 def bisect(ui, repo, rev=None, extra=None, command=None,
                reset=None, good=None, bad=None, skip=None, extend=None,
-               noupdate=None):
+               noupdate=None, status=None):
     """subdivision search of changesets
 
     This command helps to find changesets which introduce problems. To
@@ -489,6 +490,14 @@
     (command not found) will abort the bisection, and any other
     non-zero exit status means the revision is bad.
 
+    You can see the current status of the bisection (with --status),
+    either a single-line (with --quiet), the full log (with --verbose),
+    or the normal log (with neither), for each affected changesets of
+    the specified type:
+
+      - brief       last good, current, first bad changesets
+      - full        from first good to last bad changesets
+
     Returns 0 on success.
     """
     def extendbisectrange(nodes, good):
@@ -549,7 +558,7 @@
             bad = True
         else:
             reset = True
-    elif extra or good + bad + skip + reset + extend + bool(command) > 1:
+    elif extra or good + bad + skip + reset + extend + bool(command) + bool(status) > 1:
         raise util.Abort(_('incompatible arguments'))
 
     if reset:
@@ -560,6 +569,46 @@
 
     state = hbisect.load_state(repo)
 
+    if status:
+        def report(ui, repo, ctx):
+            if   ctx.node() in state['good']:
+                prefix, msg = '+',_('Good')
+            elif ctx.node() in state['bad']:
+                prefix, msg = '-',_('Bad')
+            elif ctx.node() in state['skip']:
+                prefix, msg = '!',_('Skipped')
+            elif ctx.node() == repo.lookup('.'):
+                prefix, msg = '>',_('Current')
+            else:
+                prefix, msg = ' ', _('Unknown')
+            if ui.verbose or not ui.quiet:
+                ui.write('%s:\n' % (msg) )
+                disp = cmdutil.show_changeset(ui, repo, {})
+                disp.show(repo[ctx.node()])
+                disp.close()
+            else:
+                ui.write(_('%s %d:%s: %s\n')
+                         % (prefix,
+                            ctx.rev(),
+                            short(ctx.node()),
+                            repo[ctx.node()].description().splitlines(True)[0].rstrip('\r\n')))
+
+        if status == 'brief':
+            gooditer = repo.set('max(bisected(good))')
+            report(ui, repo, gooditer.next())
+            currentiter = repo.set('.')
+            report(ui, repo, currentiter.next() )
+            baditer = repo.set('min(bisected(bad))')
+            report(ui, repo, baditer.next())
+        elif status == 'full':
+            iter = repo.set('min(bisected(good))::max(bisected(bad))')
+            for ctx in iter:
+                report(ui, repo, ctx)
+        else:
+            raise util.Abort(_('invalid status type: %s') % (status))
+
+        return
+
     if command:
         changesets = 1
         try:


More information about the Mercurial-devel mailing list