absorb: do not strip innocent children

Summary:
`repair.strip` removes required revisions and their children unconditionally.
That means innocent children may be removed. This patch fixes it.

We may want to have an in-core function for this feature to not strip innocent
children.

Thanks Zibi Braniecki from Mozilla for reporting [1]!

[1]: https://bitbucket.org/facebook/hg-experimental/issues/6/hg-absorb-merges-diverged-commits

Test Plan: Added a test

Reviewers: #mercurial, durham

Reviewed By: durham

Subscribers: mjpieters

Differential Revision: https://phabricator.intern.facebook.com/D5073342

Signature: t1:5073342:1494972231:ca2a9881415119047771c8f35e059f4bfb1749e5
This commit is contained in:
Jun Wu 2017-05-16 16:25:00 -07:00
parent b1a694579e
commit 24d8640017
2 changed files with 50 additions and 0 deletions

View File

@ -816,6 +816,11 @@ class fixupstate(object):
def _stripoldcommits(self):
nodelist = self.replacemap.keys()
# make sure we don't strip innocent children
revs = self.repo.revs('%ln - (::(heads(%ln::)-%ln))', nodelist,
nodelist, nodelist)
tonode = self.repo.changelog.node
nodelist = [tonode(r) for r in revs]
if nodelist:
repair.strip(self.repo.ui, self.repo, nodelist)

45
tests/test-absorb-strip.t Normal file
View File

@ -0,0 +1,45 @@
Do not strip innocent children. See https://bitbucket.org/facebook/hg-experimental/issues/6/hg-absorb-merges-diverged-commits
$ cat >> $HGRCPATH << EOF
> [extensions]
> absorb=$TESTDIR/../hgext3rd/absorb
> drawdag=$RUNTESTDIR/drawdag.py
> EOF
$ hg init
$ hg debugdrawdag << EOF
> E
> |
> D F
> |/
> C
> |
> B
> |
> A
> EOF
$ hg up E -q
$ echo 1 >> B
$ echo 2 >> D
$ hg absorb
saved backup bundle to * (glob)
2 of 2 chunk(s) applied
$ hg log -G -T '{desc}'
@ E
|
o D
|
o C
|
o B
|
| o F
| |
| o C
| |
| o B
|/
o A