summaryrefslogtreecommitdiff
path: root/mercurial/hbisect.py
diff options
context:
space:
mode:
Diffstat (limited to 'mercurial/hbisect.py')
-rw-r--r--mercurial/hbisect.py123
1 files changed, 10 insertions, 113 deletions
diff --git a/mercurial/hbisect.py b/mercurial/hbisect.py
index 0ce8182..38ed976 100644
--- a/mercurial/hbisect.py
+++ b/mercurial/hbisect.py
@@ -8,7 +8,7 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-import os, error
+import os
from i18n import _
from node import short, hex
import util
@@ -35,18 +35,17 @@ def bisect(changelog, state):
# build visit array
ancestors = [None] * (len(changelog) + 1) # an extra for [-1]
- # set nodes descended from goodrevs
- for rev in goodrevs:
- ancestors[rev] = []
+ # set nodes descended from goodrev
+ ancestors[goodrev] = []
for rev in xrange(goodrev + 1, len(changelog)):
for prev in clparents(rev):
if ancestors[prev] == []:
ancestors[rev] = []
# clear good revs from array
- for rev in goodrevs:
- ancestors[rev] = None
- for rev in xrange(len(changelog), goodrev, -1):
+ for node in goodrevs:
+ ancestors[node] = None
+ for rev in xrange(len(changelog), -1, -1):
if ancestors[rev] is None:
for prev in clparents(rev):
ancestors[prev] = None
@@ -69,10 +68,10 @@ def bisect(changelog, state):
# build children dict
children = {}
- visit = util.deque([badrev])
+ visit = [badrev]
candidates = []
while visit:
- rev = visit.popleft()
+ rev = visit.pop(0)
if ancestors[rev] == []:
candidates.append(rev)
for prev in clparents(rev):
@@ -132,7 +131,7 @@ def bisect(changelog, state):
def load_state(repo):
- state = {'current': [], 'good': [], 'bad': [], 'skip': []}
+ state = {'good': [], 'bad': [], 'skip': []}
if os.path.exists(repo.join("bisect.state")):
for l in repo.opener("bisect.state"):
kind, node = l[:-1].split()
@@ -150,109 +149,7 @@ def save_state(repo, state):
for kind in state:
for node in state[kind]:
f.write("%s %s\n" % (kind, hex(node)))
- f.close()
+ f.rename()
finally:
wlock.release()
-def get(repo, status):
- """
- Return a list of revision(s) that match the given status:
-
- - ``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
- - ``current`` : the cset currently being bisected
- """
- state = load_state(repo)
- if status in ('good', 'bad', 'skip', 'current'):
- return map(repo.changelog.rev, state[status])
- else:
- # In the floowing sets, we do *not* call 'bisect()' with more
- # than one level of recusrsion, because that can be very, very
- # time consuming. Instead, we always develop the expression as
- # much as possible.
-
- # 'range' is all csets that make the bisection:
- # - have a good ancestor and a bad descendant, or conversely
- # that's because the bisection can go either way
- range = '( bisect(bad)::bisect(good) | bisect(good)::bisect(bad) )'
-
- _t = repo.revs('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)
-
- # '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':
- return repo.revs(range)
- elif status == 'pruned':
- return repo.revs(pruned)
- elif status == 'untested':
- return repo.revs(untested)
- elif status == 'ignored':
- return repo.revs(ignored)
- elif status == "goods":
- return repo.revs(goods)
- elif status == "bads":
- return repo.revs(bads)
- else:
- raise error.ParseError(_('invalid bisect state'))
-
-def label(repo, node):
- rev = repo.changelog.rev(node)
-
- # Try explicit sets
- if rev in get(repo, 'good'):
- # i18n: bisect changeset status
- return _('good')
- if rev in get(repo, 'bad'):
- # i18n: bisect changeset status
- return _('bad')
- if rev in get(repo, 'skip'):
- # i18n: bisect changeset status
- return _('skipped')
- if rev in get(repo, 'untested') or rev in get(repo, 'current'):
- # i18n: bisect changeset status
- return _('untested')
- if rev in get(repo, 'ignored'):
- # i18n: bisect changeset status
- return _('ignored')
-
- # Try implicit sets
- if rev in get(repo, 'goods'):
- # i18n: bisect changeset status
- return _('good (implicit)')
- if rev in get(repo, 'bads'):
- # i18n: bisect changeset status
- return _('bad (implicit)')
-
- return None
-
-def shortlabel(label):
- if label:
- return label[0].upper()
-
- return None