Patchwork D8454: phabricator: ensure that `phabsend` is given a contiguous, linear commit range

login
register
mail settings
Submitter phabricator
Date April 19, 2020, 9:45 p.m.
Message ID <e5307b948d53c06c8fdbfc80ff57e6a9@localhost.localdomain>
Download mbox | patch
Permalink /patch/46189/
State Not Applicable
Headers show

Comments

phabricator - April 19, 2020, 9:45 p.m.
mharbison72 updated this revision to Diff 21159.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8454?vs=21157&id=21159

BRANCH
  stable

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8454/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8454

AFFECTED FILES
  hgext/phabricator.py
  tests/test-phabricator.t

CHANGE DETAILS




To: mharbison72, #hg-reviewers
Cc: marmoute, Kwan, mercurial-devel

Patch

diff --git a/tests/test-phabricator.t b/tests/test-phabricator.t
--- a/tests/test-phabricator.t
+++ b/tests/test-phabricator.t
@@ -589,6 +589,12 @@ 
   applying patch from D7917
   applying patch from D7918
 
+Phabsend requires a linear range of commits
+
+  $ hg phabsend -r 0+2+3
+  abort: cannot phabsend non-linear revisions: c44b38f24a45 8de3712202d1
+  [255]
+
 Validate arguments with --fold
 
   $ hg phabsend --fold -r 1
@@ -597,9 +603,6 @@ 
   $ hg phabsend --fold --no-amend -r 1::
   abort: cannot fold with --no-amend
   [255]
-  $ hg phabsend --fold -r 0+3
-  abort: cannot fold non-linear revisions
-  [255]
   $ hg phabsend --fold -r 1::
   abort: cannot fold revisions with different DREV values
   [255]
diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -1307,6 +1307,21 @@ 
     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.
+    heads = repo.revs(b'heads(%ld)', revs)
+    roots = repo.revs(b'roots(%ld)', revs)
+    if len(heads) > 1 or len(roots) > 1:
+        ends = {r for r in heads if r != heads.max()}
+        ends |= {r for r in roots if r != roots.min()}
+        badnodes = [repo[r].node() for r in sorted(ends)]
+        raise error.Abort(
+            _(b"cannot phabsend non-linear revisions: %s")
+            % scmutil.nodesummaries(repo, badnodes)
+        )
+
     fold = opts.get(b'fold')
     if fold:
         if len(revs) == 1:
@@ -1322,13 +1337,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