rust-status: traverse working directory in parallel
Using `rayon` for this task ensures that we are using the same work-stealing
threadpool for everything.
This change introduces `crossbeam` as an explicit dependency, although it is
already a dependency of `rayon`. It provides better structures for
multi-threaded tasks than the stdlib.
Differential Revision: https://phab.mercurial-scm.org/D8251
=====================================================
Test Copy tracing for chain of copies involving merge
=====================================================
This test files covers copies/rename case for a chains of commit where merges
are involved. It cheks we do not have unwanted update of behavior and that the
different options to retrieve copies behave correctly.
Setup
=====
use git diff to see rename
$ cat << EOF >> $HGRCPATH
> [diff]
> git=yes
> [ui]
> logtemplate={rev} {desc}]\n
> EOF
$ hg init repo-chain
$ cd repo-chain
Add some linear rename initialy
$ touch a b h
$ hg ci -Am 'i-0 initial commit: a b h'
adding a
adding b
adding h
$ hg mv a c
$ hg ci -Am 'i-1: a -move-> c'
$ hg mv c d
$ hg ci -Am 'i-2: c -move-> d'
$ hg log -G
@ 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
And having another branch with renames on the other side
$ hg mv d e
$ hg ci -Am 'a-1: d -move-> e'
$ hg mv e f
$ hg ci -Am 'a-2: e -move-> f'
$ hg log -G --rev '::.'
@ 4 a-2: e -move-> f]
|
o 3 a-1: d -move-> e]
|
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Have a branching with nothing on one side
$ hg up 'desc("i-2")'
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ echo foo > b
$ hg ci -m 'b-1: b update'
created new head
$ hg log -G --rev '::.'
@ 5 b-1: b update]
|
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Merge the two branches we just defined (in both directions)
- one with change to an unrelated file
- one with renames in them
$ hg up 'desc("b-1")'
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 'desc("a-2")'
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mBAm-0 simple merge - one way'
$ hg up 'desc("a-2")'
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 'desc("b-1")'
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mABm-0 simple merge - the other way'
created new head
$ hg log -G --rev '::(desc("mABm")+desc("mBAm"))'
@ 7 mABm-0 simple merge - the other way]
|\
+---o 6 mBAm-0 simple merge - one way]
| |/
| o 5 b-1: b update]
| |
o | 4 a-2: e -move-> f]
| |
o | 3 a-1: d -move-> e]
|/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Create a branch that delete a file previous renamed
$ hg up 'desc("i-2")'
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg rm d
$ hg ci -m 'c-1 delete d'
created new head
$ hg log -G --rev '::.'
@ 8 c-1 delete d]
|
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Merge:
- one with change to an unrelated file
- one deleting the change
and recreate an unrelated file after the merge
$ hg up 'desc("b-1")'
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 'desc("c-1")'
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mBCm-0 simple merge - one way'
$ echo bar > d
$ hg add d
$ hg ci -m 'mBCm-1 re-add d'
$ hg up 'desc("c-1")'
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg merge 'desc("b-1")'
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mCBm-0 simple merge - the other way'
created new head
$ echo bar > d
$ hg add d
$ hg ci -m 'mCBm-1 re-add d'
$ hg log -G --rev '::(desc("mCBm")+desc("mBCm"))'
@ 12 mCBm-1 re-add d]
|
o 11 mCBm-0 simple merge - the other way]
|\
| | o 10 mBCm-1 re-add d]
| | |
+---o 9 mBCm-0 simple merge - one way]
| |/
| o 8 c-1 delete d]
| |
o | 5 b-1: b update]
|/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Create a branch that delete a file previous renamed and recreate it
$ hg up 'desc("i-2")'
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg rm d
$ hg ci -m 'd-1 delete d'
created new head
$ echo bar > d
$ hg add d
$ hg ci -m 'd-2 re-add d'
$ hg log -G --rev '::.'
@ 14 d-2 re-add d]
|
o 13 d-1 delete d]
|
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Merge:
- one with change to an unrelated file
- one deleting and recreating the file
Note:
| In this case, the merge get conflicting information since on one side we have
| a "brand new" d. and one the other one we have "d renamed from c (itself
| renamed from c)".
|
| The current code arbitrarily pick one side
$ hg up 'desc("b-1")'
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 'desc("d-2")'
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mBDm-0 simple merge - one way'
$ hg up 'desc("d-2")'
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 'desc("b-1")'
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mDBm-0 simple merge - the other way'
created new head
$ hg log -G --rev '::(desc("mDBm")+desc("mBDm"))'
@ 16 mDBm-0 simple merge - the other way]
|\
+---o 15 mBDm-0 simple merge - one way]
| |/
| o 14 d-2 re-add d]
| |
| o 13 d-1 delete d]
| |
o | 5 b-1: b update]
|/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Having another branch renaming a different file to the same filename as another
$ hg up 'desc("i-2")'
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg mv b g
$ hg ci -m 'e-1 b -move-> g'
created new head
$ hg mv g f
$ hg ci -m 'e-2 g -move-> f'
$ hg log -G --rev '::.'
@ 18 e-2 g -move-> f]
|
o 17 e-1 b -move-> g]
|
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Merge:
- the "e-" branch renaming b to f (through 'g')
- the "a-" branch renaming d to f (through e)
$ hg up 'desc("a-2")'
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg merge 'desc("e-2")'
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mAEm-0 simple merge - one way'
$ hg up 'desc("e-2")'
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 'desc("a-2")'
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mEAm-0 simple merge - the other way'
created new head
$ hg log -G --rev '::(desc("mAEm")+desc("mEAm"))'
@ 20 mEAm-0 simple merge - the other way]
|\
+---o 19 mAEm-0 simple merge - one way]
| |/
| o 18 e-2 g -move-> f]
| |
| o 17 e-1 b -move-> g]
| |
o | 4 a-2: e -move-> f]
| |
o | 3 a-1: d -move-> e]
|/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Note:
| In this case, one of the merge wrongly record a merge while there is none.
| This lead to bad copy tracing information to be dug up.
Merge:
- one with change to an unrelated file (b)
- one overwriting a file (d) with a rename (from h to i to d)
$ hg up 'desc("i-2")'
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg mv h i
$ hg commit -m "f-1: rename h -> i"
created new head
$ hg mv --force i d
$ hg commit -m "f-2: rename i -> d"
$ hg debugindex d
rev linkrev nodeid p1 p2
0 2 01c2f5eabdc4 000000000000 000000000000
1 10 b004912a8510 000000000000 000000000000
2 15 0bb5445dc4d0 01c2f5eabdc4 b004912a8510
3 22 c72365ee036f 000000000000 000000000000
$ hg up 'desc("b-1")'
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 'desc("f-2")'
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mBFm-0 simple merge - one way'
$ hg up 'desc("f-2")'
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 'desc("b-1")'
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mFBm-0 simple merge - the other way'
created new head
$ hg log -G --rev '::(desc("mBFm")+desc("mFBm"))'
@ 24 mFBm-0 simple merge - the other way]
|\
+---o 23 mBFm-0 simple merge - one way]
| |/
| o 22 f-2: rename i -> d]
| |
| o 21 f-1: rename h -> i]
| |
o | 5 b-1: b update]
|/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Merge:
- one with change to a file
- one deleting and recreating the file
$ hg up 'desc("i-2")'
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ echo "some update" >> d
$ hg commit -m "g-1: update d"
created new head
$ hg up 'desc("d-2")'
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 'desc("g-1")' --tool :union
merging d
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mDGm-0 simple merge - one way'
$ hg up 'desc("g-1")'
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 'desc("d-2")' --tool :union
merging d
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mGDm-0 simple merge - the other way'
created new head
$ hg log -G --rev '::(desc("mDGm")+desc("mGDm"))'
@ 27 mGDm-0 simple merge - the other way]
|\
+---o 26 mDGm-0 simple merge - one way]
| |/
| o 25 g-1: update d]
| |
o | 14 d-2 re-add d]
| |
o | 13 d-1 delete d]
|/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Merge:
- one with change to a file (d)
- one overwriting that file with a rename (from h to i, to d)
$ hg up 'desc("f-2")'
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg merge 'desc("g-1")' --tool :union
merging d
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mFGm-0 simple merge - one way'
created new head
$ hg up 'desc("g-1")'
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 'desc("f-2")' --tool :union
merging d
0 files updated, 1 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m 'mGFm-0 simple merge - the other way'
created new head
$ hg log -G --rev '::(desc("mGFm")+desc("mFGm"))'
@ 29 mGFm-0 simple merge - the other way]
|\
+---o 28 mFGm-0 simple merge - one way]
| |/
| o 25 g-1: update d]
| |
o | 22 f-2: rename i -> d]
| |
o | 21 f-1: rename h -> i]
|/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Check results
=============
merging with unrelated change does not interfer wit the renames
---------------------------------------------------------------
- rename on one side
- unrelated change on the other side
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mABm")'
A f
d
R d
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBAm")'
A f
d
R d
$ hg status --copies --rev 'desc("a-2")' --rev 'desc("mABm")'
M b
$ hg status --copies --rev 'desc("a-2")' --rev 'desc("mBAm")'
M b
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("mABm")'
M b
A f
d
R d
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBAm")'
M b
A f
d
R d
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mABm")'
M b
A f
a
R a
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBAm")'
M b
A f
a
R a
merging with the side having a delete
-------------------------------------
case summary:
- one with change to an unrelated file
- one deleting the change
and recreate an unrelated file after the merge
checks:
- comparing from the merge
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBCm-0")'
R d
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCBm-0")'
R d
$ hg status --copies --rev 'desc("c-1")' --rev 'desc("mBCm-0")'
M b
$ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCBm-0")'
M b
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBCm-0")'
M b
R d
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("mCBm-0")'
M b
R d
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBCm-0")'
M b
R a
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCBm-0")'
M b
R a
- comparing with the merge children re-adding the file
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBCm-1")'
M d
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCBm-1")'
M d
$ hg status --copies --rev 'desc("c-1")' --rev 'desc("mBCm-1")'
M b
A d
$ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCBm-1")'
M b
A d
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBCm-1")'
M b
M d
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("mCBm-1")'
M b
M d
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBCm-1")'
M b
A d
R a
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCBm-1")'
M b
A d
R a
Comparing with a merge re-adding the file afterward
---------------------------------------------------
Merge:
- one with change to an unrelated file
- one deleting and recreating the change
Note:
| In this case, one of the merge wrongly record a merge while there is none.
| This lead to bad copy tracing information to be dug up.
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBDm-0")'
M d
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mDBm-0")'
M d
$ hg status --copies --rev 'desc("d-2")' --rev 'desc("mBDm-0")'
M b
M d
$ hg status --copies --rev 'desc("d-2")' --rev 'desc("mDBm-0")'
M b
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBDm-0")'
M b
M d
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("mDBm-0")'
M b
M d
The bugs makes recorded copy is different depending of where we started the merge from since
$ hg manifest --debug --rev 'desc("mBDm-0")' | grep '644 d'
0bb5445dc4d02f4e0d86cf16f9f3a411d0f17744 644 d
$ hg manifest --debug --rev 'desc("mDBm-0")' | grep '644 d'
b004912a8510032a0350a74daa2803dadfb00e12 644 d
The 0bb5445dc4d02f4e0d86cf16f9f3a411d0f17744 entry is wrong, since the file was
deleted on one side (then recreate) and untouched on the other side, no "merge"
has happened. The resulting `d` file is the untouched version from branch `D`,
not a merge.
$ hg manifest --debug --rev 'desc("d-2")' | grep '644 d'
b004912a8510032a0350a74daa2803dadfb00e12 644 d
$ hg manifest --debug --rev 'desc("b-1")' | grep '644 d'
01c2f5eabdc4ce2bdee42b5f86311955e6c8f573 644 d
$ hg debugindex d
rev linkrev nodeid p1 p2
0 2 01c2f5eabdc4 000000000000 000000000000
1 10 b004912a8510 000000000000 000000000000
2 15 0bb5445dc4d0 01c2f5eabdc4 b004912a8510
3 22 c72365ee036f 000000000000 000000000000
4 23 863d9bc49190 01c2f5eabdc4 c72365ee036f
5 25 7bded9d9da1f 01c2f5eabdc4 000000000000
6 26 f04cac32d703 b004912a8510 7bded9d9da1f
7 27 d7a5eafb9322 7bded9d9da1f b004912a8510
8 28 2ed7a51aed47 c72365ee036f 7bded9d9da1f
(This `hg log` output if wrong, since no merge actually happened).
$ hg log -Gfr 'desc("mBDm-0")' d
o 15 mBDm-0 simple merge - one way]
|\
o : 14 d-2 re-add d]
:/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
This `hg log` output is correct
$ hg log -Gfr 'desc("mDBm-0")' d
o 14 d-2 re-add d]
|
~
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBDm-0")'
M b
A d
a
R a
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mDBm-0")'
M b
A d
R a
Comparing with a merge with colliding rename
--------------------------------------------
- the "e-" branch renaming b to f (through 'g')
- the "a-" branch renaming d to f (through e)
$ hg manifest --debug --rev 'desc("mAEm-0")' | grep '644 f'
eb806e34ef6be4c264effd5933d31004ad15a793 644 f
$ hg manifest --debug --rev 'desc("mEAm-0")' | grep '644 f'
eb806e34ef6be4c264effd5933d31004ad15a793 644 f
$ hg manifest --debug --rev 'desc("a-2")' | grep '644 f'
0dd616bc7ab1a111921d95d76f69cda5c2ac539c 644 f
$ hg manifest --debug --rev 'desc("e-2")' | grep '644 f'
6da5a2eecb9c833f830b67a4972366d49a9a142c 644 f
$ hg debugindex f
rev linkrev nodeid p1 p2
0 4 0dd616bc7ab1 000000000000 000000000000
1 18 6da5a2eecb9c 000000000000 000000000000
2 19 eb806e34ef6b 0dd616bc7ab1 6da5a2eecb9c
$ hg status --copies --rev 'desc("a-2")' --rev 'desc("mAEm-0")'
M f
R b
$ hg status --copies --rev 'desc("a-2")' --rev 'desc("mEAm-0")'
M f
R b
$ hg status --copies --rev 'desc("e-2")' --rev 'desc("mAEm-0")'
M f
R d
$ hg status --copies --rev 'desc("e-2")' --rev 'desc("mEAm-0")'
M f
R d
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("a-2")'
A f
d
R d
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("e-2")'
A f
b
R b
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("mAEm-0")'
A f
d
R b
R d
$ hg status --copies --rev 'desc("i-2")' --rev 'desc("mEAm-0")'
A f
d
R b
R d
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mAEm-0")'
A f
a
R a
R b
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mEAm-0")'
A f
a
R a
R b
Merge:
- one with change to an unrelated file (b)
- one overwriting a file (d) with a rename (from h to i to d)
The overwriting should take over. However, the behavior is currently buggy
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBFm-0")'
M b
A d
a (true !)
h (false !)
R a
R h
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFBm-0")'
M b
A d
h
R a
R h
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBFm-0")'
M d
R h
$ hg status --copies --rev 'desc("f-2")' --rev 'desc("mBFm-0")'
M b
M d
$ hg status --copies --rev 'desc("f-1")' --rev 'desc("mBFm-0")'
M b
M d
R i
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mFBm-0")'
M d
R h
$ hg status --copies --rev 'desc("f-2")' --rev 'desc("mFBm-0")'
M b
$ hg status --copies --rev 'desc("f-1")' --rev 'desc("mFBm-0")'
M b
M d
R i
The following graphlog is wrong, the "a -> c -> d" chain was overwritten and should not appear.
$ hg log -Gfr 'desc("mBFm-0")' d
o 23 mBFm-0 simple merge - one way]
|\
o : 22 f-2: rename i -> d]
| :
o : 21 f-1: rename h -> i]
:/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
The following output is correct.
$ hg log -Gfr 'desc("mFBm-0")' d
o 22 f-2: rename i -> d]
|
o 21 f-1: rename h -> i]
:
o 0 i-0 initial commit: a b h]
Merge:
- one with change to a file
- one deleting and recreating the file
Unlike in the 'BD/DB' cases, an actuall merge happened here. So we should
consider history and rename on both branch of the merge.
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mDGm-0")'
A d
a
R a
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGDm-0")'
A d
a
R a
$ hg status --copies --rev 'desc("d-2")' --rev 'desc("mDGm-0")'
M d
$ hg status --copies --rev 'desc("d-2")' --rev 'desc("mGDm-0")'
M d
$ hg status --copies --rev 'desc("g-1")' --rev 'desc("mDGm-0")'
M d
$ hg status --copies --rev 'desc("g-1")' --rev 'desc("mGDm-0")'
M d
$ hg log -Gfr 'desc("mDGm-0")' d
o 26 mDGm-0 simple merge - one way]
|\
| o 25 g-1: update d]
| |
o | 14 d-2 re-add d]
|/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
$ hg log -Gfr 'desc("mDGm-0")' d
o 26 mDGm-0 simple merge - one way]
|\
| o 25 g-1: update d]
| |
o | 14 d-2 re-add d]
|/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
Merge:
- one with change to a file (d)
- one overwriting that file with a rename (from h to i, to d)
This case is similar to BF/FB, but an actual merge happens, so both side of the
history are relevant.
Note:
| In this case, the merge get conflicting information since on one side we have
| "a -> c -> d". and one the other one we have "h -> i -> d".
|
| The current code arbitrarily pick one side
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFGm-0")'
A d
a
R a
R h
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mGFm-0")'
A d
a
R a
R h
$ hg status --copies --rev 'desc("f-2")' --rev 'desc("mFGm-0")'
M d
$ hg status --copies --rev 'desc("f-2")' --rev 'desc("mGFm-0")'
M d
$ hg status --copies --rev 'desc("f-1")' --rev 'desc("mFGm-0")'
M d
R i
$ hg status --copies --rev 'desc("f-1")' --rev 'desc("mGFm-0")'
M d
R i
$ hg status --copies --rev 'desc("g-1")' --rev 'desc("mFGm-0")'
M d
R h
$ hg status --copies --rev 'desc("g-1")' --rev 'desc("mGFm-0")'
M d
R h
$ hg log -Gfr 'desc("mFGm-0")' d
o 28 mFGm-0 simple merge - one way]
|\
| o 25 g-1: update d]
| |
o | 22 f-2: rename i -> d]
| |
o | 21 f-1: rename h -> i]
|/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]
$ hg log -Gfr 'desc("mGFm-0")' d
@ 29 mGFm-0 simple merge - the other way]
|\
| o 25 g-1: update d]
| |
o | 22 f-2: rename i -> d]
| |
o | 21 f-1: rename h -> i]
|/
o 2 i-2: c -move-> d]
|
o 1 i-1: a -move-> c]
|
o 0 i-0 initial commit: a b h]