comparison hgext/phabricator.py @ 44720:601ce5392cb0

phabricator: restack any new orphans created by phabsend (issue6045) Previously, posting a new review for a non head commit would orphan the head. The general case is any descendant of the selected revisions got orphaned if this was the first time the selected revisions were submitted. It doesn't happen when resubmitting. I've already had coworkers hit this a few times and get confused. Since posting a review isn't generally thought of as an editing operation, it would probably be easier for new users if we just restacked. This avoids restacking existing orphans around the submission because that may involve merge conflict resolution. Users who already have orphans should know how to stabilize them anyway. Differential Revision: https://phab.mercurial-scm.org/D8438
author Matt Harbison <matt_harbison@yahoo.com>
date Tue, 14 Apr 2020 18:51:23 -0400
parents c482e2fe444c
children c1c922391314
comparison
equal deleted inserted replaced
44719:c482e2fe444c 44720:601ce5392cb0
1455 # Update commit messages and remove tags 1455 # Update commit messages and remove tags
1456 if opts.get(b'amend'): 1456 if opts.get(b'amend'):
1457 unfi = repo.unfiltered() 1457 unfi = repo.unfiltered()
1458 drevs = callconduit(ui, b'differential.query', {b'ids': drevids}) 1458 drevs = callconduit(ui, b'differential.query', {b'ids': drevids})
1459 with repo.wlock(), repo.lock(), repo.transaction(b'phabsend'): 1459 with repo.wlock(), repo.lock(), repo.transaction(b'phabsend'):
1460 # Eagerly evaluate commits to restabilize before creating new
1461 # commits. The selected revisions are excluded because they are
1462 # automatically restacked as part of the submission process.
1463 restack = [
1464 c
1465 for c in repo.set(
1466 b"(%ld::) - (%ld) - unstable() - obsolete() - public()",
1467 revs,
1468 revs,
1469 )
1470 ]
1460 wnode = unfi[b'.'].node() 1471 wnode = unfi[b'.'].node()
1461 mapping = {} # {oldnode: [newnode]} 1472 mapping = {} # {oldnode: [newnode]}
1462 newnodes = [] 1473 newnodes = []
1463 1474
1464 drevid = drevids[0] 1475 drevid = drevids[0]
1548 b"local commit list for D%d is already up-to-date\n" 1559 b"local commit list for D%d is already up-to-date\n"
1549 % drevid, 1560 % drevid,
1550 ) 1561 )
1551 elif fold: 1562 elif fold:
1552 _debug(ui, b"no newnodes to update\n") 1563 _debug(ui, b"no newnodes to update\n")
1564
1565 # Restack any children of first-time submissions that were orphaned
1566 # in the process. The ctx won't report that it is an orphan until
1567 # the cleanup takes place below.
1568 for old in restack:
1569 parents = [
1570 mapping.get(old.p1().node(), (old.p1(),))[0],
1571 mapping.get(old.p2().node(), (old.p2(),))[0],
1572 ]
1573 new = context.metadataonlyctx(
1574 repo,
1575 old,
1576 parents=parents,
1577 text=old.description(),
1578 user=old.user(),
1579 date=old.date(),
1580 extra=old.extra(),
1581 )
1582
1583 newnode = new.commit()
1584
1585 # Don't obsolete unselected descendants of nodes that have not
1586 # been changed in this transaction- that results in an error.
1587 if newnode != old.node():
1588 mapping[old.node()] = [newnode]
1589 _debug(
1590 ui,
1591 b"restabilizing %s as %s\n"
1592 % (short(old.node()), short(newnode)),
1593 )
1594 else:
1595 _debug(
1596 ui,
1597 b"not restabilizing unchanged %s\n" % short(old.node()),
1598 )
1553 1599
1554 scmutil.cleanupnodes(repo, mapping, b'phabsend', fixphase=True) 1600 scmutil.cleanupnodes(repo, mapping, b'phabsend', fixphase=True)
1555 if wnode in mapping: 1601 if wnode in mapping:
1556 unfi.setparents(mapping[wnode][0]) 1602 unfi.setparents(mapping[wnode][0])
1557 1603