Mercurial > public > mercurial-scm > hg
comparison hgext/phabricator.py @ 44774:c1c922391314 stable
phabricator: ensure that `phabsend` is given a contiguous, linear commit range
Supplying a non-linear range was another orphan factory. While in theory there
could be a use case for skipping over garbage commits (like adding debugging)
and getting the valuable commits extracted out at the same time as posting a
review, it seems far more likely that specifying a non-linear range is a user
error. This is another case of issue6045, but predates both 0680b8a1992a and
601ce5392cb0.
Neither the `--no-amend` case nor resubmitting a previously submitted commit
would cause orphans. But for the sake of simplicity and to keep the parents
tracked on Phabricator in the proper state, ban missing commits unconditionally.
Differential Revision: https://phab.mercurial-scm.org/D8454
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Thu, 16 Apr 2020 19:05:25 -0400 |
parents | 601ce5392cb0 |
children | 11592ce6a711 |
comparison
equal
deleted
inserted
replaced
44772:5e788dc7fb5d | 44774:c1c922391314 |
---|---|
1305 ctxs = [repo[rev] for rev in revs] | 1305 ctxs = [repo[rev] for rev in revs] |
1306 | 1306 |
1307 if any(c for c in ctxs if c.obsolete()): | 1307 if any(c for c in ctxs if c.obsolete()): |
1308 raise error.Abort(_(b"obsolete commits cannot be posted for review")) | 1308 raise error.Abort(_(b"obsolete commits cannot be posted for review")) |
1309 | 1309 |
1310 # Ensure the local commits are an unbroken range. The semantics of the | |
1311 # --fold option implies this, and the auto restacking of orphans requires | |
1312 # it. Otherwise A+C in A->B->C will cause B to be orphaned, and C' to | |
1313 # get A' as a parent. | |
1314 def _fail_nonlinear_revs(revs, skiprev, revtype): | |
1315 badnodes = [repo[r].node() for r in revs if r != skiprev] | |
1316 raise error.Abort( | |
1317 _(b"cannot phabsend multiple %s revisions: %s") | |
1318 % (revtype, scmutil.nodesummaries(repo, badnodes)), | |
1319 hint=_(b"the revisions must form a linear chain"), | |
1320 ) | |
1321 | |
1322 heads = repo.revs(b'heads(%ld)', revs) | |
1323 if len(heads) > 1: | |
1324 _fail_nonlinear_revs(heads, heads.max(), b"head") | |
1325 | |
1326 roots = repo.revs(b'roots(%ld)', revs) | |
1327 if len(roots) > 1: | |
1328 _fail_nonlinear_revs(roots, roots.min(), b"root") | |
1329 | |
1310 fold = opts.get(b'fold') | 1330 fold = opts.get(b'fold') |
1311 if fold: | 1331 if fold: |
1312 if len(revs) == 1: | 1332 if len(revs) == 1: |
1313 # TODO: just switch to --no-fold instead? | 1333 # TODO: just switch to --no-fold instead? |
1314 raise error.Abort(_(b"cannot fold a single revision")) | 1334 raise error.Abort(_(b"cannot fold a single revision")) |
1319 # lock the repo and ensure that the range is editable, but that would | 1339 # lock the repo and ensure that the range is editable, but that would |
1320 # make the code pretty convoluted. The default behavior of `arc` is to | 1340 # make the code pretty convoluted. The default behavior of `arc` is to |
1321 # create a new review anyway. | 1341 # create a new review anyway. |
1322 if not opts.get(b"amend"): | 1342 if not opts.get(b"amend"): |
1323 raise error.Abort(_(b"cannot fold with --no-amend")) | 1343 raise error.Abort(_(b"cannot fold with --no-amend")) |
1324 | |
1325 # Ensure the local commits are an unbroken range | |
1326 revrange = repo.revs(b'(first(%ld)::last(%ld))', revs, revs) | |
1327 if any(r for r in revs if r not in revrange) or any( | |
1328 r for r in revrange if r not in revs | |
1329 ): | |
1330 raise error.Abort(_(b"cannot fold non-linear revisions")) | |
1331 | 1344 |
1332 # It might be possible to bucketize the revisions by the DREV value, and | 1345 # It might be possible to bucketize the revisions by the DREV value, and |
1333 # iterate over those groups when posting, and then again when amending. | 1346 # iterate over those groups when posting, and then again when amending. |
1334 # But for simplicity, require all selected revisions to be for the same | 1347 # But for simplicity, require all selected revisions to be for the same |
1335 # DREV (if present). Adding local revisions to an existing DREV is | 1348 # DREV (if present). Adding local revisions to an existing DREV is |