diff --git a/mercurial/hbisect.py b/mercurial/hbisect.py --- a/mercurial/hbisect.py +++ b/mercurial/hbisect.py @@ -158,9 +158,10 @@ def get(repo, status): """ 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 - - ``pruned`` : csets that are good, bad or skipped + - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip + - ``goods``, ``bads`` : csets topologicaly good/bad + - ``range`` : csets taking part in the bisection + - ``pruned`` : csets that are goods, bads or skipped - ``untested`` : csets whose fate is yet unknown - ``ignored`` : csets ignored due to DAG topology """ @@ -178,16 +179,20 @@ def get(repo, status): # that's because the bisection can go either way range = '( bisect(bad)::bisect(good) | bisect(good)::bisect(bad) )' - # 'pruned' is all csets whose fate is already known: - # - a good ancestor and a good ascendant, or - # - a bad ancestor and a bad descendant, or - # - skipped - # But in case of irrelevant goods/bads, we also need to - # include them. - pg = 'bisect(good)::bisect(good)' # Pruned goods - pb = 'bisect(bad)::bisect(bad)' # Pruned bads - ps = 'bisect(skip)' # Pruned skipped - pruned = '( (%s) | (%s) | (%s) )' % (pg, pb, ps) + _t = [c.rev() for c in repo.set('bisect(good)::bisect(bad)')] + # The sets of topologically good or bad csets + if len(_t) == 0: + # Goods are topologically after bads + goods = 'bisect(good)::' # Pruned good csets + bads = '::bisect(bad)' # Pruned bad csets + else: + # Goods are topologically before bads + goods = '::bisect(good)' # Pruned good csets + bads = 'bisect(bad)::' # Pruned bad csets + + # 'pruned' is all csets whose fate is already known: good, bad, skip + skips = 'bisect(skip)' # Pruned skipped csets + pruned = '( (%s) | (%s) | (%s) )' % (goods, bads, skips) # 'untested' is all cset that are- in 'range', but not in 'pruned' untested = '( (%s) - (%s) )' % (range, pruned) @@ -208,6 +213,10 @@ def get(repo, status): return [c.rev() for c in repo.set(untested)] elif status == 'ignored': return [c.rev() for c in repo.set(ignored)] + elif status == "goods": + return [c.rev() for c in repo.set(goods)] + elif status == "bads": + return [c.rev() for c in repo.set(bads)] else: raise error.ParseError(_('invalid bisect state')) diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -237,13 +237,14 @@ def author(repo, subset, x): def bisect(repo, subset, x): """``bisect(string)`` - Changesets marked in the specified bisect status (``good``, ``bad``, - ``skip``), or any of the meta-status: + Changesets marked in the specified bisect status: - - ``range`` : all csets taking part in the bisection - - ``pruned`` : csets that are good, bad or skipped - - ``untested`` : csets whose fate is yet unknown - - ``ignored`` : csets ignored due to DAG topology + - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip + - ``goods``, ``bads`` : csets topologicaly good/bad + - ``range`` : csets taking part in the bisection + - ``pruned`` : csets that are goods, bads or skipped + - ``untested`` : csets whose fate is yet unknown + - ``ignored`` : csets ignored due to DAG topology """ status = getstring(x, _("bisect requires a string")).lower() return [r for r in subset if r in hbisect.get(repo, status)] diff --git a/tests/test-bisect2.t b/tests/test-bisect2.t --- a/tests/test-bisect2.t +++ b/tests/test-bisect2.t @@ -322,9 +322,26 @@ complex bisect test 1 # first bad rev i 15:857b178a7cf3 16:609d82a7ebae 17:228c06deef46 + 18:d42e18c7bc9b $ hg log -q -r 'bisect(untested)' 11:82ca6f06eccd 12:9f259202bbe7 + $ hg log -q -r 'bisect(goods)' + 0:33b1f9bc8bc5 + 1:4ca5088da217 + 2:051e12f87bf1 + 3:0950834f0a9c + 4:5c668c22234f + 5:385a529b6670 + 6:a214d5d3811a + 8:dab8161ac8fc + $ hg log -q -r 'bisect(bads)' + 9:3c77083deb4a + 10:429fcd26f52d + 15:857b178a7cf3 + 16:609d82a7ebae + 17:228c06deef46 + 18:d42e18c7bc9b complex bisect test 2 # first good rev is 13 @@ -337,6 +354,7 @@ complex bisect test 2 # first good rev Testing changeset 10:429fcd26f52d (13 changesets remaining, ~3 tests) 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg log -q -r 'bisect(pruned)' + 0:33b1f9bc8bc5 1:4ca5088da217 6:a214d5d3811a 18:d42e18c7bc9b @@ -344,6 +362,7 @@ complex bisect test 2 # first good rev Testing changeset 12:9f259202bbe7 (5 changesets remaining, ~2 tests) 3 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg log -q -r 'bisect(pruned)' + 0:33b1f9bc8bc5 1:4ca5088da217 2:051e12f87bf1 3:0950834f0a9c @@ -396,8 +415,10 @@ 10,9,13 are skipped an might be the firs Testing changeset 6:a214d5d3811a (13 changesets remaining, ~3 tests) 2 files updated, 0 files merged, 2 files removed, 0 files unresolved $ hg log -q -r 'bisect(pruned)' + 0:33b1f9bc8bc5 1:4ca5088da217 16:609d82a7ebae + 17:228c06deef46 $ hg bisect -g # -> update to rev 13 Testing changeset 13:b0a32c86eb31 (8 changesets remaining, ~3 tests) 3 files updated, 0 files merged, 1 files removed, 0 files unresolved @@ -408,6 +429,7 @@ 10,9,13 are skipped an might be the firs Testing changeset 12:9f259202bbe7 (8 changesets remaining, ~3 tests) 3 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg log -q -r 'bisect(pruned)' + 0:33b1f9bc8bc5 1:4ca5088da217 2:051e12f87bf1 3:0950834f0a9c @@ -417,6 +439,7 @@ 10,9,13 are skipped an might be the firs 10:429fcd26f52d 13:b0a32c86eb31 16:609d82a7ebae + 17:228c06deef46 $ hg bisect -g # -> update to rev 9 Testing changeset 9:3c77083deb4a (5 changesets remaining, ~2 tests) 1 files updated, 0 files merged, 1 files removed, 0 files unresolved @@ -484,6 +507,13 @@ 15,16 are skipped an might be the first Testing changeset 15:857b178a7cf3 (3 changesets remaining, ~1 tests) 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg log -q -r 'bisect(pruned)' + 0:33b1f9bc8bc5 + 1:4ca5088da217 + 2:051e12f87bf1 + 3:0950834f0a9c + 4:5c668c22234f + 5:385a529b6670 + 6:a214d5d3811a 8:dab8161ac8fc 9:3c77083deb4a 10:429fcd26f52d @@ -495,6 +525,13 @@ 15,16 are skipped an might be the first Testing changeset 16:609d82a7ebae (3 changesets remaining, ~1 tests) 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg log -q -r 'bisect(pruned)' + 0:33b1f9bc8bc5 + 1:4ca5088da217 + 2:051e12f87bf1 + 3:0950834f0a9c + 4:5c668c22234f + 5:385a529b6670 + 6:a214d5d3811a 8:dab8161ac8fc 9:3c77083deb4a 10:429fcd26f52d @@ -533,6 +570,13 @@ 15,16 are skipped an might be the first 16:609d82a7ebae 17:228c06deef46 $ hg log -q -r 'bisect(pruned)' + 0:33b1f9bc8bc5 + 1:4ca5088da217 + 2:051e12f87bf1 + 3:0950834f0a9c + 4:5c668c22234f + 5:385a529b6670 + 6:a214d5d3811a 8:dab8161ac8fc 9:3c77083deb4a 10:429fcd26f52d @@ -552,6 +596,11 @@ test unrelated revs: [255] $ hg log -q -r 'bisect(range)' $ hg log -q -r 'bisect(pruned)' + 0:33b1f9bc8bc5 + 1:4ca5088da217 + 2:051e12f87bf1 + 3:0950834f0a9c + 4:5c668c22234f 7:50c76098bbf2 14:faa450606157 $ hg bisect --reset @@ -594,12 +643,16 @@ end at merge: 17 bad, 11 good (but 9 is 16:609d82a7ebae 17:228c06deef46 $ hg log -q -r 'bisect(pruned)' + 0:33b1f9bc8bc5 + 1:4ca5088da217 + 8:dab8161ac8fc 11:82ca6f06eccd 12:9f259202bbe7 13:b0a32c86eb31 15:857b178a7cf3 16:609d82a7ebae 17:228c06deef46 + 18:d42e18c7bc9b $ hg log -q -r 'bisect(untested)' $ hg log -q -r 'bisect(ignored)' 2:051e12f87bf1 @@ -633,6 +686,18 @@ end at merge: 17 bad, 11 good (but 9 is 4:5c668c22234f 5:385a529b6670 6:a214d5d3811a + $ hg log -q -r 'bisect(goods)' + 0:33b1f9bc8bc5 + 1:4ca5088da217 + 8:dab8161ac8fc + 11:82ca6f06eccd + 12:9f259202bbe7 + 13:b0a32c86eb31 + $ hg log -q -r 'bisect(bads)' + 15:857b178a7cf3 + 16:609d82a7ebae + 17:228c06deef46 + 18:d42e18c7bc9b $ hg bisect -b The first bad revision is: changeset: 9:3c77083deb4a @@ -651,6 +716,8 @@ end at merge: 17 bad, 11 good (but 9 is 16:609d82a7ebae 17:228c06deef46 $ hg log -q -r 'bisect(pruned)' + 0:33b1f9bc8bc5 + 1:4ca5088da217 8:dab8161ac8fc 9:3c77083deb4a 10:429fcd26f52d @@ -660,6 +727,7 @@ end at merge: 17 bad, 11 good (but 9 is 15:857b178a7cf3 16:609d82a7ebae 17:228c06deef46 + 18:d42e18c7bc9b $ hg log -q -r 'bisect(untested)' $ hg log -q -r 'bisect(ignored)' 2:051e12f87bf1 @@ -667,6 +735,20 @@ end at merge: 17 bad, 11 good (but 9 is 4:5c668c22234f 5:385a529b6670 6:a214d5d3811a + $ hg log -q -r 'bisect(goods)' + 0:33b1f9bc8bc5 + 1:4ca5088da217 + 8:dab8161ac8fc + 11:82ca6f06eccd + 12:9f259202bbe7 + 13:b0a32c86eb31 + $ hg log -q -r 'bisect(bads)' + 9:3c77083deb4a + 10:429fcd26f52d + 15:857b178a7cf3 + 16:609d82a7ebae + 17:228c06deef46 + 18:d42e18c7bc9b user adds irrelevant but consistent information (here: -g 2) to bisect state @@ -698,9 +780,16 @@ user adds irrelevant but consistent info 12:9f259202bbe7 13:b0a32c86eb31 $ hg log -q -r 'bisect(pruned)' + 0:33b1f9bc8bc5 + 1:4ca5088da217 2:051e12f87bf1 8:dab8161ac8fc 11:82ca6f06eccd 12:9f259202bbe7 13:b0a32c86eb31 + 14:faa450606157 + 15:857b178a7cf3 + 16:609d82a7ebae + 17:228c06deef46 + 18:d42e18c7bc9b $ hg log -q -r 'bisect(untested)'