This instance will be upgraded to Heptapod 0.23.2 on 2021-08-05 at 11:00 UTC+2 (a few minutes of down time)

Commit 87e97868 authored by Sushil Khanchi's avatar Sushil Khanchi 🐨
Browse files

evolve: use 3-way merge to check if only one of them was moved

While deciding the resolution parent for content-divergence resolution,
now we use 3-way merge logic to check, if only one of them was moved from its
original position by applying the logic on following:
(parent of "base", parent of "divergent", parent of "other")

Before this patch, we always set the parent of ahead one (from the two
divergent cset) as resolution parent and then make sure both are located
on resolution parent and perform 3-way merge to get resultant cset.

But now, if the reason behind content-divergence is that one side amended
some content changes while other moved forward/backward in the dag;
we set the parent of relocated one as resolution parent and then make sure both
are on resolution parent and perform 3-way merge.

This patch also adds few new lines to support a case where "one cset moved
somewhere; other moved to successor of base.p1()"

Changes is test files reflect the changed behavior.
parent 067b6bd2728a
......@@ -286,7 +286,7 @@ def _resolvephasedivergent(ui, repo, prec, bumped):
repo.dirstate.setparents(newid, nodemod.nullid)
return (True, replacementnode)
def _pickresolutionparent(ui, repo, divergent, other, evolvestate):
def _pickresolutionparent(ui, repo, divergent, other, base, evolvestate):
"""Return the resolution parent (as rev) for content-divergence.
Decide the cset on which the resolution cset of content-divergence will be
......@@ -322,6 +322,7 @@ def _pickresolutionparent(ui, repo, divergent, other, evolvestate):
otherp1 = succsotherp1 = other.p1().rev()
divp1 = succsdivp1 = divergent.p1().rev()
basep1 = succsbasep1 = base.p1().rev()
# finding single successors of divp1 and otherp1
try:
......@@ -338,6 +339,12 @@ def _pickresolutionparent(ui, repo, divergent, other, evolvestate):
b"%s\n") % (divergent, other)
ui.write_err(msg)
return (False, b".")
try:
succsbasep1 = utility._singlesuccessor(repo, base.p1())
except utility.MultipleSuccessorsError:
msg = _(b"ambiguous orphan resolution parent for "
b"%s (base)\n") % (base)
ui.debug(msg)
# the changeset on which resolution changeset will be based on
resolutionparent = succsdivp1
......@@ -382,39 +389,53 @@ def _pickresolutionparent(ui, repo, divergent, other, evolvestate):
elif divergent == other.p1():
# both are in parent-child relation
pass
elif succsotherp1 == gca and succsdivp1 == gca:
# both are not on the same parent but have same parents's succs.
if otheronly and divonly:
# case: we have visible csets on both side diverging from
# tca of "divergent" and "other". We still need to decide what
# to do in this case
pass
if otheronly:
elif basep1 in (divp1, otherp1):
# only one side moved, set parent of moved one as resolution parent
if basep1 == divp1:
resolutionparent = succsotherp1
elif divonly:
else:
pass
elif succsbasep1 in (divp1, otherp1):
# one of them moved to the successor of base.p1()
# so in another sense, it's not really moved
if succsbasep1 == divp1:
resolutionparent = succsotherp1
else:
# no extra cset on either side
pass
elif succsotherp1 == gca:
pass
elif succsdivp1 == gca:
resolutionparent = succsotherp1
else:
msg = _(b"skipping %s: have a different parent than %s "
b"(not handled yet)\n") % (divergent, other)
hint = _(b"| %(d)s, %(o)s are not based on the same changeset.\n"
b"| With the current state of its implementation,\n"
b"| evolve does not work in that case.\n"
b"| rebase one of them next to the other and run\n"
b"| this command again.\n"
b"| - either: hg rebase --dest 'p1(%(d)s)' -r %(o)s\n"
b"| - or: hg rebase --dest 'p1(%(o)s)' -r %(d)s\n"
) % {b'd': divergent, b'o': other}
ui.write_err(msg)
ui.write_err(hint)
return (False, b".")
# both side moved
if succsotherp1 == gca and succsdivp1 == gca:
# both have same parents's succs.
if otheronly and divonly:
# case: we have visible csets on both side diverging from
# tca of "divergent" and "other". We still need to decide what
# to do in this case
pass
if otheronly:
resolutionparent = succsotherp1
elif divonly:
pass
else:
# no extra cset on either side
pass
elif succsotherp1 == gca:
pass
elif succsdivp1 == gca:
resolutionparent = succsotherp1
else:
msg = _(b"skipping %s: have a different parent than %s "
b"(not handled yet)\n") % (divergent, other)
hint = _(b"| %(d)s, %(o)s are not based on the same changeset.\n"
b"| With the current state of its implementation,\n"
b"| evolve does not work in that case.\n"
b"| rebase one of them next to the other and run\n"
b"| this command again.\n"
b"| - either: hg rebase --dest 'p1(%(d)s)' -r %(o)s\n"
b"| - or: hg rebase --dest 'p1(%(o)s)' -r %(d)s\n"
) % {b'd': divergent, b'o': other}
ui.write_err(msg)
ui.write_err(hint)
return (False, b".")
return (True, resolutionparent)
def _relocatedivergent(repo, orig, dest, evolvestate):
......@@ -478,8 +499,8 @@ def _solvedivergent(ui, repo, divergent, evolvestate, displayer, dryrun=False,
evolvestate[b'old-divergent'] = None
# setup everything before merging two content-divergent csets
picked, resolutionparent = _pickresolutionparent(ui, repo, divergent,
other, evolvestate)
picked, resolutionparent = _pickresolutionparent(ui, repo, divergent, other,
base, evolvestate)
resolutionparent = repo[resolutionparent].node()
if not picked:
return (False, b".")
......
......@@ -24,6 +24,7 @@ other cases.
> [experimental]
> evolution.allowdivergence = True
> [extensions]
> strip=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ mkcommit() {
......@@ -285,9 +286,11 @@ Test None docstring issue of evolve divergent, which caused hg crush
Test to make sure that evolve don't fall into unrecoverable state (issue6053)
------------------------------------------------------------------------------
It happened when two divergent csets has different parent (need relocation)
and resolution parent is obsolete. So this issue triggered when during
relocation we hit conflicts. So lets make the repo as described.
It happened when both the divergent csets has different parents and the cset which is supposed
to be the resolution parent, is obsolete. To resolve divergence we needs to relocate both
divergent csets to the parent of obsoleted "logical resolution parent" and perform 3-way merge.
So lets make a repository as per the case described here.
$ hg init localside
$ cd localside
......@@ -309,19 +312,19 @@ relocation we hit conflicts. So lets make the repo as described.
o 0:9092f1db7931 added a
() [default] draft
$ echo ee > e
$ hg amend -m "updated e"
To make sure we hit conflict while merging
$ hg up 1 -q
To make sure we hit conflict while relocating
$ echo dd > d
$ echo ee > e
$ hg add d e
$ hg ci -m "updated e"
created new head
$ echo eee > e
$ hg amend -m "updated e"
Lets create divergence
$ hg prune 4 -s . --hidden
$ hg prune 5 -s 4 --hidden
1 changesets pruned
2 new content-divergent changesets
......@@ -331,9 +334,9 @@ Making obsolete resolution parent
1 new orphan changesets
$ hg glog
@ 6:de4ea3103326 updated e
@ 6:f0057cbac933 updated e
| () [default] draft
| * 5:ff6f7cd76a7c updated e
| * 4:8d71eadcc9df added e
| | () [default] draft
| x 3:9150fe93bec6 added d
| | () [default] draft
......@@ -347,48 +350,43 @@ Making obsolete resolution parent
$ hg evolve --content-divergent --any --update --config ui.interactive=true <<EOF
> c
> EOF
merge:[5] updated e
merge:[4] added e
with: [6] updated e
base: [4] added e
rebasing "divergent" content-divergent changeset ff6f7cd76a7c on 155349b645be
rebasing "other" content-divergent changeset de4ea3103326 on 155349b645be
file 'd' was deleted in local but was modified in other.
You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
What do you want to do? c
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
working directory is now at 51ee71efed61
base: [5] updated e
rebasing "divergent" content-divergent changeset 8d71eadcc9df on 155349b645be
rebasing "other" content-divergent changeset f0057cbac933 on 155349b645be
merging e
warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
unresolved merge conflicts
(see 'hg help evolve.interrupted')
[240]
$ hg glog -l1
@ 9:51ee71efed61 updated e
@ 8:9d4e11dd79a2 updated e
| () [default] draft
~
$ hg debugobsolete
8d71eadcc9dfb21a924e75a5796c2f011bdc55a4 ff6f7cd76a7c97d938e8fe87f0fc816b66929435 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'amend', 'user': 'test'}
8d71eadcc9dfb21a924e75a5796c2f011bdc55a4 de4ea3103326293994c634101e780724346ee89f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'prune', 'user': 'test'}
de4ea3103326293994c634101e780724346ee89f f0057cbac933cd7dd88f3a4e904052dbe8211212 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
de4ea3103326293994c634101e780724346ee89f 8d71eadcc9dfb21a924e75a5796c2f011bdc55a4 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'prune', 'user': 'test'}
9150fe93bec603cd88d05cda9f6ff13420cb53e9 0 {155349b645beebee15325a9a22dd0c9ef8fbbbd3} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'prune', 'user': 'test'}
ff6f7cd76a7c97d938e8fe87f0fc816b66929435 0ceb21ca2557a61433f097e4d64024e37cae2c10 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
de4ea3103326293994c634101e780724346ee89f a2465d1d56d1aee8ed90d2292978456d2be6f7b9 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
0ceb21ca2557a61433f097e4d64024e37cae2c10 51ee71efed6170064a7155a9a35e56af0292a203 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
a2465d1d56d1aee8ed90d2292978456d2be6f7b9 51ee71efed6170064a7155a9a35e56af0292a203 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
8d71eadcc9dfb21a924e75a5796c2f011bdc55a4 b34dbef3adb673d3389849aa8776fb48de769ba8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
f0057cbac933cd7dd88f3a4e904052dbe8211212 9d4e11dd79a2fb99e42abdea30c47e2c1d670ce3 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
$ hg obslog --all
@ 51ee71efed61 (9) updated e
|\ amended(content) from 0ceb21ca2557 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
| | rewritten from a2465d1d56d1 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
| |
x | 0ceb21ca2557 (7) updated e
| | rebased(parent) from ff6f7cd76a7c using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
| |
| x a2465d1d56d1 (8) updated e
| | rebased(parent) from de4ea3103326 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
@ 9d4e11dd79a2 (8) updated e
| rebased(parent) from f0057cbac933 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
|
| @ b34dbef3adb6 (7) added e
| | rebased(parent) from 8d71eadcc9df using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
| |
| x de4ea3103326 (6) updated e
| | rewritten(description, parent, content) from 8d71eadcc9df using prune by test (Thu Jan 01 00:00:00 1970 +0000)
| x 8d71eadcc9df (4) added e
| | rewritten(description, parent, content) from de4ea3103326 using prune by test (Thu Jan 01 00:00:00 1970 +0000)
| |
x | ff6f7cd76a7c (5) updated e
|/ rewritten(description, content) from 8d71eadcc9df using amend by test (Thu Jan 01 00:00:00 1970 +0000)
x | f0057cbac933 (6) updated e
|/ amended(content) from de4ea3103326 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
|
x 8d71eadcc9df (4) added e
x de4ea3103326 (5) updated e
$ cd ..
......
......@@ -273,28 +273,41 @@ is parent of one of the divergents and relocating leads to conflicts
o 0:8fa14d15e168 added hgignore
() draft
add changes to get merge conflict during relocation
$ hg prev
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
[3] added c
$ echo "some_changes" >> a
$ hg amend
1 new orphan changesets
$ hg next
move:[4] added d
atop:[5] added c
working directory is now at 473b3332cb29
$ hg rebase -r . -d .^^^ --config extensions.rebase=
rebasing 4:c41c793e0ef1 tip "added d"
rebasing 6:473b3332cb29 tip "added d"
$ echo bar > c
$ hg add c
$ hg amend
$ hg up --hidden c41c793e0ef1
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
updated to hidden changeset c41c793e0ef1
(hidden revision 'c41c793e0ef1' was rewritten as: 69bdd23a9b0d)
working directory parent is obsolete! (c41c793e0ef1)
(use 'hg evolve' to update to its successor: 69bdd23a9b0d)
$ hg up --hidden 473b3332cb29
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
updated to hidden changeset 473b3332cb29
(hidden revision '473b3332cb29' was rewritten as: e3cde57538f5)
working directory parent is obsolete! (473b3332cb29)
(use 'hg evolve' to update to its successor: e3cde57538f5)
$ echo bar > d
$ echo "latest_changes" >> a
$ hg amend
2 new content-divergent changesets
$ hg glog
@ 7:e49523854bc8 added d
@ 9:9b560a201f46 added d
| () draft
| * 6:69bdd23a9b0d added d
| * 8:e3cde57538f5 added d
| | () draft
o | 3:ca1b80f7960a added c
o | 5:33c16a2e0eb8 added c
| | () draft
o | 2:b1661037fa25 added b
|/ () draft
......@@ -304,26 +317,26 @@ is parent of one of the divergents and relocating leads to conflicts
() draft
$ hg evolve --content-divergent
merge:[6] added d
with: [7] added d
base: [4] added d
rebasing "divergent" content-divergent changeset 69bdd23a9b0d on ca1b80f7960a
merging c
warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
merge:[8] added d
with: [9] added d
base: [6] added d
rebasing "other" content-divergent changeset 9b560a201f46 on c7586e2a9264
merging a
warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
unresolved merge conflicts
(see 'hg help evolve.interrupted')
[240]
$ hg evolve --abort
evolve aborted
working directory is now at e49523854bc8
working directory is now at 9b560a201f46
$ hg glog
@ 7:e49523854bc8 added d
@ 9:9b560a201f46 added d
| () draft
| * 6:69bdd23a9b0d added d
| * 8:e3cde57538f5 added d
| | () draft
o | 3:ca1b80f7960a added c
o | 5:33c16a2e0eb8 added c
| | () draft
o | 2:b1661037fa25 added b
|/ () draft
......@@ -336,18 +349,18 @@ Creating content-divergence on multiple parents when gca of divergent changesets
is parent of one of the divergents and merging divergent leads to conflicts
---------------------------------------------------------------------------------
$ hg up 69bdd23a9b0d
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg up e3cde57538f5
3 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg rm c
$ echo wat > d
$ hg amend
$ hg glog
@ 8:33e4442acf98 added d
@ 10:19fccc3d3903 added d
| () draft
| * 7:e49523854bc8 added d
| * 9:9b560a201f46 added d
| | () draft
| o 3:ca1b80f7960a added c
| o 5:33c16a2e0eb8 added c
| | () draft
| o 2:b1661037fa25 added b
|/ () draft
......@@ -357,27 +370,40 @@ is parent of one of the divergents and merging divergent leads to conflicts
() draft
$ hg evolve --content-divergent
merge:[7] added d
with: [8] added d
base: [4] added d
rebasing "other" content-divergent changeset 33e4442acf98 on ca1b80f7960a
merge:[9] added d
with: [10] added d
base: [6] added d
rebasing "divergent" content-divergent changeset 9b560a201f46 on c7586e2a9264
merging a
warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
unresolved merge conflicts
(see 'hg help evolve.interrupted')
[240]
$ echo a > a
$ hg res -m
(no more unresolved files)
continue: hg evolve --continue
$ hg evolve -c
evolving 9:9b560a201f46 "added d"
merging a
merging d
warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
0 files updated, 0 files merged, 0 files removed, 2 files unresolved
unresolved merge conflicts
(see 'hg help evolve.interrupted')
[240]
$ hg evolve --abort
evolve aborted
working directory is now at 33e4442acf98
working directory is now at 19fccc3d3903
$ hg glog
@ 8:33e4442acf98 added d
@ 10:19fccc3d3903 added d
| () draft
| * 7:e49523854bc8 added d
| * 9:9b560a201f46 added d
| | () draft
| o 3:ca1b80f7960a added c
| o 5:33c16a2e0eb8 added c
| | () draft
| o 2:b1661037fa25 added b
|/ () draft
......@@ -505,7 +531,7 @@ merging
merge:[5] added d
with: [7] added d
base: [4] added d
rebasing "other" content-divergent changeset 517d4375cb72 on ca1b80f7960a
rebasing "divergent" content-divergent changeset e49523854bc8 on c7586e2a9264
merging d
warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
......@@ -515,12 +541,12 @@ merging
$ hg evolve --stop
stopped the interrupted evolve
working directory is now at 517d4375cb72
working directory is now at e49523854bc8
$ hg glog
@ 7:517d4375cb72 added d
* 7:517d4375cb72 added d
| () draft
| * 5:e49523854bc8 added d
| @ 5:e49523854bc8 added d
| | () draft
| o 3:ca1b80f7960a added c
| | () draft
......@@ -535,17 +561,25 @@ Content-divergence with parent-change which will result in conflicts while
relocation
---------------------------------------------------------------------------
$ echo babar > c
$ hg add c
$ hg up -r 3
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ echo "some_changes" >> a
$ hg amend
1 new orphan changesets
$ hg next
move:[5] added d
atop:[8] added c
working directory is now at dc9ba677cba1
$ echo "latest_changes" >> a
$ hg amend
$ hg glog
@ 8:8fd1c4bd144c added d
@ 10:0892835a581f added d
| () draft
| * 5:e49523854bc8 added d
| | () draft
| o 3:ca1b80f7960a added c
o 8:33c16a2e0eb8 added c
| () draft
| * 7:517d4375cb72 added d
| | () draft
| o 2:b1661037fa25 added b
o | 2:b1661037fa25 added b
|/ () draft
o 1:c7586e2a9264 added a
| () draft
......@@ -553,48 +587,50 @@ relocation
() draft
$ hg evolve --content-divergent
merge:[5] added d
with: [8] added d
merge:[7] added d
with: [10] added d
base: [4] added d
rebasing "other" content-divergent changeset 8fd1c4bd144c on ca1b80f7960a
merging c
warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
rebasing "other" content-divergent changeset 0892835a581f on c7586e2a9264
merging a
warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
unresolved merge conflicts
(see 'hg help evolve.interrupted')
[240]
$ hg diff
diff -r ca1b80f7960a c
--- a/c Thu Jan 01 00:00:00 1970 +0000
+++ b/c Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +1,5 @@
+<<<<<<< destination: ca1b80f7960a - test: added c
diff -r c7586e2a9264 a
--- a/a Thu Jan 01 00:00:00 1970 +0000
+++ b/a Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +1,6 @@
foo
+<<<<<<< destination: c7586e2a9264 - test: added a
+=======
+babar
+>>>>>>> evolving: 8fd1c4bd144c - test: added d
diff -r ca1b80f7960a d
+some_changes
+latest_changes
+>>>>>>> evolving: 0892835a581f - test: added d
diff -r c7586e2a9264 d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/d Thu Jan 01 00:00:00 1970 +0000
@@ -0,0 +1,1 @@
+foobar
+bar
$ hg evolve --stop
stopped the interrupted evolve
working directory is now at ca1b80f7960a
working directory is now at c7586e2a9264
XXX: we should have preserved the wdir to be at rev 8
XXX: we should have preserved the wdir to be at rev 10
$ hg glog
* 8:8fd1c4bd144c added d
* 10:0892835a581f added d
| () draft
| * 5:e49523854bc8 added d
| | () draft
| @ 3:ca1b80f7960a added c
o 8:33c16a2e0eb8 added c
| () draft
| * 7:517d4375cb72 added d
| | () draft
| o 2:b1661037fa25 added b
o | 2:b1661037fa25 added b
|/ () draft
o 1:c7586e2a9264 added a
@ 1:c7586e2a9264 added a
| () draft
o 0:8fa14d15e168 added hgignore
() draft
$ cd ..
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment