mercurial/obsutil.py
author Gregory Szorc <gregory.szorc@gmail.com>
Wed, 21 Feb 2018 13:41:20 -0800
changeset 36362 01e29e885600
parent 35893 78f33dedadd0
child 36607 c6061cadb400
permissions -rw-r--r--
util: add a file object proxy that can read at most N bytes Sometimes we have data of a known size within a stream. For performance reasons, we don't want to pre-read this data (we want to allow consumers to read on demand). For simplicitly reasons, we don't want callers to necessarily know their data is coming from within an outer stream and there is a limit to how much they should read. The class introduced by this commit provides a very simple proxy around an underlying file object that allows the consumer to .read() up to N bytes from the file object. Attempts to read past this many bytes results in a simulated EOF. Differential Revision: https://phab.mercurial-scm.org/D2377
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
34420
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
    10
import re
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
    11
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
    12
from .i18n import _
33252
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
    13
from . import (
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
    14
    node as nodemod,
33252
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
    15
    phases,
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
    16
    util,
33252
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
    17
)
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
    18
33148
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    19
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
    20
    """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
    21
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    22
    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
    23
        # 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
    24
        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
    25
        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
    26
        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
    27
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    28
    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
    29
        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
    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 __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
    32
        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
    33
            return False
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    34
        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
    35
33731
2cb442bc1a76 obsmarker: rename precnode into prednode
Boris Feld <boris.feld@octobus.net>
parents: 33713
diff changeset
    36
    def prednode(self):
2cb442bc1a76 obsmarker: rename precnode into prednode
Boris Feld <boris.feld@octobus.net>
parents: 33713
diff changeset
    37
        """Predecessor changeset node identifier"""
33148
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    38
        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
    39
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    40
    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
    41
        """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
    42
        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
    43
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    44
    def parentnodes(self):
33731
2cb442bc1a76 obsmarker: rename precnode into prednode
Boris Feld <boris.feld@octobus.net>
parents: 33713
diff changeset
    45
        """Parents of the predecessors (None if not recorded)"""
33148
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    46
        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
    47
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    48
    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
    49
        """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
    50
        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
    51
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    52
    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
    53
        """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
    54
        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
    55
4e30168d7939 obsutil: move the 'marker' class to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33146
diff changeset
    56
    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
    57
        """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
    58
        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
    59
33149
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    60
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
    61
    """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
    62
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    63
    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
    64
    returned"""
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    65
    if nodes is None:
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    66
        rawmarkers = repo.obsstore
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    67
    elif exclusive:
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    68
        rawmarkers = exclusivemarkers(repo, nodes)
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    69
    else:
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    70
        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
    71
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    72
    for markerdata in rawmarkers:
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    73
        yield marker(repo, markerdata)
a14e2e7f7d1f obsutil: move 'getmarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33148
diff changeset
    74
32879
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    75
def closestpredecessors(repo, nodeid):
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    76
    """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
    77
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    78
    This function respect the repoview filtering, filtered revision will be
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    79
    considered missing.
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
33733
d5acd967f95a obsstore: rename precursors into predecessors
Boris Feld <boris.feld@octobus.net>
parents: 33731
diff changeset
    82
    precursors = repo.obsstore.predecessors
32879
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    83
    stack = [nodeid]
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    84
    seen = set(stack)
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    85
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    86
    while stack:
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    87
        current = stack.pop()
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    88
        currentpreccs = precursors.get(current, ())
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    89
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    90
        for prec in currentpreccs:
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    91
            precnodeid = prec[0]
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
            # Basic cycle protection
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    94
            if precnodeid in seen:
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    95
                continue
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    96
            seen.add(precnodeid)
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    97
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    98
            if precnodeid in repo:
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
    99
                yield precnodeid
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
   100
            else:
1858fc2327ef template: add predecessors template
Boris Feld <boris.feld@octobus.net>
parents:
diff changeset
   101
                stack.append(precnodeid)
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   102
33735
e6d8ee3c9ec3 obsutil: rename allprecursors into allpredecessors
Boris Feld <boris.feld@octobus.net>
parents: 33733
diff changeset
   103
def allpredecessors(obsstore, nodes, ignoreflags=0):
33144
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   104
    """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
   105
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   106
    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
   107
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   108
    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
   109
    initial nodes too."""
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   110
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   111
    remaining = set(nodes)
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   112
    seen = set(remaining)
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   113
    while remaining:
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   114
        current = remaining.pop()
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   115
        yield current
33733
d5acd967f95a obsstore: rename precursors into predecessors
Boris Feld <boris.feld@octobus.net>
parents: 33731
diff changeset
   116
        for mark in obsstore.predecessors.get(current, ()):
33144
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   117
            # 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
   118
            if mark[2] & ignoreflags:
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   119
                continue
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   120
            suc = mark[0]
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   121
            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
   122
                seen.add(suc)
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   123
                remaining.add(suc)
d0e5bf12f314 obsutil: move 'allprecursors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33143
diff changeset
   124
33145
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   125
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
   126
    """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
   127
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   128
    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
   129
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   130
    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
   131
    initial nodes too."""
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   132
    remaining = set(nodes)
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   133
    seen = set(remaining)
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   134
    while remaining:
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   135
        current = remaining.pop()
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   136
        yield current
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   137
        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
   138
            # 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
   139
            if mark[2] & ignoreflags:
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   140
                continue
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   141
            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
   142
                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
   143
                    seen.add(suc)
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   144
                    remaining.add(suc)
0a370b93cca2 obsutil: move 'allsuccessors' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33144
diff changeset
   145
33143
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   146
def _filterprunes(markers):
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   147
    """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
   148
    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
   149
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   150
def exclusivemarkers(repo, nodes):
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   151
    """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
   152
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   153
    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
   154
    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
   155
    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
   156
    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
   157
    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
   158
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   159
    For example:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   160
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   161
        # (A0 rewritten as A1)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   162
        #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   163
        # 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
   164
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   165
        or
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   166
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   167
        # (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
   168
        #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   169
        # <-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
   170
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   171
        or
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   172
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   173
        # (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
   174
        #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   175
        #          <-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
   176
        #        /
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   177
        # <-1- A0
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   178
        #        \
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   179
        #         <-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
   180
        #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   181
        # in addition:
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
        #  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
   184
        #  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
   185
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   186
        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
   187
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   188
    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
   189
    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
   190
    "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
   191
    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
   192
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   193
    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
   194
    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
   195
    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
   196
    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
   197
    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
   198
    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
   199
    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
   200
    the pruned changesets.
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   201
    """
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   202
    # 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
   203
    # 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
   204
    unfi = repo.unfiltered()
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   205
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   206
    # 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
   207
    nm = unfi.changelog.nodemap
33733
d5acd967f95a obsstore: rename precursors into predecessors
Boris Feld <boris.feld@octobus.net>
parents: 33731
diff changeset
   208
    precursorsmarkers = unfi.obsstore.predecessors
33143
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   209
    successormarkers = unfi.obsstore.successors
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   210
    childrenmarkers = unfi.obsstore.children
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   211
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   212
    # 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
   213
    exclmarkers = set()
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   214
    # 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
   215
    nodes = set(nodes)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   216
    # 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
   217
    #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   218
    # 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
   219
    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
   220
    stack.sort()
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   221
    # nodes already stacked
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   222
    seennodes = set(stack)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   223
    while stack:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   224
        current = stack.pop()
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   225
        # fetch precursors markers
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   226
        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
   227
        # 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
   228
        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
   229
            if not mark[1]:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   230
                markers.append(mark)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   231
        # 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
   232
        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
   233
            if not mark[1]:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   234
                markers.append(mark)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   235
        # traverse the markers
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   236
        for mark in markers:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   237
            if mark in exclmarkers:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   238
                # markers already selected
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   239
                continue
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   240
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   241
            # 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
   242
            #
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   243
            # (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
   244
            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
   245
                exclmarkers.add(mark)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   246
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   247
            # 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
   248
            prec = mark[0]
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   249
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   250
            # 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
   251
            if prec in seennodes:
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   252
                continue
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   253
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   254
            # 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
   255
            known = prec in nm
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   256
            # 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
   257
            # stop here.
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   258
            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
   259
                continue
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   260
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   261
            # 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
   262
            # 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
   263
            # 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
   264
            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
   265
            if precmarkers.issubset(exclmarkers):
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   266
                seennodes.add(prec)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   267
                stack.append(prec)
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   268
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   269
    return exclmarkers
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33142
diff changeset
   270
33146
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   271
def foreground(repo, nodes):
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   272
    """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
   273
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   274
    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
   275
    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
   276
    augmented with obsolescence information.
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   277
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   278
    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
   279
    """
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   280
    repo = repo.unfiltered()
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   281
    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
   282
    if repo.obsstore:
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   283
        # 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
   284
        # 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
   285
        nm = repo.changelog.nodemap
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   286
        plen = -1
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   287
        # 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
   288
        while len(foreground) != plen:
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   289
            plen = len(foreground)
7017567ebdf2 obsutil: move 'foreground' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33145
diff changeset
   290
            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
   291
            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
   292
            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
   293
            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
   294
            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
   295
    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
   296
34422
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   297
# effectflag field
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   298
#
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   299
# Effect-flag is a 1-byte bit field used to store what changed between a
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   300
# changeset and its successor(s).
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   301
#
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   302
# The effect flag is stored in obs-markers metadata while we iterate on the
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   303
# information design. That's why we have the EFFECTFLAGFIELD. If we come up
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   304
# with an incompatible design for effect flag, we can store a new design under
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   305
# another field name so we don't break readers. We plan to extend the existing
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   306
# obsmarkers bit-field when the effect flag design will be stabilized.
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   307
#
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   308
# The effect-flag is placed behind an experimental flag
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   309
# `effect-flags` set to off by default.
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   310
#
2fd06499dc8e effectflag: document effect flag
Boris Feld <boris.feld@octobus.net>
parents: 34421
diff changeset
   311
34413
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   312
EFFECTFLAGFIELD = "ef1"
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   313
34415
51aadc0d0da2 effectflag: detect when description changed
Boris Feld <boris.feld@octobus.net>
parents: 34413
diff changeset
   314
DESCCHANGED = 1 << 0 # action changed the description
34420
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   315
METACHANGED = 1 << 1 # action change the meta
34421
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   316
DIFFCHANGED = 1 << 3 # action change diff introduced by the changeset
34419
fa26f5891e68 effectflag: detect when parents changed
Boris Feld <boris.feld@octobus.net>
parents: 34418
diff changeset
   317
PARENTCHANGED = 1 << 2 # action change the parent
34416
55ef17ec8e59 effectflag: detect when user changed
Boris Feld <boris.feld@octobus.net>
parents: 34415
diff changeset
   318
USERCHANGED = 1 << 4 # the user changed
34417
54af8de9bd09 effectflag: detect when date changed
Boris Feld <boris.feld@octobus.net>
parents: 34416
diff changeset
   319
DATECHANGED = 1 << 5 # the date changed
34418
57980af73cfa effectflag: detect when branch changed
Boris Feld <boris.feld@octobus.net>
parents: 34417
diff changeset
   320
BRANCHCHANGED = 1 << 6 # the branch changed
34415
51aadc0d0da2 effectflag: detect when description changed
Boris Feld <boris.feld@octobus.net>
parents: 34413
diff changeset
   321
34420
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   322
METABLACKLIST = [
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   323
    re.compile('^branch$'),
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   324
    re.compile('^.*-source$'),
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   325
    re.compile('^.*_source$'),
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   326
    re.compile('^source$'),
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   327
]
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   328
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   329
def metanotblacklisted(metaitem):
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   330
    """ Check that the key of a meta item (extrakey, extravalue) does not
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   331
    match at least one of the blacklist pattern
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   332
    """
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   333
    metakey = metaitem[0]
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   334
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   335
    return not any(pattern.match(metakey) for pattern in METABLACKLIST)
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   336
34421
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   337
def _prepare_hunk(hunk):
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   338
    """Drop all information but the username and patch"""
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   339
    cleanhunk = []
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   340
    for line in hunk.splitlines():
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   341
        if line.startswith(b'# User') or not line.startswith(b'#'):
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   342
            if line.startswith(b'@@'):
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   343
                line = b'@@\n'
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   344
            cleanhunk.append(line)
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   345
    return cleanhunk
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   346
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   347
def _getdifflines(iterdiff):
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   348
    """return a cleaned up lines"""
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   349
    lines = next(iterdiff, None)
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   350
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   351
    if lines is None:
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   352
        return lines
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   353
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   354
    return _prepare_hunk(lines)
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   355
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   356
def _cmpdiff(leftctx, rightctx):
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   357
    """return True if both ctx introduce the "same diff"
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   358
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   359
    This is a first and basic implementation, with many shortcoming.
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   360
    """
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   361
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   362
    # Leftctx or right ctx might be filtered, so we need to use the contexts
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   363
    # with an unfiltered repository to safely compute the diff
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   364
    leftunfi = leftctx._repo.unfiltered()[leftctx.rev()]
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   365
    leftdiff = leftunfi.diff(git=1)
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   366
    rightunfi = rightctx._repo.unfiltered()[rightctx.rev()]
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   367
    rightdiff = rightunfi.diff(git=1)
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   368
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   369
    left, right = (0, 0)
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   370
    while None not in (left, right):
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   371
        left = _getdifflines(leftdiff)
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   372
        right = _getdifflines(rightdiff)
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   373
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   374
        if left != right:
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   375
            return False
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   376
    return True
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   377
34413
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   378
def geteffectflag(relation):
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   379
    """ From an obs-marker relation, compute what changed between the
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   380
    predecessor and the successor.
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   381
    """
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   382
    effects = 0
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   383
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   384
    source = relation[0]
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   385
34415
51aadc0d0da2 effectflag: detect when description changed
Boris Feld <boris.feld@octobus.net>
parents: 34413
diff changeset
   386
    for changectx in relation[1]:
51aadc0d0da2 effectflag: detect when description changed
Boris Feld <boris.feld@octobus.net>
parents: 34413
diff changeset
   387
        # Check if description has changed
51aadc0d0da2 effectflag: detect when description changed
Boris Feld <boris.feld@octobus.net>
parents: 34413
diff changeset
   388
        if changectx.description() != source.description():
51aadc0d0da2 effectflag: detect when description changed
Boris Feld <boris.feld@octobus.net>
parents: 34413
diff changeset
   389
            effects |= DESCCHANGED
51aadc0d0da2 effectflag: detect when description changed
Boris Feld <boris.feld@octobus.net>
parents: 34413
diff changeset
   390
34416
55ef17ec8e59 effectflag: detect when user changed
Boris Feld <boris.feld@octobus.net>
parents: 34415
diff changeset
   391
        # Check if user has changed
55ef17ec8e59 effectflag: detect when user changed
Boris Feld <boris.feld@octobus.net>
parents: 34415
diff changeset
   392
        if changectx.user() != source.user():
55ef17ec8e59 effectflag: detect when user changed
Boris Feld <boris.feld@octobus.net>
parents: 34415
diff changeset
   393
            effects |= USERCHANGED
55ef17ec8e59 effectflag: detect when user changed
Boris Feld <boris.feld@octobus.net>
parents: 34415
diff changeset
   394
34417
54af8de9bd09 effectflag: detect when date changed
Boris Feld <boris.feld@octobus.net>
parents: 34416
diff changeset
   395
        # Check if date has changed
54af8de9bd09 effectflag: detect when date changed
Boris Feld <boris.feld@octobus.net>
parents: 34416
diff changeset
   396
        if changectx.date() != source.date():
54af8de9bd09 effectflag: detect when date changed
Boris Feld <boris.feld@octobus.net>
parents: 34416
diff changeset
   397
            effects |= DATECHANGED
54af8de9bd09 effectflag: detect when date changed
Boris Feld <boris.feld@octobus.net>
parents: 34416
diff changeset
   398
34418
57980af73cfa effectflag: detect when branch changed
Boris Feld <boris.feld@octobus.net>
parents: 34417
diff changeset
   399
        # Check if branch has changed
57980af73cfa effectflag: detect when branch changed
Boris Feld <boris.feld@octobus.net>
parents: 34417
diff changeset
   400
        if changectx.branch() != source.branch():
57980af73cfa effectflag: detect when branch changed
Boris Feld <boris.feld@octobus.net>
parents: 34417
diff changeset
   401
            effects |= BRANCHCHANGED
57980af73cfa effectflag: detect when branch changed
Boris Feld <boris.feld@octobus.net>
parents: 34417
diff changeset
   402
34419
fa26f5891e68 effectflag: detect when parents changed
Boris Feld <boris.feld@octobus.net>
parents: 34418
diff changeset
   403
        # Check if at least one of the parent has changed
fa26f5891e68 effectflag: detect when parents changed
Boris Feld <boris.feld@octobus.net>
parents: 34418
diff changeset
   404
        if changectx.parents() != source.parents():
fa26f5891e68 effectflag: detect when parents changed
Boris Feld <boris.feld@octobus.net>
parents: 34418
diff changeset
   405
            effects |= PARENTCHANGED
fa26f5891e68 effectflag: detect when parents changed
Boris Feld <boris.feld@octobus.net>
parents: 34418
diff changeset
   406
34420
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   407
        # Check if other meta has changed
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   408
        changeextra = changectx.extra().items()
35875
c0a6733f7e7a obsutil: work around filter() being a generator in Python 3
Augie Fackler <augie@google.com>
parents: 35610
diff changeset
   409
        ctxmeta = list(filter(metanotblacklisted, changeextra))
34420
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   410
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   411
        sourceextra = source.extra().items()
35875
c0a6733f7e7a obsutil: work around filter() being a generator in Python 3
Augie Fackler <augie@google.com>
parents: 35610
diff changeset
   412
        srcmeta = list(filter(metanotblacklisted, sourceextra))
34420
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   413
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   414
        if ctxmeta != srcmeta:
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   415
            effects |= METACHANGED
95759620d492 effectflag: detect when meta changed
Boris Feld <boris.feld@octobus.net>
parents: 34419
diff changeset
   416
34421
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   417
        # Check if the diff has changed
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   418
        if not _cmpdiff(source, changectx):
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   419
            effects |= DIFFCHANGED
187bc224554a effectflag: detect when diff changed
Boris Feld <boris.feld@octobus.net>
parents: 34420
diff changeset
   420
34413
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   421
    return effects
014d467f9d08 effectflag: store an empty effect flag for the moment
Boris Feld <boris.feld@octobus.net>
parents: 34287
diff changeset
   422
33252
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   423
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
   424
    """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
   425
    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
   426
    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
   427
    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
   428
    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
   429
    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
   430
    addedrevs = tr.changes.get('revs')
