rework refactor _aspiringchildren by introducing _possibledestination
This allows us to reuse some of the logic for evolve from _aspiringchildren
for the new implementation of evolve --all.
The logic is also better as some previously selected changesets may not actually
evolve on the target, and some changesets that does not would not.
--- a/hgext/evolve.py Mon Jun 22 19:24:21 2015 -0700
+++ b/hgext/evolve.py Tue Jun 23 00:02:23 2015 -0700
@@ -1410,7 +1410,7 @@
elif anyopt:
revs = repo.revs('first(%s())' % (targetcat))
elif targetcat == 'unstable':
- revs = set(_aspiringchildren(repo, repo['.']))
+ revs = set(_aspiringchildren(repo, repo.revs('(.::) - obsolete()::')))
if 1 < len(revs):
msg = "multiple evolve candidates"
hint = (_("select one of %s with --rev")
@@ -1589,29 +1589,37 @@
progresscb()
_cleanup(ui, repo, startnode, showprogress)
-def _aspiringchildren(repo, pctx):
+def _possibledestination(repo, rev):
+ """return all changesets that may be a new parent for REV"""
+ tonode = repo.changelog.node
+ parents = repo.changelog.parentrevs
+ torev = repo.changelog.rev
+ dest = set()
+ tovisit = list(parents(rev))
+ while tovisit:
+ r = tovisit.pop()
+ succsets = obsolete.successorssets(repo, tonode(r))
+ if not succsets:
+ tovisit.extend(parents(r))
+ else:
+ # We should probably pick only one destination from split
+ # (case where '1 < len(ss)'), This could be the currently tipmost
+ # but logic is less clear when result of the split are now on
+ # multiple branches.
+ for ss in succsets:
+ for n in ss:
+ dest.add(torev(n))
+ return dest
+
+def _aspiringchildren(repo, revs):
"""Return a list of changectx which can be stabilized on top of pctx or
- one of its descendants. Empty list if none can be found.
- """
- def selfanddescendants(repo, pctx):
- yield pctx
- for prec in repo.set('allprecursors(%d)', pctx):
- yield prec
- for ctx in pctx.descendants():
- yield ctx
- for prec in repo.set('allprecursors(%d)', ctx):
- yield prec
-
- # Look for an unstable which can be stabilized as a child of
- # node. The unstable must be a child of one of node predecessors.
+ one of its descendants. Empty list if none can be found."""
+ target = set(revs)
result = []
- directdesc = set([pctx.rev()])
- for ctx in selfanddescendants(repo, pctx):
- for child in ctx.children():
- if ctx.rev() in directdesc and not child.obsolete():
- directdesc.add(child.rev())
- elif child.unstable():
- result.append(child)
+ for r in repo.revs('unstable() - %ld', revs):
+ dest = _possibledestination(repo, r)
+ if target & dest:
+ result.append(r)
return result
def _solveunstable(ui, repo, orig, dryrun=False, confirm=False,