[PATCH 3 of 3] revset.bisect: add 'remaining' set to the bisect keyword

Yann E. MORIN yann.morin.1998 at anciens.enib.fr
Mon Sep 19 18:16:24 CDT 2011


# HG changeset patch
# User "Yann E. MORIN" <yann.morin.1998 at anciens.enib.fr>
# Date 1316451994 -7200
# Node ID a39862781b27a7202e5830d7904d82dcca03ceb2
# Parent  d6a50317704015d90a28236e05f8a0ff02498cf0
revset.bisect: add 'remaining' set to the bisect keyword

The 'remaining' changesets are the 'untested' changesets that are
not both ancestors *and* descendant of any tow good changesets, or
any tow bad changesets.

It basically:
  bisected(untested) - ( goods::goods | bads::bads )

To be noted, is a little /glitch/ in the output, that is absolutely normal,
albeit maybe not what the user would expect:

 - take a subset of the DAG of test-bisect2.t as example:

                      16
                     /
                   15
                  /  \
                 /    \
               10     13
                 \     |
                  \    |
                   9  12
                   |   |
                   |  11
                   |  /
                   | /
                   |/
                   8

 - now suppose 8 is good, 16 is bad, and 13 is skipped;
   bisect updates to 10

 - now we mark 10 as bad; bisect updates to 9

 - again we mark 9 as bad; bisect will find that 9 is the first bad
   revision.

So, from the user's point of view, the bisection seems to be *finished*.

But the 'remaining' range will say that 11 and 12 are remaining. And when
one thinks about it, that's perfectly normal, because all we know is that
16 is bad and 8 is good, so the issue may come from either the left branch
or the right branch, or *both* branches from the merge in 15.

In the above, we know that 9 introduced an error. But nothing says that
11 or 12 did not introduce another (or the same) issue either.

But neither 11 nor 12 appear on the list of 'ignored' csets, because they
were *not* ignored. The branch point of the merge in 15 *is* in the range.

So, yes, the bisection is finished, *on one branch*. To be exhaustive,
11 and 12 should be tested as well. That's why they appear in the set
of 'remaining' csets, although the bisection appears to have completed
with a suspect.

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
@@ -547,6 +547,10 @@
 
           hg log --graph -r "bisect(range)"
 
+      - see all untested changesets that remain to be tested::
+
+          hg log -r "bisected(remaining)"
+
     Returns 0 on success.
     """
     def extendbisectrange(nodes, good):
diff --git a/mercurial/hbisect.py b/mercurial/hbisect.py
--- a/mercurial/hbisect.py
+++ b/mercurial/hbisect.py
@@ -162,6 +162,7 @@
     - ``range``              : all csets taking part in the bisection
     - ``pruned``             : good|bad|skip, excluding out-of-range csets
     - ``untested``           : csets whose fate is yet unknown
+    - ``remaining``          : remaining untested csets
     - ``ignored``            : csets ignored due to DAG topology
     """
     state = load_state(repo)
@@ -185,6 +186,15 @@
         elif status == 'untested':
             # Return the csets in range that are not pruned
             return [c for c in range if not c in (goods + bads + skips)]
+        elif status == 'remaining':
+            # Discard csets in goods::goods and in bads::bads ranges
+            # because the remaining bisection will not test for them
+            gr = [r.rev() for r in repo.set('%ld::%ld', goods, goods)]
+            br = [r.rev() for r in repo.set('%ld::%ld', bads, bads)]
+
+            # Return csets that are in range, but that are neither discarded,
+            # nor skipped
+            return [r for r in range if not r in (gr + br + skips)]
         elif status == 'ignored':
             # Ignored bad ancestors
             iba = [r.rev() for r in repo.set('::%ld - ::%ld', bads, goods)]
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -243,6 +243,7 @@
     - ``range``      : all csets taking part in the bisection
     - ``pruned``     : good|bad|skip, excluding out-of-range csets
     - ``untested``   : csets whose fate is yet unknown
