mercurial/obsutil.py
author Matt Harbison <matt_harbison@yahoo.com>
Sat, 08 Jul 2017 18:46:12 -0400
changeset 33342 96eb3f50f75c
parent 33274 68f3e819d41d
child 33713 888f24810ea2
permissions -rw-r--r--
test-mq: conditionalize output instead of tests
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
32879
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
     1
# obsutil.py - utility functions for obsolescence
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
     2
#
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
     3
# Copyright 2017 Boris Feld <boris.feld@octobus.net>
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
     4
#
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
     7
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
     8
from __future__ import absolute_import
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
     9
33252
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
    10
from . import (
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
    11
    phases,
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
    12
)
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
    13
33148
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    14
class marker(object):
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    15
    """Wrap obsolete marker raw data"""
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    16
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    17
    def __init__(self, repo, data):
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    18
        # the repo argument will be used to create changectx in later version
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    19
        self._repo = repo
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    20
        self._data = data
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    21
        self._decodedmeta = None
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    22
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    23
    def __hash__(self):
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    24
        return hash(self._data)
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    25
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    26
    def __eq__(self, other):
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    27
        if type(other) != type(self):
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    28
            return False
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    29
        return self._data == other._data
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    30
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    31
    def precnode(self):
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    32
        """Precursor changeset node identifier"""
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    33
        return self._data[0]
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    34
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    35
    def succnodes(self):
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    36
        """List of successor changesets node identifiers"""
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    37
        return self._data[1]
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    38
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    39
    def parentnodes(self):
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    40
        """Parents of the precursors (None if not recorded)"""
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    41
        return self._data[5]
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    42
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    43
    def metadata(self):
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    44
        """Decoded metadata dictionary"""
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    45
        return dict(self._data[3])
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    46
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    47
    def date(self):
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    48
        """Creation date as (unixtime, offset)"""
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    49
        return self._data[4]
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    50
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    51
    def flags(self):
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    52
        """The flags field of the marker"""
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    53
        return self._data[2]
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    54
33149
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    55
def getmarkers(repo, nodes=None, exclusive=False):
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    56
    """returns markers known in a repository
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    57
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    58
    If <nodes> is specified, only markers "relevant" to those nodes are are
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    59
    returned"""
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    60
    if nodes is None:
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    61
        rawmarkers = repo.obsstore
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    62
    elif exclusive:
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    63
        rawmarkers = exclusivemarkers(repo, nodes)
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    64
    else:
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    65
        rawmarkers = repo.obsstore.relevantmarkers(nodes)
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    66
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    67
    for markerdata in rawmarkers:
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    68
        yield marker(repo, markerdata)
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    69
32879
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    70
def closestpredecessors(repo, nodeid):
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    71
    """yield the list of next predecessors pointing on visible changectx nodes
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    72
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    73
    This function respect the repoview filtering, filtered revision will be
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    74
    considered missing.
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    75
    """
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    76
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    77
    precursors = repo.obsstore.precursors
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    78
    stack = [nodeid]
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    79
    seen = set(stack)
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    80
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    81
    while stack:
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    82
        current = stack.pop()
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    83
        currentpreccs = precursors.get(current, ())
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    84
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    85
        for prec in currentpreccs:
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    86
            precnodeid = prec[0]
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    87
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    88
            # Basic cycle protection
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    89
            if precnodeid in seen:
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    90
                continue
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    91
            seen.add(precnodeid)
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    92
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    93
            if precnodeid in repo:
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    94
                yield precnodeid
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    95
            else:
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    96
                stack.append(precnodeid)
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
    97
33144
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
    98
