Mercurial > hg-stable
view mercurial/hbisect.py @ 6789:c1c202e2d45d
Force email package to be loaded in py2exe
With Python 2.5, the email package is not fully loaded by py2exe, due to
dynamic imports which are not found by modulefinder. This breaks the patchbomb
extension. This patch forces the whole email package to be included so that
the dynamic imports work as expected.
author | Paul Moore <p.f.moore@gmail.com> |
---|---|
date | Tue, 01 Jul 2008 20:17:11 +0100 |
parents | fe8dbbe9520d |
children | 683428d1e639 8f256bf98219 |
line wrap: on
line source
# changelog bisection for mercurial # # Copyright 2007 Matt Mackall # Copyright 2005, 2006 Benoit Boissinot <benoit.boissinot@ens-lyon.org> # Inspired by git bisect, extension skeleton taken from mq.py. # # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. from i18n import _ from node import short import util def bisect(changelog, state): clparents = changelog.parentrevs skip = dict.fromkeys([changelog.rev(n) for n in state['skip']]) def buildancestors(bad, good): # only the earliest bad revision matters badrev = min([changelog.rev(n) for n in bad]) goodrevs = [changelog.rev(n) for n in good] # build ancestors array ancestors = [[]] * (changelog.count() + 1) # an extra for [-1] # clear good revs from array for node in goodrevs: ancestors[node] = None for rev in xrange(changelog.count(), -1, -1): if ancestors[rev] is None: for prev in clparents(rev): ancestors[prev] = None if ancestors[badrev] is None: return badrev, None return badrev, ancestors good = 0 badrev, ancestors = buildancestors(state['bad'], state['good']) if not ancestors: # looking for bad to good transition? good = 1 badrev, ancestors = buildancestors(state['good'], state['bad']) bad = changelog.node(badrev) if not ancestors: # now we're confused raise util.Abort(_("Inconsistent state, %s:%s is good and bad") % (badrev, short(bad))) # build children dict children = {} visit = [badrev] candidates = [] while visit: rev = visit.pop(0) if ancestors[rev] == []: candidates.append(rev) for prev in clparents(rev): if prev != -1: if prev in children: children[prev].append(rev) else: children[prev] = [rev] visit.append(prev) candidates.sort() # have we narrowed it down to one entry? tot = len(candidates) if tot == 1: return (bad, 0, good) perfect = tot / 2 # find the best node to test best_rev = None best_len = -1 poison = {} for rev in candidates: if rev in poison: for c in children.get(rev, []): poison[c] = True # poison children continue a = ancestors[rev] or [rev] ancestors[rev] = None x = len(a) # number of ancestors y = tot - x # number of non-ancestors value = min(x, y) # how good is this test? if value > best_len and rev not in skip: best_len = value best_rev = rev if value == perfect: # found a perfect candidate? quit early break if y < perfect: # all downhill from here? for c in children.get(rev, []): poison[c] = True # poison children continue for c in children.get(rev, []): if ancestors[c]: ancestors[c] = dict.fromkeys(ancestors[c] + a).keys() else: ancestors[c] = a + [c] assert best_rev is not None best_node = changelog.node(best_rev) return (best_node, tot, good)