diff --git a/hgext3rd/clindex.pyx b/hgext3rd/clindex.pyx --- a/hgext3rd/clindex.pyx +++ b/hgext3rd/clindex.pyx @@ -102,7 +102,42 @@ return self._origindex[rev] def computephasesmapsets(self, roots): - return self._origindex.computephasesmapsets(roots) + if not self._config.childmap: + return self._origindex.computephasesmapsets(roots) + # using childmap + drafts = self._descendants(roots[0]) + secrets = self._descendants(roots[1]) + drafts -= secrets + sets = [None, drafts, secrets] + revs = phaserevs(sets, len(self)) + if self._config.verify: + origrevs, origsets = self._origindex.computephasesmapsets(roots) + for phase in (1, 2): + origset = origsets[phase] + thisset = sets[phase] + added = thisset - origset + removed = origset - thisset + if added or removed: + _logandraise( + 'phases: inconsistent result(%s):\n added %r' + '\n removed %r' % (phase, added, removed)) + return revs, sets + + cpdef _descendants(self, rootrevs): + assert self._config.childmap + queue = rootrevs[:] + revs = set() + while queue: + rev = queue.pop() + if rev in revs: + continue + revs.add(rev) + queue.extend(self._children(rev)) + return revs + + cpdef _children(self, int rev): + assert self._config.childmap + return self._childmap[rev] def reachableroots2(self, int minroot, heads, roots, includepath): return self._origindex.reachableroots2(minroot, heads, roots, @@ -413,6 +448,24 @@ self._vfs.tryunlink('childmap') self._config.childmap = False +cdef class phaserevs(object): + """list-like rev -> phase map based on phasesets""" + cdef object _sets + cdef int _len + + def __cinit__(self, sets, len): + self._sets = sets + self._len = len + + def __getitem__(self, int rev): + for i, revs in enumerate(self._sets): + if revs and rev in revs: + return i + return 0 + + def __len__(self): + return self._len + # These are unfortunate. But we need vfs access inside index.__init__. Doing # that properly requires API changes in revlog.__init__ and # revlogio.parseindex that might make things uglier, or break the (potential)