evolve: move builddependencies() and _singlesuccessor() to utility module
The builddependencies() and _singlesuccessor() function are very useful
functions and can be used at a lot of places. They are also used in topic
extension also, so let's move them to utility. However moving them to utility
won't help anything in the topic extension.
--- a/hgext3rd/evolve/__init__.py Fri Jan 19 17:29:48 2018 +0530
+++ b/hgext3rd/evolve/__init__.py Sun Jan 21 20:28:06 2018 +0530
@@ -947,54 +947,6 @@
_deprecatealias('gup', 'next')
_deprecatealias('gdown', 'previous')
-def _singlesuccessor(repo, p):
- """returns p (as rev) if not obsolete or its unique latest successors
-
- fail if there are no such successor"""
-
- if not p.obsolete():
- return p.rev()
- obs = repo[p]
- ui = repo.ui
- newer = compat.successorssets(repo, obs.node())
- # search of a parent which is not killed
- while not newer:
- ui.debug("stabilize target %s is plain dead,"
- " trying to stabilize on its parent\n" %
- obs)
- obs = obs.parents()[0]
- newer = compat.successorssets(repo, obs.node())
- if len(newer) > 1 or len(newer[0]) > 1:
- raise utility.MultipleSuccessorsError(newer)
-
- return repo[newer[0][0]].rev()
-
-def builddependencies(repo, revs):
- """returns dependency graphs giving an order to solve instability of revs
- (see _orderrevs for more information on usage)"""
-
- # For each troubled revision we keep track of what instability if any should
- # be resolved in order to resolve it. Example:
- # dependencies = {3: [6], 6:[]}
- # Means that: 6 has no dependency, 3 depends on 6 to be solved
- dependencies = {}
- # rdependencies is the inverted dict of dependencies
- rdependencies = collections.defaultdict(set)
-
- for r in revs:
- dependencies[r] = set()
- for p in repo[r].parents():
- try:
- succ = _singlesuccessor(repo, p)
- except utility.MultipleSuccessorsError as exc:
- dependencies[r] = exc.successorssets
- continue
- if succ in revs:
- dependencies[r].add(succ)
- rdependencies[succ].add(r)
- return dependencies, rdependencies
-
-
def _orderrevs(repo, revs):
"""Compute an ordering to solve instability for the given revs
@@ -1008,7 +960,7 @@
revision on its final stabilized destination.
"""
# Step 1: Build the dependency graph
- dependencies, rdependencies = builddependencies(repo, revs)
+ dependencies, rdependencies = utility.builddependencies(repo, revs)
# Step 2: Build the ordering
# Remove the revisions with no dependency(A) and add them to the ordering.
# Removing these revisions leads to new revisions with no dependency (the
@@ -1153,7 +1105,7 @@
{'template': shorttemplate})
# no args and parent is obsolete, update to successors
try:
- ctx = repo[_singlesuccessor(repo, repo['.'])]
+ ctx = repo[utility._singlesuccessor(repo, repo['.'])]
except utility.MultipleSuccessorsError as exc:
repo.ui.write_err('parent is obsolete with multiple successors:\n')
for ln in exc.successorssets:
@@ -1285,7 +1237,7 @@
# we do not filter in the 1 case to allow prev to t0
if currenttopic and topic and _gettopicidx(p1) != 1:
- parents = [repo[_singlesuccessor(repo, ctx)] if ctx.mutable() else ctx
+ parents = [repo[utility._singlesuccessor(repo, ctx)] if ctx.mutable() else ctx
for ctx in parents]
parents = [ctx for ctx in parents if ctx.topic() == currenttopic]
--- a/hgext3rd/evolve/utility.py Fri Jan 19 17:29:48 2018 +0530
+++ b/hgext3rd/evolve/utility.py Sun Jan 21 20:28:06 2018 +0530
@@ -5,8 +5,14 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
+import collections
+
from mercurial.node import nullrev
+from . import (
+ compat,
+)
+
shorttemplate = "[{label('evolve.rev', rev)}] {desc|firstline}\n"
def obsexcmsg(ui, message, important=False):
@@ -76,3 +82,50 @@
def __init__(self, successorssets):
self.successorssets = successorssets
+
+def builddependencies(repo, revs):
+ """returns dependency graphs giving an order to solve instability of revs
+ (see _orderrevs for more information on usage)"""
+
+ # For each troubled revision we keep track of what instability if any should
+ # be resolved in order to resolve it. Example:
+ # dependencies = {3: [6], 6:[]}
+ # Means that: 6 has no dependency, 3 depends on 6 to be solved
+ dependencies = {}
+ # rdependencies is the inverted dict of dependencies
+ rdependencies = collections.defaultdict(set)
+
+ for r in revs:
+ dependencies[r] = set()
+ for p in repo[r].parents():
+ try:
+ succ = _singlesuccessor(repo, p)
+ except MultipleSuccessorsError as exc:
+ dependencies[r] = exc.successorssets
+ continue
+ if succ in revs:
+ dependencies[r].add(succ)
+ rdependencies[succ].add(r)
+ return dependencies, rdependencies
+
+def _singlesuccessor(repo, p):
+ """returns p (as rev) if not obsolete or its unique latest successors
+
+ fail if there are no such successor"""
+
+ if not p.obsolete():
+ return p.rev()
+ obs = repo[p]
+ ui = repo.ui
+ newer = compat.successorssets(repo, obs.node())
+ # search of a parent which is not killed
+ while not newer:
+ ui.debug("stabilize target %s is plain dead,"
+ " trying to stabilize on its parent\n" %
+ obs)
+ obs = obs.parents()[0]
+ newer = compat.successorssets(repo, obs.node())
+ if len(newer) > 1 or len(newer[0]) > 1:
+ raise MultipleSuccessorsError(newer)
+
+ return repo[newer[0][0]].rev()