Mercurial > evolve
diff hgext3rd/topic/stack.py @ 1982:d87fc4f749e6
evolve: extract the code copied from evolve in a submodule
This will allow us to use that code in other module.
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Mon, 15 Aug 2016 05:15:19 +0200 |
parents | bee7a1ef8ba8 |
children | 03d6b685c16a |
line wrap: on
line diff
--- a/hgext3rd/topic/stack.py Mon Aug 15 01:50:15 2016 +0200 +++ b/hgext3rd/topic/stack.py Mon Aug 15 05:15:19 2016 +0200 @@ -2,13 +2,12 @@ # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -import collections from mercurial.i18n import _ from mercurial import ( error, node, - obsolete, ) +from .evolvebits import builddependencies, _orderrevs, _singlesuccessor def getstack(repo, topic): # XXX need sorting @@ -80,96 +79,3 @@ return data -# Copied from evolve 081605c2e9b6 - -def _orderrevs(repo, revs): - """Compute an ordering to solve instability for the given revs - - revs is a list of unstable revisions. - - Returns the same revisions ordered to solve their instability from the - bottom to the top of the stack that the stabilization process will produce - eventually. - - This ensures the minimal number of stabilizations, as we can stabilize each - revision on its final stabilized destination. - """ - # Step 1: Build the dependency graph - dependencies, rdependencies = builddependencies(repo, revs) - # Step 2: Build the ordering - # Remove the revisions with no dependency(A) and add them to the ordering. - # Removing these revisions leads to new revisions with no dependency (the - # one depending on A) that we can remove from the dependency graph and add - # to the ordering. We progress in a similar fashion until the ordering is - # built - solvablerevs = [r for r in sorted(dependencies.keys()) - if not dependencies[r]] - ordering = [] - while solvablerevs: - rev = solvablerevs.pop() - for dependent in rdependencies[rev]: - dependencies[dependent].remove(rev) - if not dependencies[dependent]: - solvablerevs.append(dependent) - del dependencies[rev] - ordering.append(rev) - - ordering.extend(sorted(dependencies)) - return ordering - -def builddependencies(repo, revs): - """returns dependency graphs giving an order to solve instability of revs - (see _orderrevs for more information on usage)""" - - # For each troubled revision we keep track of what instability if any should - # be resolved in order to resolve it. Example: - # dependencies = {3: [6], 6:[]} - # Means that: 6 has no dependency, 3 depends on 6 to be solved - dependencies = {} - # rdependencies is the inverted dict of dependencies - rdependencies = collections.defaultdict(set) - - for r in revs: - dependencies[r] = set() - for p in repo[r].parents(): - try: - succ = _singlesuccessor(repo, p) - except MultipleSuccessorsError as exc: - dependencies[r] = exc.successorssets - continue - if succ in revs: - dependencies[r].add(succ) - rdependencies[succ].add(r) - return dependencies, rdependencies - -def _singlesuccessor(repo, p): - """returns p (as rev) if not obsolete or its unique latest successors - - fail if there are no such successor""" - - if not p.obsolete(): - return p.rev() - obs = repo[p] - ui = repo.ui - newer = obsolete.successorssets(repo, obs.node()) - # search of a parent which is not killed - while not newer: - ui.debug("stabilize target %s is plain dead," - " trying to stabilize on its parent\n" % - obs) - obs = obs.parents()[0] - newer = obsolete.successorssets(repo, obs.node()) - if len(newer) > 1 or len(newer[0]) > 1: - raise MultipleSuccessorsError(newer) - - return repo[newer[0][0]].rev() - -class MultipleSuccessorsError(RuntimeError): - """Exception raised by _singlesuccessor when multiple successor sets exists - - The object contains the list of successorssets in its 'successorssets' - attribute to call to easily recover. - """ - - def __init__(self, successorssets): - self.successorssets = successorssets