+    - ``remaining``  : remaining untested csets
     - ``ignored``    : csets ignored by the bisection due to topology
     """
     status = getstring(x, _("bisect requires a string")).lower()
diff --git a/tests/test-bisect2.t b/tests/test-bisect2.t
--- a/tests/test-bisect2.t
+++ b/tests/test-bisect2.t
@@ -267,6 +267,21 @@
   13:b0a32c86eb31
   15:857b178a7cf3
   16:609d82a7ebae
+  $ hg log -q -r 'bisect(remaining)'
+  1:4ca5088da217
+  2:051e12f87bf1
+  3:0950834f0a9c
+  4:5c668c22234f
+  5:385a529b6670
+  6:a214d5d3811a
+  8:dab8161ac8fc
+  9:3c77083deb4a
+  10:429fcd26f52d
+  11:82ca6f06eccd
+  12:9f259202bbe7
+  13:b0a32c86eb31
+  15:857b178a7cf3
+  16:609d82a7ebae
   $ hg log -q -r 'bisect(ignored)'
   $ hg bisect -g      # -> update to rev 13
   Testing changeset 13:b0a32c86eb31 (9 changesets remaining, ~3 tests)
@@ -277,6 +292,11 @@
   $ hg bisect -b      # -> update to rev 8
   Testing changeset 8:dab8161ac8fc (3 changesets remaining, ~1 tests)
   2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg log -q -r 'bisect(remaining)'
+  8:dab8161ac8fc
+  9:3c77083deb4a
+  11:82ca6f06eccd
+  12:9f259202bbe7
   $ hg bisect -g      # -> update to rev 9
   Testing changeset 9:3c77083deb4a (2 changesets remaining, ~1 tests)
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -322,6 +342,9 @@
   12:9f259202bbe7
   15:857b178a7cf3
   16:609d82a7ebae
+  $ hg log -q -r 'bisect(remaining)'
+  11:82ca6f06eccd
+  12:9f259202bbe7
   $ hg log -q -r 'bisect(ignored)'
 
 complex bisect test 2  # first good rev is 13
@@ -351,6 +374,9 @@
   $ hg bisect -b      # -> update to rev 13
   Testing changeset 13:b0a32c86eb31 (3 changesets remaining, ~1 tests)
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg log -q -r 'bisect(remaining)'
+  13:b0a32c86eb31
+  15:857b178a7cf3
   $ hg bisect -g
   The first good revision is:
   changeset:   13:b0a32c86eb31
@@ -514,6 +540,7 @@
   15:857b178a7cf3
   16:609d82a7ebae
   17:228c06deef46
+  $ hg log -q -r 'bisect(remaining)'
 
 test unrelated revs:
 
@@ -579,6 +606,7 @@
   6:a214d5d3811a
   9:3c77083deb4a
   10:429fcd26f52d
+  $ hg log -q -r 'bisect(remaining)'
   $ hg bisect --extend
   Extending search to changeset 8:dab8161ac8fc
   2 files updated, 0 files merged, 2 files removed, 0 files unresolved
@@ -593,6 +621,7 @@
   6:a214d5d3811a
   9:3c77083deb4a
   10:429fcd26f52d
+  $ hg log -q -r 'bisect(remaining)'
   $ hg bisect -g # dab8161ac8fc
   Testing changeset 9:3c77083deb4a (3 changesets remaining, ~1 tests)
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -602,6 +631,9 @@
   4:5c668c22234f
   5:385a529b6670
   6:a214d5d3811a
+  $ hg log -q -r 'bisect(remaining)'
+  9:3c77083deb4a
+  10:429fcd26f52d
   $ hg bisect -b
   The first bad revision is:
   changeset:   9:3c77083deb4a
@@ -630,6 +662,7 @@
   10:429fcd26f52d
   12:9f259202bbe7
   16:609d82a7ebae
+  $ hg log -q -r 'bisect(remaining)'
 
 user adds irrelevant but consistent information (here: -g 2) to bisect state
 
@@ -641,12 +674,18 @@
   $ hg log -q -r 'bisect(untested)'
   11:82ca6f06eccd
   12:9f259202bbe7
+  $ hg log -q -r 'bisect(remaining)'
+  11:82ca6f06eccd
+  12:9f259202bbe7
   $ hg bisect -g 2
   Testing changeset 11:82ca6f06eccd (3 changesets remaining, ~1 tests)
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg log -q -r 'bisect(untested)'
   11:82ca6f06eccd
   12:9f259202bbe7
+  $ hg log -q -r 'bisect(remaining)'
+  11:82ca6f06eccd
+  12:9f259202bbe7
   $ hg bisect -b
   The first bad revision is:
   changeset:   11:82ca6f06eccd
@@ -666,3 +705,4 @@
   13:b0a32c86eb31
   $ hg log -q -r 'bisect(untested)'
   12:9f259202bbe7
+  $ hg log -q -r 'bisect(remaining)'


More information about the Mercurial-devel mailing list