As the current test misbehavior show, this confuse various part of the code:
- the committed file is different depending of the commit source,
- the upgrade code compute the wrong information on this changeset.
This will be fixed in upcoming patches.
( )
hg-reviewers |
As the current test misbehavior show, this confuse various part of the code:
This will be fixed in upcoming patches.
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
|/ | |/ | ||||
o i-2: c -move-> d, s -move-> t | o i-2: c -move-> d, s -move-> t | ||||
| | | | ||||
o i-1: a -move-> c, p -move-> s | o i-1: a -move-> c, p -move-> s | ||||
| | | | ||||
o i-0 initial commit: a b h p q r | o i-0 initial commit: a b h p q r | ||||
Subcase: merge overwrite common copy information, but with extra change during the merge | |||||
```````````````````````````````````````````````````````````````````````````````````````` | |||||
Merge: | |||||
- one with change to an unrelated file (b) | |||||
- one overwriting a file (d) with a rename (from h to i to d) | |||||
- the merge update f content | |||||
$ case_desc="merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d)" | |||||
$ hg up 'desc("f-2")' | |||||
2 files updated, 0 files merged, 2 files removed, 0 files unresolved | |||||
#if no-changeset | |||||
$ hg debugindex d | ../no-linkrev | |||||
rev linkrev nodeid p1 p2 | |||||
0 * d8252ab2e760 000000000000 000000000000 | |||||
1 * b004912a8510 000000000000 000000000000 | |||||
2 * 7b79e2fe0c89 000000000000 000000000000 | |||||
3 * 17ec97e60577 d8252ab2e760 000000000000 | |||||
4 * 06dabf50734c b004912a8510 17ec97e60577 | |||||
5 * 19c0e3924691 17ec97e60577 b004912a8510 | |||||
6 * 89c873a01d97 7b79e2fe0c89 17ec97e60577 | |||||
7 * d55cb4e9ef57 000000000000 000000000000 | |||||
#else | |||||
$ hg debugindex d | ../no-linkrev | |||||
rev linkrev nodeid p1 p2 | |||||
0 * ae258f702dfe 000000000000 000000000000 | |||||
1 * b004912a8510 000000000000 000000000000 | |||||
2 * 5cce88bf349f ae258f702dfe 000000000000 | |||||
3 * cc269dd788c8 b004912a8510 5cce88bf349f | |||||
4 * 51c91a115080 5cce88bf349f b004912a8510 | |||||
#endif | |||||
$ hg up 'desc("b-1")' | |||||
3 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-changeset !) | |||||
2 files updated, 0 files merged, 0 files removed, 0 files unresolved (changeset !) | |||||
$ hg merge 'desc("f-2")' | |||||
1 files updated, 0 files merged, 1 files removed, 0 files unresolved (no-changeset !) | |||||
0 files updated, 0 files merged, 1 files removed, 0 files unresolved (changeset !) | |||||
(branch merge, don't forget to commit) | |||||
$ echo "extra-change to (formelly h) during the merge" > d | |||||
$ hg ci -m "mBF-change-m-0 $case_desc - one way" | |||||
created new head | |||||
$ hg manifest --rev . --debug | grep " d" | |||||
1c334238bd42ec85c6a0d83fd1b2a898a6a3215d 644 d (no-changeset !) | |||||
cea2d99c0fde64672ef61953786fdff34f16e230 644 d (changeset !) | |||||
$ 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) | |||||
$ echo "extra-change to (formelly h) during the merge" > d | |||||
$ hg ci -m "mFB-change-m-0 $case_desc - the other way" | |||||
created new head | |||||
$ hg manifest --rev . --debug | grep " d" | |||||
1c334238bd42ec85c6a0d83fd1b2a898a6a3215d 644 d (no-changeset missing-correct-output !) | |||||
646ed7992dec41eb29635ab28268e7867d0e59a0 644 d (no-changeset known-bad-output !) | |||||
cea2d99c0fde64672ef61953786fdff34f16e230 644 d (changeset !) | |||||
#if no-changeset | |||||
$ hg debugindex d | ../no-linkrev | |||||
rev linkrev nodeid p1 p2 | |||||
0 * d8252ab2e760 000000000000 000000000000 | |||||
1 * b004912a8510 000000000000 000000000000 | |||||
2 * 7b79e2fe0c89 000000000000 000000000000 | |||||
3 * 17ec97e60577 d8252ab2e760 000000000000 | |||||
4 * 06dabf50734c b004912a8510 17ec97e60577 | |||||
5 * 19c0e3924691 17ec97e60577 b004912a8510 | |||||
6 * 89c873a01d97 7b79e2fe0c89 17ec97e60577 | |||||
7 * d55cb4e9ef57 000000000000 000000000000 | |||||
8 * 1c334238bd42 7b79e2fe0c89 000000000000 | |||||
9 * 646ed7992dec 7b79e2fe0c89 d8252ab2e760 (known-bad-output !) | |||||
#else | |||||
$ hg debugindex d | ../no-linkrev | |||||
rev linkrev nodeid p1 p2 | |||||
0 * ae258f702dfe 000000000000 000000000000 | |||||
1 * b004912a8510 000000000000 000000000000 | |||||
2 * 5cce88bf349f ae258f702dfe 000000000000 | |||||
3 * cc269dd788c8 b004912a8510 5cce88bf349f | |||||
4 * 51c91a115080 5cce88bf349f b004912a8510 | |||||
5 * cea2d99c0fde ae258f702dfe 000000000000 | |||||
#endif | |||||
$ hg log -G --rev '::(desc("mBF-change-m")+desc("mFB-change-m"))' | |||||
@ mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way | |||||
|\ | |||||
+---o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way | |||||
| |/ | |||||
| o f-2: rename i -> d | |||||
| | | |||||
| o f-1: rename h -> i | |||||
| | | |||||
o | b-1: b update | |||||
|/ | |||||
o i-2: c -move-> d, s -move-> t | |||||
| | |||||
o i-1: a -move-> c, p -move-> s | |||||
| | |||||
o i-0 initial commit: a b h p q r | |||||
Decision from previous merge are properly chained with later merge | Decision from previous merge are properly chained with later merge | ||||
------------------------------------------------------------------ | ------------------------------------------------------------------ | ||||
Subcase: chaining conflicting rename resolution | Subcase: chaining conflicting rename resolution | ||||
``````````````````````````````````````````````` | ``````````````````````````````````````````````` | ||||
The "mAEm" and "mEAm" case create a rename tracking conflict on file 'f'. We | The "mAEm" and "mEAm" case create a rename tracking conflict on file 'f'. We | ||||
add more change on the respective branch and merge again. These second merge | add more change on the respective branch and merge again. These second merge | ||||
does not involve the file 'f' and the arbitration done within "mAEm" and "mEA" | does not involve the file 'f' and the arbitration done within "mAEm" and "mEA" | ||||
about that file should stay unchanged. | about that file should stay unchanged. | ||||
$ case_desc="chained merges (conflict -> simple) - same content everywhere" | $ case_desc="chained merges (conflict -> simple) - same content everywhere" | ||||
(extra unrelated changes) | (extra unrelated changes) | ||||
$ hg up 'desc("a-2")' | $ hg up 'desc("a-2")' | ||||
2 files updated, 0 files merged, 0 files removed, 0 files unresolved | 3 files updated, 0 files merged, 1 files removed, 0 files unresolved | ||||
$ echo j > unrelated-j | $ echo j > unrelated-j | ||||
$ hg add unrelated-j | $ hg add unrelated-j | ||||
$ hg ci -m 'j-1: unrelated changes (based on the "a" series of changes)' | $ hg ci -m 'j-1: unrelated changes (based on the "a" series of changes)' | ||||
created new head | created new head | ||||
$ hg up 'desc("e-2")' | $ hg up 'desc("e-2")' | ||||
2 files updated, 0 files merged, 2 files removed, 0 files unresolved (no-changeset !) | 2 files updated, 0 files merged, 2 files removed, 0 files unresolved (no-changeset !) | ||||
1 files updated, 0 files merged, 2 files removed, 0 files unresolved (changeset !) | 1 files updated, 0 files merged, 2 files removed, 0 files unresolved (changeset !) | ||||
mAE-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - one way | mAE-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - one way | ||||
mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way | mAEm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - one way | ||||
mBAm-0 simple merge - A side: multiple renames, B side: unrelated update - one way | mBAm-0 simple merge - A side: multiple renames, B side: unrelated update - one way | ||||
mBC+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists) | mBC+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists) | ||||
mBC-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way | mBC-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - the other way | ||||
mBCm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - one way | mBCm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - one way | ||||
mBCm-1 re-add d | mBCm-1 re-add d | ||||
mBDm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - one way | mBDm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - one way | ||||
mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way | |||||
mBFm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way | mBFm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way | ||||
mBRm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - one way | mBRm-0 simple merge - B side: unrelated change, R side: overwrite d with a copy (from r->x->t) different content - one way | ||||
mCB+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists) | mCB+revert,Lm: chained merges (salvaged -> simple) - same content (when the file exists) | ||||
mCB-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way | mCB-revert-m-0 merge explicitely revive deleted file - B side: unrelated change, C side: delete d (restored by merge) - one way | ||||
mCBm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - the other way | mCBm-0 simple merge - C side: delete a file with copies history , B side: unrelated update - the other way | ||||
mCBm-1 re-add d | mCBm-1 re-add d | ||||
mCGm-0 merge updated/deleted - revive the file (updated content) - one way | mCGm-0 merge updated/deleted - revive the file (updated content) - one way | ||||
mCH-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - one way | mCH-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - one way | ||||
mDBm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - the other way | mDBm-0 simple merge - B side: unrelated update, D side: delete and recreate a file (with different content) - the other way | ||||
mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way | mDGm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - one way | ||||
mEA,Jm: chained merges (conflict -> simple) - same content everywhere | mEA,Jm: chained merges (conflict -> simple) - same content everywhere | ||||
mEA-change,Jm: chained merges (conflict+change -> simple) - same content on both branch in the initial merge | mEA-change,Jm: chained merges (conflict+change -> simple) - same content on both branch in the initial merge | ||||
mEA-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - the other way | mEA-change-m-0 merge with file update and copies info on both side - A side: rename d to f, E side: b to f, (same content for f in parent) - the other way | ||||
mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way | mEAm-0 merge with copies info on both side - A side: rename d to f, E side: b to f, (same content for f) - the other way | ||||
mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way | |||||
mFBm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way | mFBm-0 simple merge - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way | ||||
mFG,Om: chained merges (copy-overwrite -> simple) - same content | mFG,Om: chained merges (copy-overwrite -> simple) - same content | ||||
mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way | mFGm-0 merge - G side: content change, F side: copy overwrite, no content change - one way | ||||
mGCm-0 merge updated/deleted - revive the file (updated content) - the other way | mGCm-0 merge updated/deleted - revive the file (updated content) - the other way | ||||
mGDm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - the other way | mGDm-0 actual content merge, copies on one side - D side: delete and re-add (different content), G side: update content - the other way | ||||
mGF,Nm: chained merges (copy-overwrite -> simple) - same content | mGF,Nm: chained merges (copy-overwrite -> simple) - same content | ||||
mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way | mGFm-0 merge - G side: content change, F side: copy overwrite, no content change - the other way | ||||
mHC-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - the other way | mHC-delete-before-conflict-m-0 simple merge - C side: d is the results of renames then deleted, H side: d is result of another rename (same content as the other branch) - the other way | ||||
entry-0014 size 14 | entry-0014 size 14 | ||||
'\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f' | '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f' | ||||
merged : f, ; | merged : f, ; | ||||
##### revision "mEA-change-m-0 merge with file update and copies info on both side - A side" ##### | ##### revision "mEA-change-m-0 merge with file update and copies info on both side - A side" ##### | ||||
1 sidedata entries | 1 sidedata entries | ||||
entry-0014 size 14 | entry-0014 size 14 | ||||
'\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f' | '\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00f' | ||||
merged : f, ; | merged : f, ; | ||||
##### revision "mBF-change-m-0 merge with extra change - B side" ##### | |||||
1 sidedata entries | |||||
entry-0014 size 14 | |||||
'\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d' (no-upgraded no-upgraded-parallel !) | |||||
touched : d, ; (no-upgraded no-upgraded-parallel !) | |||||
'\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d' (upgraded missing-correct-output !) | |||||
touched : d, ; (upgraded missing-correct-output !) | |||||
'\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d' (upgraded known-bad-output !) | |||||
merged : d, ; (upgraded known-bad-output !) | |||||
'\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d' (upgraded-parallel missing-correct-output !) | |||||
touched : d, ; (upgraded-parallel missing-correct-output !) | |||||
'\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d' (upgraded-parallel known-bad-output !) | |||||
merged : d, ; (upgraded-parallel known-bad-output !) | |||||
##### revision "mFB-change-m-0 merge with extra change - B side" ##### | |||||
1 sidedata entries | |||||
entry-0014 size 14 | |||||
'\x00\x00\x00\x01\x08\x00\x00\x00\x01\x00\x00\x00\x00d' (known-bad-output !) | |||||
merged : d, ; (known-bad-output !) | |||||
'\x00\x00\x00\x01\x14\x00\x00\x00\x01\x00\x00\x00\x00d' (missing-correct-output !) | |||||
touched : d, ; (missing-correct-output !) | |||||
##### revision "j-1" ##### | ##### revision "j-1" ##### | ||||
1 sidedata entries | 1 sidedata entries | ||||
entry-0014 size 24 | entry-0014 size 24 | ||||
'\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-j' | '\x00\x00\x00\x01\x04\x00\x00\x00\x0b\x00\x00\x00\x00unrelated-j' | ||||
added : unrelated-j, ; | added : unrelated-j, ; | ||||
##### revision "k-1" ##### | ##### revision "k-1" ##### | ||||
1 sidedata entries | 1 sidedata entries | ||||
entry-0014 size 24 | entry-0014 size 24 | ||||
b (no-filelog !) | b (no-filelog !) | ||||
A t | A t | ||||
p | p | ||||
R a | R a | ||||
R b | R b | ||||
R p | R p | ||||
Subcase: merge overwrite common copy information, but with extra change during the merge | |||||
``````````````````````````````````````````````````````````````````````````````````` | |||||
Merge: | |||||
- one with change to an unrelated file (b) | |||||
- one overwriting a file (d) with a rename (from h to i to d) | |||||
$ hg log -G --rev '::(desc("mBF-change-m")+desc("mFB-change-m"))' | |||||
o mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way | |||||
|\ | |||||
+---o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way | |||||
| |/ | |||||
| o f-2: rename i -> d | |||||
| | | |||||
| o f-1: rename h -> i | |||||
| | | |||||
o | b-1: b update | |||||
|/ | |||||
o i-2: c -move-> d, s -move-> t | |||||
| | |||||
o i-1: a -move-> c, p -move-> s | |||||
| | |||||
o i-0 initial commit: a b h p q r | |||||
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBF-change-m-0")' | |||||
M b | |||||
A d | |||||
h (filelog !) | |||||
h (sidedata !) | |||||
a (upgraded known-bad-output !) | |||||
h (upgraded missing-correct-output !) | |||||
a (upgraded-parallel known-bad-output !) | |||||
h (upgraded-parallel missing-correct-output !) | |||||
h (changeset !) | |||||
h (compatibility !) | |||||
A t | |||||
p | |||||
R a | |||||
R h | |||||
R p | |||||
$ hg status --copies --rev 'desc("i-0")' --rev 'desc("mFB-change-m-0")' | |||||
M b | |||||
A d | |||||
h (filelog missing-correct-output !) | |||||
a (filelog known-bad-output !) | |||||
h (sidedata !) | |||||
h (upgraded !) | |||||
h (upgraded-parallel !) | |||||
h (changeset !) | |||||
h (compatibility !) | |||||
A t | |||||
p | |||||
R a | |||||
R h | |||||
R p | |||||
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBF-change-m-0")' | |||||
M d | |||||
h (no-filelog !) | |||||
R h | |||||
$ hg status --copies --rev 'desc("f-2")' --rev 'desc("mBF-change-m-0")' | |||||
M b | |||||
M d | |||||
$ hg status --copies --rev 'desc("f-1")' --rev 'desc("mBF-change-m-0")' | |||||
M b | |||||
M d | |||||
i (no-filelog !) | |||||
R i | |||||
$ hg status --copies --rev 'desc("b-1")' --rev 'desc("mFB-change-m-0")' | |||||
M d | |||||
h (no-filelog !) | |||||
R h | |||||
$ hg status --copies --rev 'desc("f-2")' --rev 'desc("mFB-change-m-0")' | |||||
M b | |||||
M d | |||||
$ hg status --copies --rev 'desc("f-1")' --rev 'desc("mFB-change-m-0")' | |||||
M b | |||||
M d | |||||
i (no-filelog !) | |||||
R i | |||||
#if no-changeset | |||||
$ hg log -Gfr 'desc("mBF-change-m-0")' d | |||||
o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way | |||||
|\ | |||||
o : f-2: rename i -> d | |||||
| : | |||||
o : f-1: rename h -> i | |||||
:/ | |||||
o i-0 initial commit: a b h p q r | |||||
#else | |||||
BROKEN: `hg log --follow <file>` relies on filelog metadata to work | |||||
$ hg log -Gfr 'desc("mBF-change-m-0")' d | |||||
o mBF-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - one way | |||||
: | |||||
o i-2: c -move-> d, s -move-> t | |||||
| | |||||
~ | |||||
#endif | |||||
#if no-changeset | |||||
$ hg log -Gfr 'desc("mFB-change-m-0")' d | |||||
o mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way | |||||
|\ | |||||
o : f-2: rename i -> d | |||||
| : | |||||
o : f-1: rename h -> i | |||||
:/ | |||||
o i-2: c -move-> d, s -move-> t (known-bad-output !) | |||||
| (known-bad-output !) | |||||
o i-1: a -move-> c, p -move-> s (known-bad-output !) | |||||
| (known-bad-output !) | |||||
o i-0 initial commit: a b h p q r | |||||
#else | |||||
BROKEN: `hg log --follow <file>` relies on filelog metadata to work | |||||
$ hg log -Gfr 'desc("mFB-change-m-0")' d | |||||
o mFB-change-m-0 merge with extra change - B side: unrelated change, F side: overwrite d with a copy (from h->i->d) - the other way | |||||
: | |||||
o i-2: c -move-> d, s -move-> t | |||||
| | |||||
~ | |||||
#endif | |||||
Decision from previous merge are properly chained with later merge | Decision from previous merge are properly chained with later merge | ||||
------------------------------------------------------------------ | ------------------------------------------------------------------ | ||||
Subcase: chaining conflicting rename resolution | Subcase: chaining conflicting rename resolution | ||||
``````````````````````````````````````````````` | ``````````````````````````````````````````````` | ||||
The "mAEm" and "mEAm" case create a rename tracking conflict on file 'f'. We | The "mAEm" and "mEAm" case create a rename tracking conflict on file 'f'. We |