35308
137a08d82232 transaction: build changes['revs'] as range instead of a set
Joerg Sonnenberger <joerg@bec.de>
parents: 35010
diff changeset
   431
    seenrevs = set()
33252
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   432
    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
   433
    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
   434
        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
   435
        rev = torev(node)
35308
137a08d82232 transaction: build changes['revs'] as range instead of a set
Joerg Sonnenberger <joerg@bec.de>
parents: 35010
diff changeset
   436
        if rev is None or rev in seenrevs or rev in addedrevs:
33252
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   437
            continue
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   438
        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
   439
        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
   440
            continue
33713
888f24810ea2 obsutil: defend against succsmarkers() returning None
Augie Fackler <augie@google.com>
parents: 33274
diff changeset
   441
        if set(succsmarkers(node) or []).issubset(addedmarkers):
33252
53b3a1968aa6 obsolete: reports the number of local changeset obsoleted when unbundling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   442
            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
   443
    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
   444
33909
84f72072bde6 obsolete: introduce a _succs class
Boris Feld <boris.feld@octobus.net>
parents: 33857
diff changeset
   445
class _succs(list):
84f72072bde6 obsolete: introduce a _succs class
Boris Feld <boris.feld@octobus.net>
parents: 33857
diff changeset
   446
    """small class to represent a successors with some metadata about it"""
