diff --git a/hgext/absorb.py b/hgext/absorb.py --- a/hgext/absorb.py +++ b/hgext/absorb.py @@ -34,6 +34,7 @@ from __future__ import absolute_import import collections +import itertools from mercurial.i18n import _ from mercurial import ( @@ -662,16 +663,19 @@ 4. call commit, to commit changes to hg database """ - def __init__(self, stack, ui=None, opts=None): + def __init__(self, stack, fixuptargets=[], ui=None, opts=None): """([ctx], ui or None) -> None stack: should be linear, and sorted by topo order - oldest first. + fixuptargets: changeset contexts that need to be fixed up, but are not + used for fixup computation. all commits in stack are considered mutable. """ assert stack self.ui = ui or nullui() self.opts = opts or {} self.stack = stack + self.fixuptargets = fixuptargets self.repo = stack[-1].repo().unfiltered() # following fields will be filled later @@ -777,7 +781,7 @@ # p1 which overrides the parent of the next commit, "None" means use # the original parent unchanged nextp1 = None - for ctx in self.stack: + for ctx in itertools.chain(self.stack, self.fixuptargets): memworkingcopy = self._getnewfilecontents(ctx) if not memworkingcopy and not lastcommitted: # nothing changed, nothing commited @@ -1011,7 +1015,10 @@ pats = () if opts is None: opts = {} - state = fixupstate(stack, ui=ui, opts=opts) + fixuptargets = [] + if targetctx.rev() is not None: + fixuptargets.append(targetctx) + state = fixupstate(stack, fixuptargets=fixuptargets, ui=ui, opts=opts) matcher = scmutil.match(targetctx, pats, opts) if opts.get(b'interactive'): diff = patch.diff(repo, stack[-1].node(), targetctx.node(), matcher) diff --git a/tests/test-absorb-rev.t b/tests/test-absorb-rev.t --- a/tests/test-absorb-rev.t +++ b/tests/test-absorb-rev.t @@ -71,10 +71,10 @@ Run absorb: $ hg absorb --apply-changes -s . - 1 new orphan changesets 2 of 2 chunk(s) applied Check that the pending wdir change was left alone: +TODO: The absorbed commit should have disappeared when it became empty. $ hg status M a @@ -87,19 +87,11 @@ 4d 5e +6 - $ hg update -Cq . - -Rebase the absorbed revision on top of the destination (as evolve would): -TODO: the evolve-type operation should happen automatically for the changeset -being absorbed, and even through that the pending wdir change should be left -alone. - - $ hg rebase -d tip -r . - rebasing 5:1631091f9648 "commit to absorb" - note: not rebasing 5:1631091f9648 "commit to absorb", its destination already has all its changes $ hg log -G -T '{node|short} {desc} {instabilities}' - @ 2f7ba78d6abc commit 5 + @ 9a0ec5cae1a1 commit to absorb + | + o 2f7ba78d6abc commit 5 | o 04c8ba6df782 commit 4 | @@ -109,12 +101,15 @@ | o 241ace8326d0 commit 1 - $ hg annotate -c a - 241ace8326d0: 1a - 9b19176bb127: 2b - 484c6ac0cea3: 3 - 04c8ba6df782: 4d - 2f7ba78d6abc: 5e + $ hg annotate -c a -r 'wdir()' + 241ace8326d0 : 1a + 9b19176bb127 : 2b + 484c6ac0cea3 : 3 + 04c8ba6df782 : 4d + 2f7ba78d6abc : 5e + 9a0ec5cae1a1+: 6 + + $ hg diff -c . Do it again, but this time with an unrelated commit checked out (plus working directory changes on top): @@ -145,7 +140,6 @@ 2 changesets affected 2f7ba78 commit 5 04c8ba6 commit 4 - 1 new orphan changesets 1 of 1 chunk(s) applied $ hg annotate -c a -r 'wdir()' @@ -153,19 +147,16 @@ dbce69d9fe03 : committed unrelated dbce69d9fe03+: pending wdir change - - $ hg update -Cq . - - $ hg rebase -d tip -r ${TOABSORB} - rebasing \d+:[0-9a-f]+ "commit to absorb 2" (re) - note: not rebasing \d+:[0-9a-f]+ "commit to absorb 2", its destination already has all its changes (re) + $ hg update -Cq tip $ hg log -G -T '{node|short} {desc} {instabilities}' + @ 59655ff113fb commit to absorb 2 + | o 789b01face13 commit 5 | o 9c83c60f49f2 commit 4 | - | @ dbce69d9fe03 unrelated commit + | o dbce69d9fe03 unrelated commit | | o | 484c6ac0cea3 commit 3 | | @@ -174,7 +165,7 @@ o 241ace8326d0 commit 1 - $ hg annotate -c a -r tip + $ hg annotate -c a 241ace8326d0: 1a 9b19176bb127: 2b 484c6ac0cea3: 3