comparison hgext/rebase.py @ 44381:9c9cfecd4600

rebase: don't use rebased node as dirstate p2 (BC) When rebasing a node, we currently use the rebased node as p2 in the dirstate until just before we commit it (we then change to the desired parents). This p2 is visible to the user when the rebase gets interrupted because of merge conflicts. That can be useful to the user as a reminder of which commit is currently being rebased, but I believe it's incorrect for a few reasons: * I think the dirstate parents should be the ones that will be set when the commit is created. * I think having two parents means that you're merging those two commits, but when rebasing, you're generally grafting, not merging. * When rebasing a merge commit, we should use the two desired parents as dirstate parents (and we clearly can't have the rebased node as a third dirstate parent). * `hg graft` (and `hg update --merge`) sets only one parent and `hg rebase` should be consistent with that. I realize that this is a somewhat large user-visible change, but I think it's worth it because it will simplify things quite a bit. Differential Revision: https://phab.mercurial-scm.org/D7827
author Martin von Zweigbergk <martinvonz@google.com>
date Fri, 10 Jan 2020 14:22:20 -0800
parents b42ce825308e
children 8082a77cc3a2
comparison
equal deleted inserted replaced
44380:b42ce825308e 44381:9c9cfecd4600
616 with ui.configoverride(overrides, b'rebase'): 616 with ui.configoverride(overrides, b'rebase'):
617 stats = rebasenode( 617 stats = rebasenode(
618 repo, 618 repo,
619 rev, 619 rev,
620 p1, 620 p1,
621 p2,
621 base, 622 base,
622 self.collapsef, 623 self.collapsef,
623 dest, 624 dest,
624 wctx=self.wctx, 625 wctx=self.wctx,
625 ) 626 )
640 editform=editform, **pycompat.strkwargs(opts) 641 editform=editform, **pycompat.strkwargs(opts)
641 ) 642 )
642 newnode = self._concludenode(rev, p1, p2, editor) 643 newnode = self._concludenode(rev, p1, p2, editor)
643 else: 644 else:
644 # Skip commit if we are collapsing 645 # Skip commit if we are collapsing
645 if self.inmemory:
646 self.wctx.setbase(repo[p1])
647 else:
648 repo.setparents(repo[p1].node())
649 newnode = None 646 newnode = None
650 # Update the state 647 # Update the state
651 if newnode is not None: 648 if newnode is not None:
652 self.state[rev] = repo[newnode].rev() 649 self.state[rev] = repo[newnode].rev()
653 ui.debug(b'rebased as %s\n' % short(newnode)) 650 ui.debug(b'rebased as %s\n' % short(newnode))
1466 1463
1467 repo.dirstate.setbranch(repo[newnode].branch()) 1464 repo.dirstate.setbranch(repo[newnode].branch())
1468 return newnode 1465 return newnode
1469 1466
1470 1467
1471 def rebasenode(repo, rev, p1, base, collapse, dest, wctx): 1468 def rebasenode(repo, rev, p1, p2, base, collapse, dest, wctx):
1472 """Rebase a single revision rev on top of p1 using base as merge ancestor""" 1469 """Rebase a single revision rev on top of p1 using base as merge ancestor"""
1473 # Merge phase 1470 # Merge phase
1474 # Update to destination and merge it with local 1471 # Update to destination and merge it with local
1475 p1ctx = repo[p1] 1472 p1ctx = repo[p1]
1476 if wctx.isinmemory(): 1473 if wctx.isinmemory():
1500 ancestor=base, 1497 ancestor=base,
1501 mergeancestor=mergeancestor, 1498 mergeancestor=mergeancestor,
1502 labels=[b'dest', b'source'], 1499 labels=[b'dest', b'source'],
1503 wc=wctx, 1500 wc=wctx,
1504 ) 1501 )
1502 wctx.setparents(p1ctx.node(), repo[p2].node())
1505 if collapse: 1503 if collapse:
1506 copies.graftcopies(wctx, ctx, repo[dest]) 1504 copies.graftcopies(wctx, ctx, repo[dest])
1507 else: 1505 else:
1508 # If we're not using --collapse, we need to 1506 # If we're not using --collapse, we need to
1509 # duplicate copies between the revision we're 1507 # duplicate copies between the revision we're