evolve: add a new method picksplitsuccessor() in utility.py
This patch adds the logic to return a single successor of a rev which was
split. If split revisions are on a single topological branch then we return
highest one; otherwise prompt user to choose an evolve destination.
--- a/hgext3rd/evolve/evolvecmd.py Wed Jan 15 15:28:44 2020 +0700
+++ b/hgext3rd/evolve/evolvecmd.py Sun Dec 08 02:17:11 2019 +0530
@@ -128,35 +128,22 @@
while repo[newer].node() == orig.node():
obs = obs.parents()[0]
newer = utility._singlesuccessor(repo, obs)
- target = newer
except utility.MultipleSuccessorsError as exc:
if exc.divergenceflag:
msg = _(b"skipping %s: divergent rewriting. can't choose "
b"destination\n") % obs
ui.write_err(msg)
return (False, b".")
- targets = exc.successorssets[0]
- assert targets
if exc.splitflag:
- # split target, figure out which one to pick, are they all in line?
- targetrevs = [repo[r].rev() for r in targets]
- roots = repo.revs(b'roots(%ld)', targetrevs)
- heads = repo.revs(b'heads(%ld)', targetrevs)
- if len(roots) > 1 or len(heads) > 1:
- cheader = _(b"ancestor '%s' split over multiple topological"
- b" branches.\nchoose an evolve destination:") % orig
- selectedrev = utility.revselectionprompt(ui, repo, list(heads),
- cheader)
- if selectedrev is None:
- msg = _(b"could not solve instability, "
- b"ambiguous destination: "
- b"parent split across two branches\n")
- ui.write_err(msg)
- return (False, b".")
- target = repo[selectedrev]
- else:
- target = repo[heads.first()]
- target = repo[target]
+ splitsucc = utility.picksplitsuccessor(ui, repo, obs, orig)
+ if not splitsucc[0]:
+ msg = _(b"could not solve instability, "
+ b"ambiguous destination: "
+ b"parent split across two branches\n")
+ ui.write_err(msg)
+ return (False, b".")
+ newer = splitsucc[1]
+ target = repo[newer]
if not ui.quiet or confirm:
repo.ui.write(_(b'move:'), label=b'evolve.operation')
displayer.show(orig)
--- a/hgext3rd/evolve/utility.py Wed Jan 15 15:28:44 2020 +0700
+++ b/hgext3rd/evolve/utility.py Sun Dec 08 02:17:11 2019 +0530
@@ -125,6 +125,34 @@
return repo[newer[0][0]].rev()
+def picksplitsuccessor(ui, repo, ctx, evolvecand):
+ """choose a successor of ctx from split targets
+
+ Choose highest one if all successors are in a topological branch. And if
+ they are split over multiple topological branches, we ask user to choose
+ an evolve destination.
+
+ Return (True, succ) unless split targets are split over multiple
+ topological branches and user didn't choose any evolve destination,
+ in which case return (False, '.')
+ """
+ targets = obsutil.successorssets(repo, ctx.node())[0]
+ assert targets
+ targetrevs = [repo[r].rev() for r in targets]
+ roots = repo.revs(b'roots(%ld)', targetrevs)
+ heads = repo.revs(b'heads(%ld)', targetrevs)
+ if len(roots) > 1 or len(heads) > 1:
+ cheader = (_(b"ancestor '%s' split over multiple topological"
+ b" branches.\nchoose an evolve destination:") %
+ evolvecand)
+ selectedrev = revselectionprompt(ui, repo, list(heads), cheader)
+ if selectedrev is None:
+ return (False, '.')
+ succ = repo[selectedrev]
+ else:
+ succ = repo[heads.first()]
+ return (True, repo[succ].rev())
+
def _successorrevs(repo, ctx):
try:
return {_singlesuccessor(repo, ctx)}