hgext3rd/topic/evolvebits.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Sat, 09 Dec 2017 22:37:10 +0100
changeset 3251 0e4a05907c5e
parent 3017 0884856a4143
child 3697 6aff4bb3970d
permissions -rw-r--r--
stablerange: introduce an 'basicstablerange' This class hold all the basic of stable range but the part specific to the sorting. This allow to clearly express what is expected from each method and to generate tests output to be validated against the more complex implementation. While writing this, we spotted a bug in the current stable range implementation. Fix coming.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1982
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     1
import collections
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     2
2922
66357d4d03b2 topic: centralize compatibility logic between hg versions into compat module
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 2694
diff changeset
     3
from . import compat
2694
8a222745a71c topic: adapt to function migrate to obsutil
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 1982
diff changeset
     4
1982
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     5
# Copied from evolve 081605c2e9b6
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     6
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     7
def _orderrevs(repo, revs):
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     8
    """Compute an ordering to solve instability for the given revs
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     9
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    10
    revs is a list of unstable revisions.
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    11
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    12
    Returns the same revisions ordered to solve their instability from the
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    13
    bottom to the top of the stack that the stabilization process will produce
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    14
    eventually.
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    15
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    16
    This ensures the minimal number of stabilizations, as we can stabilize each
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    17
    revision on its final stabilized destination.
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    18
    """
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    19
    # Step 1: Build the dependency graph
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    20
    dependencies, rdependencies = builddependencies(repo, revs)
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    21
    # Step 2: Build the ordering
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    22
    # Remove the revisions with no dependency(A) and add them to the ordering.
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    23
    # Removing these revisions leads to new revisions with no dependency (the
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    24
    # one depending on A) that we can remove from the dependency graph and add
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    25
    # to the ordering. We progress in a similar fashion until the ordering is
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    26
    # built
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    27
    solvablerevs = [r for r in sorted(dependencies.keys())
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    28
                    if not dependencies[r]]
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    29
    ordering = []
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    30
    while solvablerevs:
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    31
        rev = solvablerevs.pop()
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    32
        for dependent in rdependencies[rev]:
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    33
            dependencies[dependent].remove(rev)
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    34
            if not dependencies[dependent]:
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    35
                solvablerevs.append(dependent)
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    36
        del dependencies[rev]
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    37
        ordering.append(rev)
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    38
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    39
    ordering.extend(sorted(dependencies))
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    40
    return ordering
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    41
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    42
def builddependencies(repo, revs):
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    43
    """returns dependency graphs giving an order to solve instability of revs
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    44
    (see _orderrevs for more information on usage)"""
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    45
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    46
    # For each troubled revision we keep track of what instability if any should
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    47
    # be resolved in order to resolve it. Example:
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    48
    # dependencies = {3: [6], 6:[]}
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    49
    # Means that: 6 has no dependency, 3 depends on 6 to be solved
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    50
    dependencies = {}
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    51
    # rdependencies is the inverted dict of dependencies
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    52
    rdependencies = collections.defaultdict(set)
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    53
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    54
    for r in revs:
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    55
        dependencies[r] = set()
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    56
        for p in repo[r].parents():
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    57
            try:
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    58
                succ = _singlesuccessor(repo, p)
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    59
            except MultipleSuccessorsError as exc:
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    60
                dependencies[r] = exc.successorssets
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    61
                continue
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    62
            if succ in revs:
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    63
                dependencies[r].add(succ)
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    64
                rdependencies[succ].add(r)
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    65
    return dependencies, rdependencies
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    66
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    67
def _singlesuccessor(repo, p):
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    68
    """returns p (as rev) if not obsolete or its unique latest successors
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    69
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    70
    fail if there are no such successor"""
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    71
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    72
    if not p.obsolete():
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    73
        return p.rev()
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    74
    obs = repo[p]
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    75
    ui = repo.ui
2922
66357d4d03b2 topic: centralize compatibility logic between hg versions into compat module
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 2694
diff changeset
    76
    newer = compat.successorssets(repo, obs.node())
1982
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    77
    # search of a parent which is not killed
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    78
    while not newer:
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    79
        ui.debug("stabilize target %s is plain dead,"
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    80
                 " trying to stabilize on its parent\n" %
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    81
                 obs)
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    82
        obs = obs.parents()[0]
2922
66357d4d03b2 topic: centralize compatibility logic between hg versions into compat module
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 2694
diff changeset
    83
        newer = compat.successorssets(repo, obs.node())
3017
0884856a4143 stack: handle basic case of splitting with crash
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2922
diff changeset
    84
    if 1 < len(newer):
0884856a4143 stack: handle basic case of splitting with crash
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2922
diff changeset
    85
        # divergence case
0884856a4143 stack: handle basic case of splitting with crash
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2922
diff changeset
    86
        # we should pick as arbitrary one
1982
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    87
        raise MultipleSuccessorsError(newer)
3017
0884856a4143 stack: handle basic case of splitting with crash
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2922
diff changeset
    88
    elif 1 < len(newer[0]):
0884856a4143 stack: handle basic case of splitting with crash
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2922
diff changeset
    89
        splitheads = list(repo.revs('heads(%ln::%ln)', newer[0], newer[0]))
0884856a4143 stack: handle basic case of splitting with crash
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2922
diff changeset
    90
        if 1 < len(splitheads):
0884856a4143 stack: handle basic case of splitting with crash
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2922
diff changeset
    91
            # split case, See if we can make sense of it.
0884856a4143 stack: handle basic case of splitting with crash
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2922
diff changeset
    92
            raise MultipleSuccessorsError(newer)
0884856a4143 stack: handle basic case of splitting with crash
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2922
diff changeset
    93
        return splitheads[0]
1982
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    94
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    95
    return repo[newer[0][0]].rev()
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    96
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    97
class MultipleSuccessorsError(RuntimeError):
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    98
    """Exception raised by _singlesuccessor when multiple successor sets exists
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    99
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   100
    The object contains the list of successorssets in its 'successorssets'
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   101
    attribute to call to easily recover.
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   102
    """
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   103
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   104
    def __init__(self, successorssets):
d87fc4f749e6 evolve: extract the code copied from evolve in a submodule
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   105
        self.successorssets = successorssets