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.
| No Linters Available |
| No Unit Test Coverage |
| Path | Packages | |||
|---|---|---|---|---|
| M | tests/test-copies-chain-merge.t (241 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| 9d108b32c874 | 87f8b3add56b | Pierre-Yves David | Mar 1 2021, 6:05 PM |
| |/ | |/ | ||||
| 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 !) | |||||
| touched : d, ; (no-upgraded !) | |||||
| '\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 !) | |||||
| ##### 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 !) | |||||
| 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 (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 | ||||