revset.bisect: add 'ignored' set to the bisect keyword

The 'ignored' changesets are outside the bisection range, but are
changesets that may have an impact on the outcome of the bisection.

For example, in case there's a merge between the good and bad csets,
but the branch-point is out of the bisection range, and the issue
originates from this branch, the branch will not be visited by bisect
and bisect will find that the culprit cset is the merge.

So, the 'ignored' set is equivalent to:
    (   ( ::bisect(bad) - ::bisect(good) )
      | ( ::bisect(good) - ::bisect(bad) ) )
    - bisect(range)

 - all ancestors of bad csets that are not ancestors of good csets, or
 - all ancestors of good csets that are not ancestors of bad csets
 - but that are not in the bisection range.

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
This commit is contained in:
Yann E. MORIN 2011-09-20 20:21:04 +02:00
parent 67456b9f23
commit bd0d47a8d1
4 changed files with 53 additions and 0 deletions

View File

@ -547,6 +547,8 @@ def bisect(ui, repo, rev=None, extra=None, command=None,
hg log --graph -r "bisect(range)" hg log --graph -r "bisect(range)"
See :hg:`help revsets` for more about the `bisect()` keyword.
Returns 0 on success. Returns 0 on success.
""" """
def extendbisectrange(nodes, good): def extendbisectrange(nodes, good):

View File

@ -162,6 +162,7 @@ def get(repo, status):
- ``range`` : all csets taking part in the bisection - ``range`` : all csets taking part in the bisection
- ``pruned`` : csets that are good, bad or skipped - ``pruned`` : csets that are good, bad or skipped
- ``untested`` : csets whose fate is yet unknown - ``untested`` : csets whose fate is yet unknown
- ``ignored`` : csets ignored due to DAG topology
""" """
state = load_state(repo) state = load_state(repo)
if status in ('good', 'bad', 'skip'): if status in ('good', 'bad', 'skip'):
@ -191,12 +192,22 @@ def get(repo, status):
# 'untested' is all cset that are- in 'range', but not in 'pruned' # 'untested' is all cset that are- in 'range', but not in 'pruned'
untested = '( (%s) - (%s) )' % (range, pruned) untested = '( (%s) - (%s) )' % (range, pruned)
# 'ignored' is all csets that were not used during the bisection
# due to DAG topology, but may however have had an impact.
# Eg., a branch merged between bads and goods, but whose branch-
# point is out-side of the range.
iba = '::bisect(bad) - ::bisect(good)' # Ignored bads' ancestors
iga = '::bisect(good) - ::bisect(bad)' # Ignored goods' ancestors
ignored = '( ( (%s) | (%s) ) - (%s) )' % (iba, iga, range)
if status == 'range': if status == 'range':
return [c.rev() for c in repo.set(range)] return [c.rev() for c in repo.set(range)]
elif status == 'pruned': elif status == 'pruned':
return [c.rev() for c in repo.set(pruned)] return [c.rev() for c in repo.set(pruned)]
elif status == 'untested': elif status == 'untested':
return [c.rev() for c in repo.set(untested)] return [c.rev() for c in repo.set(untested)]
elif status == 'ignored':
return [c.rev() for c in repo.set(ignored)]
else: else:
raise error.ParseError(_('invalid bisect state')) raise error.ParseError(_('invalid bisect state'))

View File

@ -243,6 +243,7 @@ def bisect(repo, subset, x):
- ``range`` : all csets taking part in the bisection - ``range`` : all csets taking part in the bisection
- ``pruned`` : csets that are good, bad or skipped - ``pruned`` : csets that are good, bad or skipped
- ``untested`` : csets whose fate is yet unknown - ``untested`` : csets whose fate is yet unknown
- ``ignored`` : csets ignored due to DAG topology
""" """
status = getstring(x, _("bisect requires a string")).lower() status = getstring(x, _("bisect requires a string")).lower()
return [r for r in subset if r in hbisect.get(repo, status)] return [r for r in subset if r in hbisect.get(repo, status)]

View File

@ -270,6 +270,7 @@ complex bisect test 1 # first bad rev is 9
13:b0a32c86eb31 13:b0a32c86eb31
15:857b178a7cf3 15:857b178a7cf3
16:609d82a7ebae 16:609d82a7ebae
$ hg log -q -r 'bisect(ignored)'
$ hg bisect -g # -> update to rev 13 $ hg bisect -g # -> update to rev 13
Testing changeset 13:b0a32c86eb31 (9 changesets remaining, ~3 tests) Testing changeset 13:b0a32c86eb31 (9 changesets remaining, ~3 tests)
3 files updated, 0 files merged, 1 files removed, 0 files unresolved 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
@ -422,6 +423,7 @@ first bad rev is 15
$ hg bisect -s # -> update to rev 15 $ hg bisect -s # -> update to rev 15
Testing changeset 15:857b178a7cf3 (5 changesets remaining, ~2 tests) Testing changeset 15:857b178a7cf3 (5 changesets remaining, ~2 tests)
3 files updated, 0 files merged, 0 files removed, 0 files unresolved 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg log -q -r 'bisect(ignored)'
$ hg bisect -b $ hg bisect -b
Due to skipped revisions, the first bad revision could be any of: Due to skipped revisions, the first bad revision could be any of:
changeset: 9:3c77083deb4a changeset: 9:3c77083deb4a
@ -463,6 +465,7 @@ first bad rev is 15
13:b0a32c86eb31 13:b0a32c86eb31
15:857b178a7cf3 15:857b178a7cf3
16:609d82a7ebae 16:609d82a7ebae
$ hg log -q -r 'bisect(ignored)'
complex bisect test 4 complex bisect test 4
@ -560,6 +563,14 @@ end at merge: 17 bad, 11 good (but 9 is first bad)
$ hg bisect -g 11 $ hg bisect -g 11
Testing changeset 13:b0a32c86eb31 (5 changesets remaining, ~2 tests) Testing changeset 13:b0a32c86eb31 (5 changesets remaining, ~2 tests)
3 files updated, 0 files merged, 1 files removed, 0 files unresolved 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg log -q -r 'bisect(ignored)'
2:051e12f87bf1
3:0950834f0a9c
4:5c668c22234f
5:385a529b6670
6:a214d5d3811a
9:3c77083deb4a
10:429fcd26f52d
$ hg bisect -g $ hg bisect -g
Testing changeset 15:857b178a7cf3 (3 changesets remaining, ~1 tests) Testing changeset 15:857b178a7cf3 (3 changesets remaining, ~1 tests)
3 files updated, 0 files merged, 0 files removed, 0 files unresolved 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
@ -590,16 +601,38 @@ end at merge: 17 bad, 11 good (but 9 is first bad)
16:609d82a7ebae 16:609d82a7ebae
17:228c06deef46 17:228c06deef46
$ hg log -q -r 'bisect(untested)' $ hg log -q -r 'bisect(untested)'
$ hg log -q -r 'bisect(ignored)'
2:051e12f87bf1
3:0950834f0a9c
4:5c668c22234f
5:385a529b6670
6:a214d5d3811a
9:3c77083deb4a
10:429fcd26f52d
$ hg bisect --extend $ hg bisect --extend
Extending search to changeset 8:dab8161ac8fc Extending search to changeset 8:dab8161ac8fc
2 files updated, 0 files merged, 2 files removed, 0 files unresolved 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
$ hg log -q -r 'bisect(untested)' $ hg log -q -r 'bisect(untested)'
$ hg log -q -r 'bisect(ignored)'
2:051e12f87bf1
3:0950834f0a9c
4:5c668c22234f
5:385a529b6670
6:a214d5d3811a
9:3c77083deb4a
10:429fcd26f52d
$ hg bisect -g # dab8161ac8fc $ hg bisect -g # dab8161ac8fc
Testing changeset 9:3c77083deb4a (3 changesets remaining, ~1 tests) Testing changeset 9:3c77083deb4a (3 changesets remaining, ~1 tests)
1 files updated, 0 files merged, 0 files removed, 0 files unresolved 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg log -q -r 'bisect(untested)' $ hg log -q -r 'bisect(untested)'
9:3c77083deb4a 9:3c77083deb4a
10:429fcd26f52d 10:429fcd26f52d
$ hg log -q -r 'bisect(ignored)'
2:051e12f87bf1
3:0950834f0a9c
4:5c668c22234f
5:385a529b6670
6:a214d5d3811a
$ hg bisect -b $ hg bisect -b
The first bad revision is: The first bad revision is:
changeset: 9:3c77083deb4a changeset: 9:3c77083deb4a
@ -628,6 +661,12 @@ end at merge: 17 bad, 11 good (but 9 is first bad)
16:609d82a7ebae 16:609d82a7ebae
17:228c06deef46 17:228c06deef46
$ hg log -q -r 'bisect(untested)' $ hg log -q -r 'bisect(untested)'
$ hg log -q -r 'bisect(ignored)'
2:051e12f87bf1
3:0950834f0a9c
4:5c668c22234f
5:385a529b6670
6:a214d5d3811a
user adds irrelevant but consistent information (here: -g 2) to bisect state user adds irrelevant but consistent information (here: -g 2) to bisect state