84f72072bde6 obsolete: introduce a _succs class
Boris Feld <boris.feld@octobus.net>
parents: 33857
diff changeset
   447
33911
34e10e09afa5 obsolete: track markers in _succs
Boris Feld <boris.feld@octobus.net>
parents: 33910
diff changeset
   448
    def __init__(self, *args, **kwargs):
34e10e09afa5 obsolete: track markers in _succs
Boris Feld <boris.feld@octobus.net>
parents: 33910
diff changeset
   449
        super(_succs, self).__init__(*args, **kwargs)
34e10e09afa5 obsolete: track markers in _succs
Boris Feld <boris.feld@octobus.net>
parents: 33910
diff changeset
   450
        self.markers = set()
34e10e09afa5 obsolete: track markers in _succs
Boris Feld <boris.feld@octobus.net>
parents: 33910
diff changeset
   451
33910
dba493981284 obsolete: add an explicit '_succs.copy()' method
Boris Feld <boris.feld@octobus.net>
parents: 33909
diff changeset
   452
    def copy(self):
33911
34e10e09afa5 obsolete: track markers in _succs
Boris Feld <boris.feld@octobus.net>
parents: 33910
diff changeset
   453
        new = _succs(self)
34e10e09afa5 obsolete: track markers in _succs
Boris Feld <boris.feld@octobus.net>
parents: 33910
diff changeset
   454
        new.markers = self.markers.copy()
34e10e09afa5 obsolete: track markers in _succs
Boris Feld <boris.feld@octobus.net>
parents: 33910
diff changeset
   455
        return new
33910
dba493981284 obsolete: add an explicit '_succs.copy()' method
Boris Feld <boris.feld@octobus.net>
parents: 33909
diff changeset
   456