def allprecursors(obsstore, nodes, ignoreflags=0):
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
    99
    """Yield node for every precursors of <nodes>.
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   100
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   101
    Some precursors may be unknown locally.
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   102
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   103
    This is a linear yield unsuited to detecting folded changesets. It includes
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   104
    initial nodes too."""
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   105
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   106
    remaining = set(nodes)
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   107
    seen = set(remaining)
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   108
    while remaining:
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   109
        current = remaining.pop()
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   110
        yield current
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   111
        for mark in obsstore.precursors.get(current, ()):
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   112
            # ignore marker flagged with specified flag
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   113
            if mark[2] & ignoreflags:
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   114
                continue
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   115
            suc = mark[0]
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   116
            if suc not in seen:
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   117
                seen.add(suc)
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   118
                remaining.add(suc)
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   119
33145
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   120
def allsuccessors(obsstore, nodes, ignoreflags=0):
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   121
    """Yield node for every successor of <nodes>.
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   122
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   123
    Some successors may be unknown locally.
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   124
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   125
    This is a linear yield unsuited to detecting split changesets. It includes
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   126
    initial nodes too."""
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   127
    remaining = set(nodes)
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   128
    seen = set(remaining)
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   129
    while remaining:
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   130
        current = remaining.pop()
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   131
        yield current
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   132
        for mark in obsstore.successors.get(current, ()):
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   133
            # ignore marker flagged with specified flag
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   134
            if mark[2] & ignoreflags:
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   135
                continue
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   136
            for suc in mark[1]:
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   137
                if suc not in seen:
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   138
                    seen.add(suc)
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   139
                    remaining.add(suc)
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   140
33143
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   141
def _filterprunes(markers):
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   142
    """return a set with no prune markers"""
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   143
    return set(m for m in markers if m[1])
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   144
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   145
def exclusivemarkers(repo, nodes):
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   146
    """set of markers relevant to "nodes" but no other locally-known nodes
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   147
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   148
    This function compute the set of markers "exclusive" to a locally-known
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   149
    node. This means we walk the markers starting from <nodes> until we reach a
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   150
    locally-known precursors outside of <nodes>. Element of <nodes> with
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   151
    locally-known successors outside of <nodes> are ignored (since their
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   152
    precursors markers are also relevant to these successors).
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   153
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   154
    For example:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   155
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   156
        # (A0 rewritten as A1)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   157
        #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   158
        # A0 <-1- A1 # Marker "1" is exclusive to A1
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   159
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   160
        or
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   161
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   162
        # (A0 rewritten as AX; AX rewritten as A1; AX is unkown locally)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   163
        #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   164
        # <-1- A0 <-2- AX <-3- A1 # Marker "2,3" are exclusive to A1
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   165
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   166
        or
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   167
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   168
        # (A0 has unknown precursors, A0 rewritten as A1 and A2 (divergence))
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   169
        #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   170
        #          <-2- A1 # Marker "2" is exclusive to A0,A1
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   171
        #        /
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   172
        # <-1- A0
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   173
        #        \
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   174
        #         <-3- A2 # Marker "3" is exclusive to A0,A2
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   175
        #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   176
        # in addition:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   177
        #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   178
        #  Markers "2,3" are exclusive to A1,A2
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   179
        #  Markers "1,2,3" are exclusive to A0,A1,A2
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   180
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   181
        See test/test-obsolete-bundle-strip.t for more examples.
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   182
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   183
    An example usage is strip. When stripping a changeset, we also want to
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   184
    strip the markers exclusive to this changeset. Otherwise we would have
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   185
    "dangling"" obsolescence markers from its precursors: Obsolescence markers
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   186
    marking a node as obsolete without any successors available locally.
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   187
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   188
    As for relevant markers, the prune markers for children will be followed.
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   189
    Of course, they will only be followed if the pruned children is
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   190
    locally-known. Since the prune markers are relevant to the pruned node.
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   191
    However, while prune markers are considered relevant to the parent of the
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   192
    pruned changesets, prune markers for locally-known changeset (with no
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   193
    successors) are considered exclusive to the pruned nodes. This allows
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   194
    to strip the prune markers (with the rest of the exclusive chain) alongside
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   195
    the pruned changesets.
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   196
    """
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   197
    # running on a filtered repository would be dangerous as markers could be
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   198
    # reported as exclusive when they are relevant for other filtered nodes.
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   199
    unfi = repo.unfiltered()
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   200
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   201
    # shortcut to various useful item
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   202
    nm = unfi.changelog.nodemap
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   203
    precursorsmarkers = unfi.obsstore.precursors
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   204
    successormarkers = unfi.obsstore.successors
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   205
    childrenmarkers = unfi.obsstore.children
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   206
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   207
    # exclusive markers (return of the function)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   208
    exclmarkers = set()
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   209
    # we need fast membership testing
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   210
    nodes = set(nodes)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   211
    # looking for head in the obshistory
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   212
    #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   213
    # XXX we are ignoring all issues in regard with cycle for now.
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   214
    stack = [n for n in nodes if not _filterprunes(successormarkers.get(n, ()))]
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   215
    stack.sort()
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   216
    # nodes already stacked
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   217
    seennodes = set(stack)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   218
    while stack:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   219
        current = stack.pop()
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   220
        # fetch precursors markers
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   221
        markers = list(precursorsmarkers.get(current, ()))
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   222
        # extend the list with prune markers
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   223
        for mark in successormarkers.get(current, ()):
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   224
            if not mark[1]:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   225
                markers.append(mark)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   226
        # and markers from children (looking for prune)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   227
        for mark in childrenmarkers.get(current, ()):
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   228
            if not mark[1]:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   229
                markers.append(mark)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   230
        # traverse the markers
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   231
        for mark in markers:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   232
            if mark in exclmarkers:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   233
                # markers already selected
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   234
                continue
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   235
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   236
            # If the markers is about the current node, select it
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   237
            #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   238
            # (this delay the addition of markers from children)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   239
            if mark[1] or mark[0] == current:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   240
                exclmarkers.add(mark)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   241
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   242
            # should we keep traversing through the precursors?
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   243
            prec = mark[0]
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   244
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   245
            # nodes in the stack or already processed
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   246
            if prec in seennodes:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   247
                continue
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   248
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   249
            # is this a locally known node ?
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   250
            known = prec in nm
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   251
            # if locally-known and not in the <nodes> set the traversal
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   252
            # stop here.
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   253
            if known and prec not in nodes:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   254
                continue
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   255
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   256
            # do not keep going if there are unselected markers pointing to this
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   257
            # nodes. If we end up traversing these unselected markers later the
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   258
            # node will be taken care of at that point.
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   259
            precmarkers = _filterprunes(successormarkers.get(prec))
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   260
            if precmarkers.issubset(exclmarkers):
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   261
                seennodes.add(prec)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   262
                stack.append(prec)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   263
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   264
    return exclmarkers
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   265
33146
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   266
def foreground(repo, nodes):
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   267
    """return all nodes in the "foreground" of other node
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   268
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   269
    The foreground of a revision is anything reachable using parent -> children
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   270
    or precursor -> successor relation. It is very similar to "descendant" but
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   271
    augmented with obsolescence information.
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   272
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   273
    Beware that possible obsolescence cycle may result if complex situation.
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   274
    """
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   275
    repo = repo.unfiltered()
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   276
    foreground = set(repo.set('%ln::', nodes))
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   277
    if repo.obsstore:
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   278
        # We only need this complicated logic if there is obsolescence
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   279
        # XXX will probably deserve an optimised revset.
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   280
        nm = repo.changelog.nodemap
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   281
        plen = -1
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   282
        # compute the whole set of successors or descendants
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   283
        while len(foreground) != plen:
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   284
            plen = len(foreground)
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   285
            succs = set(c.node() for c in foreground)
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   286
            mutable = [c.node() for c in foreground if c.mutable()]
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   287
            succs.update(allsuccessors(repo.obsstore, mutable))
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   288
            known = (n for n in succs if n in nm)
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   289
            foreground = set(repo.set('%ln::', known))
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   290
    return set(c.node() for c in foreground)
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   291
33252
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   292
def getobsoleted(repo, tr):
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   293
    """return the set of pre-existing revisions obsoleted by a transaction"""
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   294
    torev = repo.unfiltered().changelog.nodemap.get
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   295
    phase = repo._phasecache.phase
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   296
    succsmarkers = repo.obsstore.successors.get
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   297
    public = phases.public
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   298
    addedmarkers = tr.changes.get('obsmarkers')
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   299
    addedrevs = tr.changes.get('revs')
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   300
    seenrevs = set(addedrevs)
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   301
    obsoleted = set()
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   302
    for mark in addedmarkers:
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   303
        node = mark[0]
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   304
        rev = torev(node)
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   305
        if rev is None or rev in seenrevs:
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   306
            continue
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   307
        seenrevs.add(rev)
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   308
        if phase(repo, rev) == public:
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   309
            continue
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   310
        if set(succsmarkers(node)).issubset(addedmarkers):
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   311
            obsoleted.add(rev)
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   312
    return obsoleted
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   313
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   314
def successorssets(repo, initialnode, closest=False, cache=None):
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   315
    """Return set of all latest successors of initial nodes
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   316
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   317
    The successors set of a changeset A are the group of revisions that succeed
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   318
    A. It succeeds A as a consistent whole, each revision being only a partial
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   319
    replacement. By default, the successors set contains non-obsolete
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   320
    changesets only, walking the obsolescence graph until reaching a leaf. If
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   321
    'closest' is set to True, closest successors-sets are return (the
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   322
    obsolescence walk stops on known changesets).
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   323
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   324
    This function returns the full list of successor sets which is why it
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   325
    returns a list of tuples and not just a single tuple. Each tuple is a valid
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   326
    successors set. Note that (A,) may be a valid successors set for changeset A
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   327
    (see below).
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   328
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   329
    In most cases, a changeset A will have a single element (e.g. the changeset
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   330
    A is replaced by A') in its successors set. Though, it is also common for a
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   331
    changeset A to have no elements in its successor set (e.g. the changeset
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   332
    has been pruned). Therefore, the returned list of successors sets will be
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   333
    [(A',)] or [], respectively.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   334
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   335
    When a changeset A is split into A' and B', however, it will result in a
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   336
    successors set containing more than a single element, i.e. [(A',B')].
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   337
    Divergent changesets will result in multiple successors sets, i.e. [(A',),
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   338
    (A'')].
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   339
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   340
    If a changeset A is not obsolete, then it will conceptually have no
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   341
    successors set. To distinguish this from a pruned changeset, the successor
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   342
    set will contain itself only, i.e. [(A,)].
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   343
33272
df90f4d6c609 obsolete: small doc update for 'successorssets'
Boris Feld <boris.feld@octobus.net>
parents: 33252
diff changeset
   344
    Finally, final successors unknown locally are considered to be pruned
df90f4d6c609 obsolete: small doc update for 'successorssets'
Boris Feld <boris.feld@octobus.net>
parents: 33252
diff changeset
   345
    (pruned: obsoleted without any successors). (Final: successors not affected
df90f4d6c609 obsolete: small doc update for 'successorssets'
Boris Feld <boris.feld@octobus.net>
parents: 33252
diff changeset
   346
    by markers).
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   347
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   348
    The 'closest' mode respect the repoview filtering. For example, without
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   349
    filter it will stop at the first locally known changeset, with 'visible'
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   350
    filter it will stop on visible changesets).
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   351
33272
df90f4d6c609 obsolete: small doc update for 'successorssets'
Boris Feld <boris.feld@octobus.net>
parents: 33252
diff changeset
   352
    The optional `cache` parameter is a dictionary that may contains
df90f4d6c609 obsolete: small doc update for 'successorssets'
Boris Feld <boris.feld@octobus.net>
parents: 33252
diff changeset
   353
    precomputed successors sets. It is meant to reuse the computation of a
df90f4d6c609 obsolete: small doc update for 'successorssets'
Boris Feld <boris.feld@octobus.net>
parents: 33252
diff changeset
   354
    previous call to `successorssets` when multiple calls are made at the same
df90f4d6c609 obsolete: small doc update for 'successorssets'
Boris Feld <boris.feld@octobus.net>
parents: 33252
diff changeset
   355
    time. The cache dictionary is updated in place. The caller is responsible
df90f4d6c609 obsolete: small doc update for 'successorssets'
Boris Feld <boris.feld@octobus.net>
parents: 33252
diff changeset
   356
    for its life span. Code that makes multiple calls to `successorssets`
df90f4d6c609 obsolete: small doc update for 'successorssets'
Boris Feld <boris.feld@octobus.net>
parents: 33252
diff changeset
   357
    *should* use this cache mechanism or risk a performance hit.
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   358
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   359
    Since results are different depending of the 'closest' most, the same cache
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   360
    cannot be reused for both mode.
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   361
    """
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   362
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   363
    succmarkers = repo.obsstore.successors
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   364
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   365
    # Stack of nodes we search successors sets for
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   366
    toproceed = [initialnode]
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   367
    # set version of above list for fast loop detection
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   368
    # element added to "toproceed" must be added here
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   369
    stackedset = set(toproceed)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   370
    if cache is None:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   371
        cache = {}
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   372
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   373
    # This while loop is the flattened version of a recursive search for
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   374
    # successors sets
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   375
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   376
    # def successorssets(x):
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   377
    #    successors = directsuccessors(x)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   378
    #    ss = [[]]
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   379
    #    for succ in directsuccessors(x):
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   380
    #        # product as in itertools cartesian product
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   381
    #        ss = product(ss, successorssets(succ))
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   382
    #    return ss
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   383
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   384
    # But we can not use plain recursive calls here:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   385
    # - that would blow the python call stack
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   386
    # - obsolescence markers may have cycles, we need to handle them.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   387
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   388
    # The `toproceed` list act as our call stack. Every node we search
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   389
    # successors set for are stacked there.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   390
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   391
    # The `stackedset` is set version of this stack used to check if a node is
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   392
    # already stacked. This check is used to detect cycles and prevent infinite
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   393
    # loop.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   394
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   395
    # successors set of all nodes are stored in the `cache` dictionary.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   396
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   397
    # After this while loop ends we use the cache to return the successors sets
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   398
    # for the node requested by the caller.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   399
    while toproceed:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   400
        # Every iteration tries to compute the successors sets of the topmost
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   401
        # node of the stack: CURRENT.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   402
        #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   403
        # There are four possible outcomes:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   404
        #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   405
        # 1) We already know the successors sets of CURRENT:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   406
        #    -> mission accomplished, pop it from the stack.
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   407
        # 2) Stop the walk:
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   408
        #    default case: Node is not obsolete
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   409
        #    closest case: Node is known at this repo filter level
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   410
        #      -> the node is its own successors sets. Add it to the cache.
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   411
        # 3) We do not know successors set of direct successors of CURRENT:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   412
        #    -> We add those successors to the stack.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   413
        # 4) We know successors sets of all direct successors of CURRENT:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   414
        #    -> We can compute CURRENT successors set and add it to the
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   415
        #       cache.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   416
        #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   417
        current = toproceed[-1]
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   418
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   419
        # case 2 condition is a bit hairy because of closest,
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   420
        # we compute it on its own
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   421
        case2condition =  ((current not in succmarkers)
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   422
                           or (closest and current != initialnode
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   423
                               and current in repo))
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   424
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   425
        if current in cache:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   426
            # case (1): We already know the successors sets
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   427
            stackedset.remove(toproceed.pop())
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   428
        elif case2condition:
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   429
            # case (2): end of walk.
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   430
            if current in repo:
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   431
                # We have a valid successors.
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   432
                cache[current] = [(current,)]
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   433
            else:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   434
                # Final obsolete version is unknown locally.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   435
                # Do not count that as a valid successors
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   436
                cache[current] = []
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   437
        else:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   438
            # cases (3) and (4)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   439
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   440
            # We proceed in two phases. Phase 1 aims to distinguish case (3)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   441
            # from case (4):
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   442
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   443
            #     For each direct successors of CURRENT, we check whether its
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   444
            #     successors sets are known. If they are not, we stack the
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   445
            #     unknown node and proceed to the next iteration of the while
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   446
            #     loop. (case 3)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   447
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   448
            #     During this step, we may detect obsolescence cycles: a node
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   449
            #     with unknown successors sets but already in the call stack.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   450
            #     In such a situation, we arbitrary set the successors sets of
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   451
            #     the node to nothing (node pruned) to break the cycle.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   452
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   453
            #     If no break was encountered we proceed to phase 2.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   454
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   455
            # Phase 2 computes successors sets of CURRENT (case 4); see details
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   456
            # in phase 2 itself.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   457
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   458
            # Note the two levels of iteration in each phase.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   459
            # - The first one handles obsolescence markers using CURRENT as
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   460
            #   precursor (successors markers of CURRENT).
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   461
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   462
            #   Having multiple entry here means divergence.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   463
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   464
            # - The second one handles successors defined in each marker.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   465
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   466
            #   Having none means pruned node, multiple successors means split,
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   467
            #   single successors are standard replacement.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   468
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   469
            for mark in sorted(succmarkers[current]):
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   470
                for suc in mark[1]:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   471
                    if suc not in cache:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   472
                        if suc in stackedset:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   473
                            # cycle breaking
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   474
                            cache[suc] = []
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   475
                        else:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   476
                            # case (3) If we have not computed successors sets
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   477
                            # of one of those successors we add it to the
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   478
                            # `toproceed` stack and stop all work for this
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   479
                            # iteration.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   480
                            toproceed.append(suc)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   481
                            stackedset.add(suc)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   482
                            break
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   483
                else:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   484
                    continue
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   485
                break
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   486
            else:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   487
                # case (4): we know all successors sets of all direct
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   488
                # successors
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   489
                #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   490
                # Successors set contributed by each marker depends on the
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   491
                # successors sets of all its "successors" node.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   492
                #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   493
                # Each different marker is a divergence in the obsolescence
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   494
                # history. It contributes successors sets distinct from other
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   495
                # markers.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   496
                #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   497
                # Within a marker, a successor may have divergent successors
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   498
                # sets. In such a case, the marker will contribute multiple
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   499
                # divergent successors sets. If multiple successors have
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   500
                # divergent successors sets, a Cartesian product is used.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   501
                #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   502
                # At the end we post-process successors sets to remove
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   503
                # duplicated entry and successors set that are strict subset of
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   504
                # another one.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   505
                succssets = []
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   506
                for mark in sorted(succmarkers[current]):
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   507
                    # successors sets contributed by this marker
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   508
                    markss = [[]]
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   509
                    for suc in mark[1]:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   510
                        # cardinal product with previous successors
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   511
                        productresult = []
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   512
                        for prefix in markss:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   513
                            for suffix in cache[suc]:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   514
                                newss = list(prefix)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   515
                                for part in suffix:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   516
                                    # do not duplicated entry in successors set
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   517
                                    # first entry wins.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   518
                                    if part not in newss:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   519
                                        newss.append(part)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   520
                                productresult.append(newss)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   521
                        markss = productresult
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   522
                    succssets.extend(markss)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   523
                # remove duplicated and subset
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   524
                seen = []
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   525
                final = []
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   526
                candidate = sorted(((set(s), s) for s in succssets if s),
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   527
                                   key=lambda x: len(x[1]), reverse=True)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   528
                for setversion, listversion in candidate:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   529
                    for seenset in seen:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   530
                        if setversion.issubset(seenset):
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   531
                            break
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   532
                    else:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   533
                        final.append(listversion)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   534
                        seen.append(setversion)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   535
                final.reverse() # put small successors set first
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   536
                cache[current] = final
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   537
    return cache[initialnode]