evolve: refactor content-divergence resolution logic
> What is the case we are looking at?
This is about refactoring the part of content-div resolution logic where it
decides which cset should be relocated and where.
> What is a "topologicial common ancestors" vs a "greatest common ancestors"?
`tca` is an ancestor which we can decide/find by looking at the at graph
visually for e.g
```
c3(*) c4(*)
| |
c2(x) c1(x)
c5 | /
\ | /
c0
```
(c5 is the successor of c2 and c1)
now here,
`tca` of c3 and c4 is: c0
`gca` of c3 and c4 is: c5
> What is the new top-level logic/behavior that makes it better?
The old code had some unnecessary edge cases just because we were using `gca`,
since it can point to a revision that is not a topological ancestor.
For e.g see b779b40f996e
Eventually, the code around this was getting messy unnecessarily. So I looked
into it and found a simple and more robust approach.
And in new code, it is simple and straightforward (and easy to understand),
where we handle the following 4 cases when solving content-div:
1) when both are on the same parent
=> (no need to do anything special, and simply proceed)
2) both are on the different parent but a) `tca` is the parent of one of them
or b) there is no non-obsolete revision between `tca` and one of the
divergent cset.
=> (relocate one to the other side and proceed)
3) both are on different parents and `tca` is not the parent of any of them and
there is at least one non-obsolete cset between tca and both the divergent
cset i.e (tca::div1) and (tca::div2) both the ranges have at least one non-obs
revision.
=> (this is the case which we don't handle yet, but the solution would be to
prompt the user to choose an evolve destination.)
4) both are in the parent-child relation
=> (both are merged and new cset will be based on the successor of `tca`)
Changes in test-evolve-issue5958.t demonstrate that new code also covered case4
because in a resolution of "two divergent csets with parent-child relation"
there should be one cset as a result and no orphan revs (as you can see there
was an orphan before this patch).
Content divergence and trying to relocate a node on top of itself (issue5958)
https://bz.mercurial-scm.org/show_bug.cgi?id=5958
$ . $TESTDIR/testlib/common.sh
$ cat << EOF >> $HGRCPATH
> [extensions]
> rebase =
> evolve =
> EOF
$ hg init issue5958
$ cd issue5958
$ echo hi > r0
$ hg ci -qAm 'add r0'
$ echo hi > foo.txt
$ hg ci -qAm 'add foo.txt'
$ hg metaedit -r . -d '0 2'
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
(Make changes in unrelated files so that we don't have any merge conflicts
during the rebase, but the two touched revisions aren't identical)
$ echo hi > bar.txt
$ hg add -q bar.txt
$ hg amend -q
$ hg metaedit -r 1 -d '0 1' --hidden
2 new content-divergent changesets
$ hg log -r tip
changeset: 4:c17bf400a278
tag: tip
parent: 0:a24ed8ad918c
user: test
date: Wed Dec 31 23:59:59 1969 -0000
instability: content-divergent
summary: add foo.txt
$ echo hi > baz.txt
$ hg add -q baz.txt
$ hg amend -q
$ hg rebase -qr tip -d 4
$ hg log -G
@ changeset: 6:08bc7ba82799
| tag: tip
| parent: 4:c17bf400a278
| user: test
| date: Wed Dec 31 23:59:58 1969 -0000
| instability: content-divergent
| summary: add foo.txt
|
* changeset: 4:c17bf400a278
| parent: 0:a24ed8ad918c
| user: test
| date: Wed Dec 31 23:59:59 1969 -0000
| instability: content-divergent
| summary: add foo.txt
|
o changeset: 0:a24ed8ad918c
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: add r0
$ hg obslog -a -r .
@ 08bc7ba82799 (6) add foo.txt
|
| * c17bf400a278 (4) add foo.txt
| |
x | 1d1fc409af98 (5) add foo.txt
| | rewritten(parent, content) as 08bc7ba82799 using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
| |
x | a25dd7af6cf6 (3) add foo.txt
| | rewritten(content) as 1d1fc409af98 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
| |
x | 0065551bd38f (2) add foo.txt
|/ rewritten(content) as a25dd7af6cf6 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
|
x cc71ffbc7c00 (1) add foo.txt
rewritten(date) as 0065551bd38f using metaedit by test (Thu Jan 01 00:00:00 1970 +0000)
rewritten(date) as c17bf400a278 using metaedit by test (Thu Jan 01 00:00:00 1970 +0000)
$ hg evolve --content-divergent
merge:[4] add foo.txt
with: [6] add foo.txt
base: [1] add foo.txt
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
working directory is now at 95a06d27be64
$ hg log -Gp
@ changeset: 7:95a06d27be64
| tag: tip
| parent: 0:a24ed8ad918c
| user: test
| date: Wed Dec 31 23:59:58 1969 -0000
| summary: add foo.txt
|
| diff -r a24ed8ad918c -r 95a06d27be64 bar.txt
| --- /dev/null Thu Jan 01 00:00:00 1970 +0000
| +++ b/bar.txt Wed Dec 31 23:59:58 1969 -0000
| @@ -0,0 +1,1 @@
| +hi
| diff -r a24ed8ad918c -r 95a06d27be64 baz.txt
| --- /dev/null Thu Jan 01 00:00:00 1970 +0000
| +++ b/baz.txt Wed Dec 31 23:59:58 1969 -0000
| @@ -0,0 +1,1 @@
| +hi
| diff -r a24ed8ad918c -r 95a06d27be64 foo.txt
| --- /dev/null Thu Jan 01 00:00:00 1970 +0000
| +++ b/foo.txt Wed Dec 31 23:59:58 1969 -0000
| @@ -0,0 +1,1 @@
| +hi
|
o changeset: 0:a24ed8ad918c
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: add r0
diff -r 000000000000 -r a24ed8ad918c r0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/r0 Thu Jan 01 00:00:00 1970 +0000
@@ -0,0 +1,1 @@
+hi