diff mercurial/obsolete.py @ 33149:d09ae850296d

obsutil: move 'exclusivemarkers' to the new modules We have a new 'obsutil' module now. We move the high level utility there to bring 'obsolete.py' back to a more reasonable size.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 27 Jun 2017 01:11:56 +0200
parents 4f49810a1011
children d0e5bf12f314
line wrap: on
line diff
--- a/mercurial/obsolete.py	Tue Jun 27 01:03:01 2017 +0200
+++ b/mercurial/obsolete.py	Tue Jun 27 01:11:56 2017 +0200
@@ -771,131 +771,6 @@
                 % len(list(store)))
     return store
 
-def _filterprunes(markers):
-    """return a set with no prune markers"""
-    return set(m for m in markers if m[1])
-
-def exclusivemarkers(repo, nodes):
-    """set of markers relevant to "nodes" but no other locally-known nodes
-
-    This function compute the set of markers "exclusive" to a locally-known
-    node. This means we walk the markers starting from <nodes> until we reach a
-    locally-known precursors outside of <nodes>. Element of <nodes> with
-    locally-known successors outside of <nodes> are ignored (since their
-    precursors markers are also relevant to these successors).
-
-    For example:
-
-        # (A0 rewritten as A1)
-        #
-        # A0 <-1- A1 # Marker "1" is exclusive to A1
-
-        or
-
-        # (A0 rewritten as AX; AX rewritten as A1; AX is unkown locally)
-        #
-        # <-1- A0 <-2- AX <-3- A1 # Marker "2,3" are exclusive to A1
-
-        or
-
-        # (A0 has unknown precursors, A0 rewritten as A1 and A2 (divergence))
-        #
-        #          <-2- A1 # Marker "2" is exclusive to A0,A1
-        #        /
-        # <-1- A0
-        #        \
-        #         <-3- A2 # Marker "3" is exclusive to A0,A2
-        #
-        # in addition:
-        #
-        #  Markers "2,3" are exclusive to A1,A2
-        #  Markers "1,2,3" are exclusive to A0,A1,A2
-
-        See test/test-obsolete-bundle-strip.t for more examples.
-
-    An example usage is strip. When stripping a changeset, we also want to
-    strip the markers exclusive to this changeset. Otherwise we would have
-    "dangling"" obsolescence markers from its precursors: Obsolescence markers
-    marking a node as obsolete without any successors available locally.
-
-    As for relevant markers, the prune markers for children will be followed.
-    Of course, they will only be followed if the pruned children is
-    locally-known. Since the prune markers are relevant to the pruned node.
-    However, while prune markers are considered relevant to the parent of the
-    pruned changesets, prune markers for locally-known changeset (with no
-    successors) are considered exclusive to the pruned nodes. This allows
-    to strip the prune markers (with the rest of the exclusive chain) alongside
-    the pruned changesets.
-    """
-    # running on a filtered repository would be dangerous as markers could be
-    # reported as exclusive when they are relevant for other filtered nodes.
-    unfi = repo.unfiltered()
-
-    # shortcut to various useful item
-    nm = unfi.changelog.nodemap
-    precursorsmarkers = unfi.obsstore.precursors
-    successormarkers = unfi.obsstore.successors
-    childrenmarkers = unfi.obsstore.children
-
-    # exclusive markers (return of the function)
-    exclmarkers = set()
-    # we need fast membership testing
-    nodes = set(nodes)
-    # looking for head in the obshistory
-    #
-    # XXX we are ignoring all issues in regard with cycle for now.
-    stack = [n for n in nodes if not _filterprunes(successormarkers.get(n, ()))]
-    stack.sort()
-    # nodes already stacked
-    seennodes = set(stack)
-    while stack:
-        current = stack.pop()
-        # fetch precursors markers
-        markers = list(precursorsmarkers.get(current, ()))
-        # extend the list with prune markers
-        for mark in successormarkers.get(current, ()):
-            if not mark[1]:
-                markers.append(mark)
-        # and markers from children (looking for prune)
-        for mark in childrenmarkers.get(current, ()):
-            if not mark[1]:
-                markers.append(mark)
-        # traverse the markers
-        for mark in markers:
-            if mark in exclmarkers:
-                # markers already selected
-                continue
-
-            # If the markers is about the current node, select it
-            #
-            # (this delay the addition of markers from children)
-            if mark[1] or mark[0] == current:
-                exclmarkers.add(mark)
-
-            # should we keep traversing through the precursors?
-            prec = mark[0]
-
-            # nodes in the stack or already processed
-            if prec in seennodes:
-                continue
-
-            # is this a locally known node ?
-            known = prec in nm
-            # if locally-known and not in the <nodes> set the traversal
-            # stop here.
-            if known and prec not in nodes:
-                continue
-
-            # do not keep going if there are unselected markers pointing to this
-            # nodes. If we end up traversing these unselected markers later the
-            # node will be taken care of at that point.
-            precmarkers = _filterprunes(successormarkers.get(prec))
-            if precmarkers.issubset(exclmarkers):
-                seennodes.add(prec)
-                stack.append(prec)
-
-    return exclmarkers
-
 def commonversion(versions):
     """Return the newest version listed in both versions and our local formats.
 
@@ -971,7 +846,7 @@
     if nodes is None:
         rawmarkers = repo.obsstore
     elif exclusive:
-        rawmarkers = exclusivemarkers(repo, nodes)
+        rawmarkers = obsutil.exclusivemarkers(repo, nodes)
     else:
         rawmarkers = repo.obsstore.relevantmarkers(nodes)
 
@@ -1063,6 +938,11 @@
             foreground = set(repo.set('%ln::', known))
     return set(c.node() for c in foreground)
 
+def exclusivemarkers(repo, nodes):
+    movemsg = 'obsolete.exclusivemarkers moved to obsutil.exclusivemarkers'
+    repo.ui.deprecwarn(movemsg, '4.3')
+    return obsutil.exclusivemarkers(repo, nodes)
+
 def successorssets(repo, initialnode, cache=None):
     movemsg = 'obsolete.successorssets moved to obsutil.successorssets'
     repo.ui.deprecwarn(movemsg, '4.3')