Mercurial > hg
comparison hgext/rebase.py @ 44347: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
44346:b42ce825308e | 44347: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 |