33941
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   457
    @util.propertycache
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   458
    def _set(self):
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   459
        # immutable
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   460
        return set(self)
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   461
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   462
    def canmerge(self, other):
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   463
        return self._set.issubset(other._set)
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   464
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   465
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
   466
    """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
   467
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   468
    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
   469
    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
   470
    replacement. By default, the successors set contains non-obsolete
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   471
    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
   472
    '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
   473
    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
   474
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   475
    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
   476
    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
   477
    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
   478
    (see below).
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   479
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   480
    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
   481
    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
   482
    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
   483
    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
   484
    [(A',)] or [], respectively.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   485
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   486
    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
   487
    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
   488
    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
   489
    (A'')].
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   490
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   491
    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
   492
    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
   493
    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
   494
33272
df90f4d6c609 obsolete: small doc update for 'successorssets'
Boris Feld <boris.feld@octobus.net>
parents: 33252
diff changeset
   495
    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
   496
    (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
   497
    by markers).
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   498
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   499
    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
   500
    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
   501
    filter it will stop on visible changesets).
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   502
33272
df90f4d6c609 obsolete: small doc update for 'successorssets'
Boris Feld <boris.feld@octobus.net>
parents: 33252
diff changeset
   503
    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
   504
    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
   505
    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
   506
    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
   507
    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
   508
    *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
   509
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   510
    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
   511
    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
   512
    """
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   513
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   514
    succmarkers = repo.obsstore.successors
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   515
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   516
    # 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
   517
    toproceed = [initialnode]
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   518
    # 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
   519
    # 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
   520
    stackedset = set(toproceed)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   521
    if cache is None:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   522
        cache = {}
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   523
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   524
    # 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
   525
    # successors sets
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   526
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   527
    # def successorssets(x):
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   528
    #    successors = directsuccessors(x)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   529
    #    ss = [[]]
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   530
    #    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
   531
    #        # 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
   532
    #        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
   533
    #    return ss
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   534
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   535
    # 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
   536
    # - 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
   537
    # - 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
   538
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   539
    # 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
   540
    # 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
   541
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   542
    # 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
   543
    # 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
   544
    # loop.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   545
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   546
    # 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
   547
    #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   548
    # 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
   549
    # 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
   550
    while toproceed:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   551
        # 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
   552
        # 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
   553
        #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   554
        # 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
   555
        #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   556
        # 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
   557
        #    -> mission accomplished, pop it from the stack.
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   558
        # 2) Stop the walk:
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   559
        #    default case: Node is not obsolete
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   560
        #    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
   561
        #      -> 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
   562
        # 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
   563
        #    -> 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
   564
        # 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
   565
        #    -> 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
   566
        #       cache.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   567
        #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   568
        current = toproceed[-1]
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   569
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   570
        # 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
   571
        # we compute it on its own
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   572
        case2condition =  ((current not in succmarkers)
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   573
                           or (closest and current != initialnode
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   574
                               and current in repo))
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   575
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   576
        if current in cache:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   577
            # 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
   578
            stackedset.remove(toproceed.pop())
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   579
        elif case2condition:
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   580
            # 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
   581
            if current in repo:
33274
68f3e819d41d obsolete: closest divergent support
Boris Feld <boris.feld@octobus.net>
parents: 33272
diff changeset
   582
                # We have a valid successors.
33909
84f72072bde6 obsolete: introduce a _succs class
Boris Feld <boris.feld@octobus.net>
parents: 33857
diff changeset
   583
                cache[current] = [_succs((current,))]
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   584
            else:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   585
                # 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
   586
                # 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
   587
                cache[current] = []
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   588
        else:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   589
            # cases (3) and (4)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   590
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   591
            # 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
   592
            # from case (4):
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   593
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   594
            #     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
   595
            #     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
   596
            #     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
   597
            #     loop. (case 3)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   598
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   599
            #     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
   600
            #     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
   601
            #     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
   602
            #     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
   603
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   604
            #     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
   605
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   606
            # 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
   607
            # in phase 2 itself.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   608
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   609
            # 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
   610
            # - 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
   611
            #   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
   612
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   613
            #   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
   614
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   615
            # - 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
   616
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   617
            #   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
   618
            #   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
   619
            #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   620
            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
   621
                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
   622
                    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
   623
                        if suc in stackedset:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   624
                            # cycle breaking
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   625
                            cache[suc] = []
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   626
                        else:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   627
                            # 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
   628
                            # 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
   629
                            # `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
   630
                            # iteration.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   631
                            toproceed.append(suc)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   632
                            stackedset.add(suc)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   633
                            break
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   634
                else:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   635
                    continue
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   636
                break
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   637
            else:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   638
                # 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
   639
                # successors
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   640
                #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   641
                # 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
   642
                # 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
   643
                #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   644
                # 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
   645
                # 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
   646
                # markers.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   647
                #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   648
                # 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
   649
                # 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
   650
                # 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
   651
                # 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
   652
                #
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   653
                # 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
   654
                # 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
   655
                # another one.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   656
                succssets = []
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   657
                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
   658
                    # successors sets contributed by this marker
33911
34e10e09afa5 obsolete: track markers in _succs
Boris Feld <boris.feld@octobus.net>
parents: 33910
diff changeset
   659
                    base = _succs()
34e10e09afa5 obsolete: track markers in _succs
Boris Feld <boris.feld@octobus.net>
parents: 33910
diff changeset
   660
                    base.markers.add(mark)
34e10e09afa5 obsolete: track markers in _succs
Boris Feld <boris.feld@octobus.net>
parents: 33910
diff changeset
   661
                    markss = [base]
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   662
                    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
   663
                        # 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
   664
                        productresult = []
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   665
                        for prefix in markss:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   666
                            for suffix in cache[suc]:
33910
dba493981284 obsolete: add an explicit '_succs.copy()' method
Boris Feld <boris.feld@octobus.net>
parents: 33909
diff changeset
   667
                                newss = prefix.copy()
33911
34e10e09afa5 obsolete: track markers in _succs
Boris Feld <boris.feld@octobus.net>
parents: 33910
diff changeset
   668
                                newss.markers.update(suffix.markers)
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   669
                                for part in suffix:
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   670
                                    # 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
   671
                                    # first entry wins.
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   672
                                    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
   673
                                        newss.append(part)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   674
                                productresult.append(newss)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   675
                        markss = productresult
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   676
                    succssets.extend(markss)
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   677
                # remove duplicated and subset
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   678
                seen = []
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   679
                final = []
33942
54c21114e41d obsolete: fix old typo
Boris Feld <boris.feld@octobus.net>
parents: 33941
diff changeset
   680
                candidates = sorted((s for s in succssets if s),
54c21114e41d obsolete: fix old typo
Boris Feld <boris.feld@octobus.net>
parents: 33941
diff changeset
   681
                                    key=len, reverse=True)
