comparison tests/test-rename-merge2.t @ 42252:57203e0210f8

copies: calculate mergecopies() based on pathcopies() When copies are stored in changesets, we need a changeset-centric version of mergecopies() just like we have a changeset-centric version of pathcopies(). I think the natural way of thinking about mergecopies() is in terms of pathcopies() from the base to each of the commits. So if we can rewrite mergecopies() based on two such pathcopies() calls, we'll get the changeset-centric version for free. That's what this patch does. A nice bonus is that it ends up being a lot simpler. mergecopies() has accumulated a lot of technical debt over time. One good example is the code for dealing with grafts (the "partial/incomplete/dirty" stuff). Since pathcopies() already deals with backwards renames and ping-pong renames, we get that for free. I've run tests with hard-coded debug logging for "fullcopy" and while I haven't looked at every difference it produces, all the ones I have looked at seemed reasonable to me. I'm a little surprised that no more tests fail when run with '--extra-config-opt experimental.copies.read-from=compatibility' compared to before this patch. This patch also fixes the broken cases in test-annotate.t and test-fastannotate.t. It also enables the part of test-copies.t that was previously disabled exactly because mergecopies() needed to get a changeset-centric version. One drawback of the rewritten code is that we may now make remotefilelog prefetch more files. We used to prefetch files that were unique to either side of the merge compared to the other. We now prefetch files that are unique to either side of the merge compared to the base. This means that if you added the same file to each side, we would not prefetch it before, but we would now. Such cases are probably quite rare, but one likely scenario where they happen is when moving from a commit to its successor (or the other way around). The user will probably already have the files in the cache in such cases, so it's probably not a big deal. Some timings for calculating mergecopies between two revisions (revisions shown on each line, all using the common ancestor as base): In the hg repo: 4.8 4.9: 0.21s -> 0.21s 4.0 4.8: 0.35s -> 0.63s In and old copy of the mozilla-unified repo: FIREFOX_BETA_60_BASE^ FIREFOX_BETA_60_BASE: 0.82s -> 0.82s FIREFOX_NIGHTLY_59_END FIREFOX_BETA_60_BASE: 2.5s -> 2.6s FIREFOX_BETA_59_END FIREFOX_BETA_60_BASE: 3.9s -> 4.1s FIREFOX_AURORA_50_BASE FIREFOX_BETA_60_BASE: 31s -> 33s So it's measurably slower in most cases. The most significant difference is in the hg repo between revisions 4.0 and 4.8. In that case it seems to come from the fact that pathcopies() uses fctx.isintroducedafter() (in _tracefile), while the old mergecopies() used fctx.linkrev() (in _checkcopies()). That results in a single call to filectx._adjustlinkrev(), which is responsible for the entire difference in time (in my repo). So we pay a performance penalty but we get more correct code (see change in test-mv-cp-st-diff.t). Deleting the "== f.filenode()" in _tracefile() recovers the lost performance in the hg repo. There were are few other optimizations in _checkcopies() that I could not measure any impact from. One was from the "seen" set. Another was from a "continue" when the file was not in the destination manifest (corresponding to "am" in _tracefile). Also note that merge copies are not calculated when updating with a clean working copy, which is probably the most common case. I therefore think the much simpler code is worth the slowdown. Differential Revision: https://phab.mercurial-scm.org/D6255
author Martin von Zweigbergk <martinvonz@google.com>
date Thu, 11 Apr 2019 23:22:54 -0700
parents a68036b849b0
children 4764e8436b2a
comparison
equal deleted inserted replaced
42251:c83c08cf02b7 42252:57203e0210f8
431 $ tm "nc a b" "up b " " " "12 merge b no ancestor" 431 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
432 created new head 432 created new head
433 -------------- 433 --------------
434 test L:nc a b R:up b W: - 12 merge b no ancestor 434 test L:nc a b R:up b W: - 12 merge b no ancestor
435 -------------- 435 --------------
436 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
437 src: 'a' -> dst: 'b'
438 checking for directory renames
436 resolving manifests 439 resolving manifests
437 branchmerge: True, force: False, partial: False 440 branchmerge: True, force: False, partial: False
438 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7 441 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
439 preserving b for resolve of b 442 preserving b for resolve of b
440 preserving rev for resolve of rev 443 preserving rev for resolve of rev
467 $ tm "up b " "nm a b" " " "13 merge b no ancestor" 470 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
468 created new head 471 created new head
469 -------------- 472 --------------
470 test L:up b R:nm a b W: - 13 merge b no ancestor 473 test L:up b R:nm a b W: - 13 merge b no ancestor
471 -------------- 474 --------------
475 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
476 src: 'a' -> dst: 'b'
477 checking for directory renames
472 resolving manifests 478 resolving manifests
473 branchmerge: True, force: False, partial: False 479 branchmerge: True, force: False, partial: False
474 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a 480 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
475 preserving b for resolve of b 481 preserving b for resolve of b
476 preserving rev for resolve of rev 482 preserving rev for resolve of rev
504 $ tm "nc a b" "up a b" " " "14 merge b no ancestor" 510 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
505 created new head 511 created new head
506 -------------- 512 --------------
507 test L:nc a b R:up a b W: - 14 merge b no ancestor 513 test L:nc a b R:up a b W: - 14 merge b no ancestor
508 -------------- 514 --------------
515 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
516 src: 'a' -> dst: 'b'
517 checking for directory renames
509 resolving manifests 518 resolving manifests
510 branchmerge: True, force: False, partial: False 519 branchmerge: True, force: False, partial: False
511 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a 520 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
512 preserving b for resolve of b 521 preserving b for resolve of b
513 preserving rev for resolve of rev 522 preserving rev for resolve of rev
541 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a" 550 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
542 created new head 551 created new head
543 -------------- 552 --------------
544 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a 553 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
545 -------------- 554 --------------
555 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
556 src: 'a' -> dst: 'b'
557 checking for directory renames
546 resolving manifests 558 resolving manifests
547 branchmerge: True, force: False, partial: False 559 branchmerge: True, force: False, partial: False
548 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a 560 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
549 preserving b for resolve of b 561 preserving b for resolve of b
550 preserving rev for resolve of rev 562 preserving rev for resolve of rev
578 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor" 590 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
579 created new head 591 created new head
580 -------------- 592 --------------
581 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor 593 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
582 -------------- 594 --------------
595 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
596 src: 'a' -> dst: 'b'
597 checking for directory renames
583 resolving manifests 598 resolving manifests
584 branchmerge: True, force: False, partial: False 599 branchmerge: True, force: False, partial: False
585 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a 600 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
586 preserving b for resolve of b 601 preserving b for resolve of b
587 preserving rev for resolve of rev 602 preserving rev for resolve of rev
615 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor" 630 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
616 created new head 631 created new head
617 -------------- 632 --------------
618 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor 633 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
619 -------------- 634 --------------
635 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
636 src: 'a' -> dst: 'b'
637 checking for directory renames
620 resolving manifests 638 resolving manifests
621 branchmerge: True, force: False, partial: False 639 branchmerge: True, force: False, partial: False
622 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24 640 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
623 preserving b for resolve of b 641 preserving b for resolve of b
624 preserving rev for resolve of rev 642 preserving rev for resolve of rev
651 $ tm "nm a b" "up a b" " " "18 merge b no ancestor" 669 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
652 created new head 670 created new head
653 -------------- 671 --------------
654 test L:nm a b R:up a b W: - 18 merge b no ancestor 672 test L:nm a b R:up a b W: - 18 merge b no ancestor
655 -------------- 673 --------------
674 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
675 src: 'a' -> dst: 'b'
676 checking for directory renames
656 resolving manifests 677 resolving manifests
657 branchmerge: True, force: False, partial: False 678 branchmerge: True, force: False, partial: False
658 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a 679 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
659 preserving b for resolve of b 680 preserving b for resolve of b
660 preserving rev for resolve of rev 681 preserving rev for resolve of rev
693 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a" 714 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
694 created new head 715 created new head
695 -------------- 716 --------------
696 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a 717 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
697 -------------- 718 --------------
719 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
720 src: 'a' -> dst: 'b'
721 checking for directory renames
698 resolving manifests 722 resolving manifests
699 branchmerge: True, force: False, partial: False 723 branchmerge: True, force: False, partial: False
700 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a 724 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
701 preserving a for resolve of a 725 preserving a for resolve of a
702 preserving b for resolve of b 726 preserving b for resolve of b