hgext/phabricator.py
branchstable
changeset 44758 c1c922391314
parent 44720 601ce5392cb0
child 44906 11592ce6a711
--- a/hgext/phabricator.py	Fri Apr 24 12:37:43 2020 -0700
+++ b/hgext/phabricator.py	Thu Apr 16 19:05:25 2020 -0400
@@ -1307,6 +1307,26 @@
     if any(c for c in ctxs if c.obsolete()):
         raise error.Abort(_(b"obsolete commits cannot be posted for review"))
 
+    # Ensure the local commits are an unbroken range.  The semantics of the
+    # --fold option implies this, and the auto restacking of orphans requires
+    # it.  Otherwise A+C in A->B->C will cause B to be orphaned, and C' to
+    # get A' as a parent.
+    def _fail_nonlinear_revs(revs, skiprev, revtype):
+        badnodes = [repo[r].node() for r in revs if r != skiprev]
+        raise error.Abort(
+            _(b"cannot phabsend multiple %s revisions: %s")
+            % (revtype, scmutil.nodesummaries(repo, badnodes)),
+            hint=_(b"the revisions must form a linear chain"),
+        )
+
+    heads = repo.revs(b'heads(%ld)', revs)
+    if len(heads) > 1:
+        _fail_nonlinear_revs(heads, heads.max(), b"head")
+
+    roots = repo.revs(b'roots(%ld)', revs)
+    if len(roots) > 1:
+        _fail_nonlinear_revs(roots, roots.min(), b"root")
+
     fold = opts.get(b'fold')
     if fold:
         if len(revs) == 1:
@@ -1322,13 +1342,6 @@
         if not opts.get(b"amend"):
             raise error.Abort(_(b"cannot fold with --no-amend"))
 
-        # Ensure the local commits are an unbroken range
-        revrange = repo.revs(b'(first(%ld)::last(%ld))', revs, revs)
-        if any(r for r in revs if r not in revrange) or any(
-            r for r in revrange if r not in revs
-        ):
-            raise error.Abort(_(b"cannot fold non-linear revisions"))
-
         # It might be possible to bucketize the revisions by the DREV value, and
         # iterate over those groups when posting, and then again when amending.
         # But for simplicity, require all selected revisions to be for the same