54c21114e41d obsolete: fix old typo
Boris Feld <boris.feld@octobus.net>
parents: 33941
diff changeset
   682
                for cand in candidates:
33941
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   683
                    for seensuccs in seen:
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   684
                        if cand.canmerge(seensuccs):
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   685
                            seensuccs.markers.update(cand.markers)
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   686
                            break
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   687
                    else:
33941
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   688
                        final.append(cand)
c0bbaefc2c5a obsolete: move merge logic on the smaller object
Boris Feld <boris.feld@octobus.net>
parents: 33912
diff changeset
   689
                        seen.append(cand)
33142
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   690
                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
   691
                cache[current] = final
4f49810a1011 obsutil: move 'successorssets' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32879
diff changeset
   692
    return cache[initialnode]
33912
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   693
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   694
def successorsandmarkers(repo, ctx):
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   695
    """compute the raw data needed for computing obsfate
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   696
    Returns a list of dict, one dict per successors set
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   697
    """
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   698
    if not ctx.obsolete():
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   699
        return None
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   700
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   701
    ssets = successorssets(repo, ctx.node(), closest=True)
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   702
33996
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   703
    # closestsuccessors returns an empty list for pruned revisions, remap it
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   704
    # into a list containing an empty list for future processing
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   705
    if ssets == []:
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   706
        ssets = [[]]
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   707
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   708
    # Try to recover pruned markers
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   709
    succsmap = repo.obsstore.successors
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   710
    fullsuccessorsets = [] # successor set + markers
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   711
    for sset in ssets:
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   712
        if sset:
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   713
            fullsuccessorsets.append(sset)
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   714
        else:
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   715
            # successorsset return an empty set() when ctx or one of its
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   716
            # successors is pruned.
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   717
            # In this case, walk the obs-markers tree again starting with ctx
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   718
            # and find the relevant pruning obs-makers, the ones without
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   719
            # successors.
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   720
            # Having these markers allow us to compute some information about
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   721
            # its fate, like who pruned this changeset and when.
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   722
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   723
            # XXX we do not catch all prune markers (eg rewritten then pruned)
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   724
            # (fix me later)
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   725
            foundany = False
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   726
            for mark in succsmap.get(ctx.node(), ()):
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   727
                if not mark[1]:
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   728
                    foundany = True
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   729
                    sset = _succs()
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   730
                    sset.markers.add(mark)
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   731
                    fullsuccessorsets.append(sset)
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   732
            if not foundany:
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   733
                fullsuccessorsets.append(_succs())
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   734
33912
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   735
    values = []
33996
98fa777cd7a1 template: better prune support in obsfate
Boris Feld <boris.feld@octobus.net>
parents: 33995
diff changeset
   736
    for sset in fullsuccessorsets:
33912
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   737
        values.append({'successors': sset, 'markers': sset.markers})
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   738
e278d6d2d7d2 template: add minimal obsfate template function
Boris Feld <boris.feld@octobus.net>
parents: 33911
diff changeset
   739
    return values
33993
3d0f8918351b template: compute verb in obsfateverb
Boris Feld <boris.feld@octobus.net>
parents: 33942
diff changeset
   740
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   741
def _getobsfate(successorssets):
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   742
    """ Compute a changeset obsolescence fate based on its successorssets.
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   743
    Successors can be the tipmost ones or the immediate ones. This function
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   744
    return values are not meant to be shown directly to users, it is meant to
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   745
    be used by internal functions only.
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   746
    Returns one fate from the following values:
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   747
    - pruned
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   748
    - diverged
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   749
    - superseded
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   750
    - superseded_split
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   751
    """
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   752
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   753
    if len(successorssets) == 0:
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   754
        # The commit has been pruned
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   755
        return 'pruned'
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   756
    elif len(successorssets) > 1:
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   757
        return 'diverged'
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   758
    else:
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   759
        # No divergence, only one set of successors
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   760
        successors = successorssets[0]
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   761
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   762
        if len(successors) == 1:
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   763
            return 'superseded'
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   764
        else:
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   765
            return 'superseded_split'
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   766
35010
b81ad5b78a81 obsfate: makes successorsetverb takes the markers as argument
Boris Feld <boris.feld@octobus.net>
parents: 34873
diff changeset
   767
def obsfateverb(successorset, markers):
b81ad5b78a81 obsfate: makes successorsetverb takes the markers as argument
Boris Feld <boris.feld@octobus.net>
parents: 34873
diff changeset
   768
    """ Return the verb summarizing the successorset and potentially using
b81ad5b78a81 obsfate: makes successorsetverb takes the markers as argument
Boris Feld <boris.feld@octobus.net>
parents: 34873
diff changeset
   769
    information from the markers
33993
3d0f8918351b template: compute verb in obsfateverb
Boris Feld <boris.feld@octobus.net>
parents: 33942
diff changeset
   770
    """
3d0f8918351b template: compute verb in obsfateverb
Boris Feld <boris.feld@octobus.net>
parents: 33942
diff changeset
   771
    if not successorset:
3d0f8918351b template: compute verb in obsfateverb
Boris Feld <boris.feld@octobus.net>
parents: 33942
diff changeset
   772
        verb = 'pruned'
3d0f8918351b template: compute verb in obsfateverb
Boris Feld <boris.feld@octobus.net>
parents: 33942
diff changeset
   773
    elif len(successorset) == 1:
3d0f8918351b template: compute verb in obsfateverb
Boris Feld <boris.feld@octobus.net>
parents: 33942
diff changeset
   774
        verb = 'rewritten'
3d0f8918351b template: compute verb in obsfateverb
Boris Feld <boris.feld@octobus.net>
parents: 33942
diff changeset
   775
    else:
3d0f8918351b template: compute verb in obsfateverb
Boris Feld <boris.feld@octobus.net>
parents: 33942
diff changeset
   776
        verb = 'split'
