revset.bisect: add new 'range' set to the bisect keyword
author"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sat, 17 Sep 2011 17:33:34 +0200
changeset 15136 18219c0789ae
parent 15135 f19de58af225
child 15137 91f93dcd72aa
revset.bisect: add new 'range' set to the bisect keyword The 'range' set is made of all changesets that make the bisection range, that is - csets that are ancestors of bad csets and descendants of good csets or - csets that are ancestors of good csets and descendants of bad csets That is, roughly equivalent of: bisect(good)::bisect(bad) | bisect(bad)::bisect(good) Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
mercurial/hbisect.py
mercurial/revset.py
tests/test-bisect2.t
--- a/mercurial/hbisect.py	Sat Sep 17 00:20:45 2011 +0200
+++ b/mercurial/hbisect.py	Sat Sep 17 17:33:34 2011 +0200
@@ -159,9 +159,37 @@
     Return a list of revision(s) that match the given status:
 
     - ``good``, ``bad``, ``skip``: as the names imply
+    - ``range``              : all csets taking part in the bisection
     """
     state = load_state(repo)
     if status in ('good', 'bad', 'skip'):
         return [repo.changelog.rev(n) for n in state[status]]
     else:
-        raise error.ParseError(_('invalid bisect state'))
+        # Build sets of good, bad, and skipped csets
+        goods = set(repo.changelog.rev(n) for n in state['good'])
+        bads  = set(repo.changelog.rev(n) for n in state['bad'])
+        skips = set(repo.changelog.rev(n) for n in state['skip'])
+
+        # Build kinship of good csets
+        ga = goods.copy()   # Goods' Ancestors
+        gd = goods.copy()   # Goods' Descendants
+        for g in goods:
+            ga |= set(repo.changelog.ancestors(g))
+            gd |= set(repo.changelog.descendants(g))
+
+        # Build kinship of bad csets
+        ba = bads.copy()    # Bads' Ancestors
+        bd = bads.copy()    # Bads' Descendants
+        for b in bads:
+            ba |= set(repo.changelog.ancestors(b))
+            bd |= set(repo.changelog.descendants(b))
+
+        # Build the range of the bisection
+        range  = set(c for c in ba if c in gd)
+        range |= set(c for c in ga if c in bd)
+
+        if status == 'range':
+            return [c for c in range]
+
+        else:
+            raise error.ParseError(_('invalid bisect state'))
--- a/mercurial/revset.py	Sat Sep 17 00:20:45 2011 +0200
+++ b/mercurial/revset.py	Sat Sep 17 17:33:34 2011 +0200
@@ -237,7 +237,10 @@
 
 def bisect(repo, subset, x):
     """``bisect(string)``
-    Changesets marked in the specified bisect status (good, bad, skip).
+    Changesets marked in the specified bisect status (``good``, ``bad``,
+    ``skip``), or any of the meta-status:
+
+    - ``range``      : all csets taking part in the bisection
     """
     status = getstring(x, _("bisect requires a string")).lower()
     return [r for r in subset if r in hbisect.get(repo, status)]
--- a/tests/test-bisect2.t	Sat Sep 17 00:20:45 2011 +0200
+++ b/tests/test-bisect2.t	Sat Sep 17 17:33:34 2011 +0200
@@ -271,6 +271,23 @@
   date:        Thu Jan 01 00:00:09 1970 +0000
   summary:     9
   
+  $ hg log -q -r 'bisect(range)'
+  0:33b1f9bc8bc5
+  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
+  17:228c06deef46
 
 complex bisect test 2  # first good rev is 13
 
@@ -295,6 +312,21 @@
   date:        Thu Jan 01 00:00:13 1970 +0000
   summary:     13
   
+  $ hg log -q -r 'bisect(range)'
+  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
+  18:d42e18c7bc9b
 
 complex bisect test 3
 
@@ -347,6 +379,21 @@
   date:        Thu Jan 01 00:00:15 1970 +0000
   summary:     merge 10,13
   
+  $ hg log -q -r 'bisect(range)'
+  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
 
 complex bisect test 4
 
@@ -386,6 +433,16 @@
   date:        Thu Jan 01 00:00:17 1970 +0000
   summary:     17
   
+  $ hg log -q -r 'bisect(range)'
+  8:dab8161ac8fc
+  9:3c77083deb4a
+  10:429fcd26f52d
+  11:82ca6f06eccd
+  12:9f259202bbe7
+  13:b0a32c86eb31
+  15:857b178a7cf3
+  16:609d82a7ebae
+  17:228c06deef46
 
 test unrelated revs:
 
@@ -394,6 +451,7 @@
   $ hg bisect -g 14
   abort: starting revisions are not directly related
   [255]
+  $ hg log -q -r 'bisect(range)'
   $ hg bisect --reset
 
 end at merge: 17 bad, 11 good (but 9 is first bad)
@@ -418,6 +476,13 @@
   Not all ancestors of this changeset have been checked.
   Use bisect --extend to continue the bisection from
   the common ancestor, dab8161ac8fc.
+  $ hg log -q -r 'bisect(range)'
+  11:82ca6f06eccd
+  12:9f259202bbe7
+  13:b0a32c86eb31
+  15:857b178a7cf3
+  16:609d82a7ebae
+  17:228c06deef46
   $ hg bisect --extend
   Extending search to changeset 8:dab8161ac8fc
   2 files updated, 0 files merged, 2 files removed, 0 files unresolved
@@ -431,6 +496,16 @@
   date:        Thu Jan 01 00:00:09 1970 +0000
   summary:     9
   
+  $ hg log -q -r 'bisect(range)'
+  8:dab8161ac8fc
+  9:3c77083deb4a
+  10:429fcd26f52d
+  11:82ca6f06eccd
+  12:9f259202bbe7
+  13:b0a32c86eb31
+  15:857b178a7cf3
+  16:609d82a7ebae
+  17:228c06deef46
 
 user adds irrelevant but consistent information (here: -g 2) to bisect state
 
@@ -450,3 +525,8 @@
   date:        Thu Jan 01 00:00:11 1970 +0000
   summary:     11
   
+  $ hg log -q -r 'bisect(range)'
+  8:dab8161ac8fc
+  11:82ca6f06eccd
+  12:9f259202bbe7
+  13:b0a32c86eb31