3d0f8918351b template: compute verb in obsfateverb
Boris Feld <boris.feld@octobus.net>
parents: 33942
diff changeset
   777
    return verb
33994
38f08eaba6b0 template: compute user in obsfateusers
Boris Feld <boris.feld@octobus.net>
parents: 33993
diff changeset
   778
33995
c35c0f54f420 template: compute dates in obsfatedate
Boris Feld <boris.feld@octobus.net>
parents: 33994
diff changeset
   779
def markersdates(markers):
c35c0f54f420 template: compute dates in obsfatedate
Boris Feld <boris.feld@octobus.net>
parents: 33994
diff changeset
   780
    """returns the list of dates for a list of markers
c35c0f54f420 template: compute dates in obsfatedate
Boris Feld <boris.feld@octobus.net>
parents: 33994
diff changeset
   781
    """
c35c0f54f420 template: compute dates in obsfatedate
Boris Feld <boris.feld@octobus.net>
parents: 33994
diff changeset
   782
    return [m[4] for m in markers]
c35c0f54f420 template: compute dates in obsfatedate
Boris Feld <boris.feld@octobus.net>
parents: 33994
diff changeset
   783
33994
38f08eaba6b0 template: compute user in obsfateusers
Boris Feld <boris.feld@octobus.net>
parents: 33993
diff changeset
   784
def markersusers(markers):
38f08eaba6b0 template: compute user in obsfateusers
Boris Feld <boris.feld@octobus.net>
parents: 33993
diff changeset
   785
    """ Returns a sorted list of markers users without duplicates
38f08eaba6b0 template: compute user in obsfateusers
Boris Feld <boris.feld@octobus.net>
parents: 33993
diff changeset
   786
    """
38f08eaba6b0 template: compute user in obsfateusers
Boris Feld <boris.feld@octobus.net>
parents: 33993
diff changeset
   787
    markersmeta = [dict(m[3]) for m in markers]
38f08eaba6b0 template: compute user in obsfateusers
Boris Feld <boris.feld@octobus.net>
parents: 33993
diff changeset
   788
    users = set(meta.get('user') for meta in markersmeta if meta.get('user'))
38f08eaba6b0 template: compute user in obsfateusers
Boris Feld <boris.feld@octobus.net>
parents: 33993
diff changeset
   789
38f08eaba6b0 template: compute user in obsfateusers
Boris Feld <boris.feld@octobus.net>
parents: 33993
diff changeset
   790
    return sorted(users)
34287
7cdc8c5a481a templates: introduce a obsfateoperation() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 33996
diff changeset
   791
7cdc8c5a481a templates: introduce a obsfateoperation() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 33996
diff changeset
   792
def markersoperations(markers):
7cdc8c5a481a templates: introduce a obsfateoperation() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 33996
diff changeset
   793
    """ Returns a sorted list of markers operations without duplicates
7cdc8c5a481a templates: introduce a obsfateoperation() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 33996
diff changeset
   794
    """
7cdc8c5a481a templates: introduce a obsfateoperation() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 33996
diff changeset
   795
    markersmeta = [dict(m[3]) for m in markers]
7cdc8c5a481a templates: introduce a obsfateoperation() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 33996
diff changeset
   796
    operations = set(meta.get('operation') for meta in markersmeta
7cdc8c5a481a templates: introduce a obsfateoperation() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 33996
diff changeset
   797
                     if meta.get('operation'))
7cdc8c5a481a templates: introduce a obsfateoperation() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 33996
diff changeset
   798
7cdc8c5a481a templates: introduce a obsfateoperation() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 33996
diff changeset
   799
    return sorted(operations)
34847
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   800
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   801
def obsfateprinter(successors, markers, ui):
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   802
    """ Build a obsfate string for a single successorset using all obsfate
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   803
    related function defined in obsutil
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   804
    """
34850
62a4ccf9784a obsfate: filter out current user if not in verbose
Boris Feld <boris.feld@octobus.net>
parents: 34847
diff changeset
   805
    quiet = ui.quiet
62a4ccf9784a obsfate: filter out current user if not in verbose
Boris Feld <boris.feld@octobus.net>
parents: 34847
diff changeset
   806
    verbose = ui.verbose
62a4ccf9784a obsfate: filter out current user if not in verbose
Boris Feld <boris.feld@octobus.net>
parents: 34847
diff changeset
   807
    normal = not verbose and not quiet
62a4ccf9784a obsfate: filter out current user if not in verbose
Boris Feld <boris.feld@octobus.net>
parents: 34847
diff changeset
   808
34847
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   809
    line = []
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   810
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   811
    # Verb
35010
b81ad5b78a81 obsfate: makes successorsetverb takes the markers as argument
Boris Feld <boris.feld@octobus.net>
parents: 34873
diff changeset
   812
    line.append(obsfateverb(successors, markers))
34847
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   813
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   814
    # Operations
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   815
    operations = markersoperations(markers)
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   816
    if operations:
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   817
        line.append(" using %s" % ", ".join(operations))
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   818
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   819
    # Successors
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   820
    if successors:
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   821
        fmtsuccessors = [successors.joinfmt(succ) for succ in successors]
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   822
        line.append(" as %s" % ", ".join(fmtsuccessors))
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   823
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   824
    # Users
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   825
    users = markersusers(markers)
34850
62a4ccf9784a obsfate: filter out current user if not in verbose
Boris Feld <boris.feld@octobus.net>
parents: 34847
diff changeset
   826
    # Filter out current user in not verbose mode to reduce amount of
62a4ccf9784a obsfate: filter out current user if not in verbose
Boris Feld <boris.feld@octobus.net>
parents: 34847
diff changeset
   827
    # information
62a4ccf9784a obsfate: filter out current user if not in verbose
Boris Feld <boris.feld@octobus.net>
parents: 34847
diff changeset
   828
    if not verbose:
62a4ccf9784a obsfate: filter out current user if not in verbose
Boris Feld <boris.feld@octobus.net>
parents: 34847
diff changeset
   829
        currentuser = ui.username(acceptempty=True)
62a4ccf9784a obsfate: filter out current user if not in verbose
Boris Feld <boris.feld@octobus.net>
parents: 34847
diff changeset
   830
        if len(users) == 1 and currentuser in users:
62a4ccf9784a obsfate: filter out current user if not in verbose
Boris Feld <boris.feld@octobus.net>
parents: 34847
diff changeset
   831
            users = None
34847
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   832
34850
62a4ccf9784a obsfate: filter out current user if not in verbose
Boris Feld <boris.feld@octobus.net>
parents: 34847
diff changeset
   833
    if (verbose or normal) and users:
34847
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   834
        line.append(" by %s" % ", ".join(users))
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   835
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   836
    # Date
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   837
    dates = markersdates(markers)
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   838
34873
aa849cf5d089 obsfate: fix obsfate_printer with empty date list
Boris Feld <boris.feld@octobus.net>
parents: 34851
diff changeset
   839
    if dates and verbose:
34851
6f53a53245a2 obsfate: only display date in verbose mode
Boris Feld <boris.feld@octobus.net>
parents: 34850
diff changeset
   840
        min_date = min(dates)
6f53a53245a2 obsfate: only display date in verbose mode
Boris Feld <boris.feld@octobus.net>
parents: 34850
diff changeset
   841
        max_date = max(dates)
34847
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   842
34851
6f53a53245a2 obsfate: only display date in verbose mode
Boris Feld <boris.feld@octobus.net>
parents: 34850
diff changeset
   843
        if min_date == max_date:
6f53a53245a2 obsfate: only display date in verbose mode
Boris Feld <boris.feld@octobus.net>
parents: 34850
diff changeset
   844
            fmtmin_date = util.datestr(min_date, '%Y-%m-%d %H:%M %1%2')
6f53a53245a2 obsfate: only display date in verbose mode
Boris Feld <boris.feld@octobus.net>
parents: 34850
diff changeset
   845
            line.append(" (at %s)" % fmtmin_date)
6f53a53245a2 obsfate: only display date in verbose mode
Boris Feld <boris.feld@octobus.net>
parents: 34850
diff changeset
   846
        else:
6f53a53245a2 obsfate: only display date in verbose mode
Boris Feld <boris.feld@octobus.net>
parents: 34850
diff changeset
   847
            fmtmin_date = util.datestr(min_date, '%Y-%m-%d %H:%M %1%2')
6f53a53245a2 obsfate: only display date in verbose mode
Boris Feld <boris.feld@octobus.net>
parents: 34850
diff changeset
   848
            fmtmax_date = util.datestr(max_date, '%Y-%m-%d %H:%M %1%2')
6f53a53245a2 obsfate: only display date in verbose mode
Boris Feld <boris.feld@octobus.net>
parents: 34850
diff changeset
   849
            line.append(" (between %s and %s)" % (fmtmin_date, fmtmax_date))
34847
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   850
e27f1f04c2cf templatekw: introduce obsfate keyword
Boris Feld <boris.feld@octobus.net>
parents: 34422
diff changeset
   851
    return "".join(line)
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   852
35609
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   853
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   854
filteredmsgtable = {
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   855
    "pruned": _("hidden revision '%s' is pruned"),
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   856
    "diverged": _("hidden revision '%s' has diverged"),
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   857
    "superseded": _("hidden revision '%s' was rewritten as: %s"),
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   858
    "superseded_split": _("hidden revision '%s' was split as: %s"),
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   859
    "superseded_split_several": _("hidden revision '%s' was split as: %s and "
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   860
                                  "%d more"),
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   861
}
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   862
35610
22c42bfbe7ab visibility: pass a normal repo to _getfilteredreason
Boris Feld <boris.feld@octobus.net>
parents: 35609
diff changeset
   863
def _getfilteredreason(repo, changeid, ctx):
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   864
    """return a human-friendly string on why a obsolete changeset is hidden
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   865
    """
35610
22c42bfbe7ab visibility: pass a normal repo to _getfilteredreason
Boris Feld <boris.feld@octobus.net>
parents: 35609
diff changeset
   866
    successors = successorssets(repo, ctx.node())
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   867
    fate = _getobsfate(successors)
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   868
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   869
    # Be more precise in case the revision is superseded
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   870
    if fate == 'pruned':
35609
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   871
        return filteredmsgtable['pruned'] % changeid
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   872
    elif fate == 'diverged':
35609
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   873
        return filteredmsgtable['diverged'] % changeid
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   874
    elif fate == 'superseded':
35609
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   875
        single_successor = nodemod.short(successors[0][0])
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   876
        return filteredmsgtable['superseded'] % (changeid, single_successor)
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   877
    elif fate == 'superseded_split':
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   878
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   879
        succs = []
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   880
        for node_id in successors[0]:
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   881
            succs.append(nodemod.short(node_id))
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   882
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   883
        if len(succs) <= 2:
35609
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   884
            fmtsuccs = ', '.join(succs)
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   885
            return filteredmsgtable['superseded_split'] % (changeid, fmtsuccs)
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   886
        else:
35609
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   887
            firstsuccessors = ', '.join(succs[:2])
35571
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   888
            remainingnumber = len(succs) - 2
265cd9e19d26 visibility: improve the message when accessing filtered obsolete rev
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   889
35609
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   890
            args = (changeid, firstsuccessors, remainingnumber)
c026547454dd visibility: make the filtered message translatable
Boris Feld <boris.feld@octobus.net>
parents: 35571
diff changeset
   891
            return filteredmsgtable['superseded_split_several'] % args