mercurial/copies.py
author Martin von Zweigbergk <martinvonz@google.com>
Sat, 27 Apr 2019 23:30:19 -0700
changeset 42213 618b9ffefa87
parent 42210 390ec72b8ea4
child 42222 57203e0210f8
permissions -rw-r--r--
tests: demonstrate that rename is followed to wrong parent from merge This test case shows another way that copies are handled differently between `hg st` (pathcopies()) and `hg co -m` (mergecopies). The reason is that pathcopies() calls _tracefiles(), which checks that the file nodeid of an ancestor matches the file nodeid in the base commit. mergecopies() should probably be doing the same. Differential Revision: https://phab.mercurial-scm.org/D6323
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# copies.py - copy detection for Mercurial
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2008 Matt Mackall <mpm@selenic.com>
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10262
diff changeset
     6
# GNU General Public License version 2 or any later version.
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
     8
from __future__ import absolute_import
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
     9
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
    10
import collections
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8225
diff changeset
    11
import heapq
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
    12
import os
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
34846
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
    14
from .i18n import _
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
    15
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    16
from . import (
33867
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 33822
diff changeset
    17
    match as matchmod,
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
    18
    node,
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    19
    pathutil,
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    20
    util,
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    21
)
39366
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
    22
from .utils import (
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
    23
    stringutil,
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
    24
)
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    25
41393
dc50121126ae copies: pass contexts into _findlimit()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41392
diff changeset
    26
def _findlimit(repo, ctxa, ctxb):
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    27
    """
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    28
    Find the last revision that needs to be checked to ensure that a full
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    29
    transitive closure for file copies can be properly calculated.
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    30
    Generally, this means finding the earliest revision number that's an
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    31
    ancestor of a or b but not both, except when a or b is a direct descendent
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    32
    of the other, in which case we can return the minimum revnum of a and b.
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
    33
    """
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    34
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    35
    # basic idea:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    36
    # - mark a and b with different sides
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    37
    # - if a parent's children are all on the same side, the parent is
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    38
    #   on that side, otherwise it is on no side
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    39
    # - walk the graph in topological order with the help of a heap;
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    40
    #   - add unseen parents to side map
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    41
    #   - clear side of any parent that has children on different sides
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
    42
    #   - track number of interesting revs that might still be on a side
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
    43
    #   - track the lowest interesting rev seen
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
    44
    #   - quit when interesting revs is zero
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    45
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    46
    cl = repo.changelog
41394
75e753a26806 copies: get working copy parents from wctx, not dirstate, to make in-mem work
Martin von Zweigbergk <martinvonz@google.com>
parents: 41393
diff changeset
    47
    wdirparents = None
41393
dc50121126ae copies: pass contexts into _findlimit()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41392
diff changeset
    48
    a = ctxa.rev()
dc50121126ae copies: pass contexts into _findlimit()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41392
diff changeset
    49
    b = ctxb.rev()
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    50
    if a is None:
41394
75e753a26806 copies: get working copy parents from wctx, not dirstate, to make in-mem work
Martin von Zweigbergk <martinvonz@google.com>
parents: 41393
diff changeset
    51
        wdirparents = (ctxa.p1(), ctxa.p2())
41231
e3e1b0639375 copies: use node.wdirrev instead of inventing another constant for it
Martin von Zweigbergk <martinvonz@google.com>
parents: 40694
diff changeset
    52
        a = node.wdirrev
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    53
    if b is None:
41394
75e753a26806 copies: get working copy parents from wctx, not dirstate, to make in-mem work
Martin von Zweigbergk <martinvonz@google.com>
parents: 41393
diff changeset
    54
        assert not wdirparents
75e753a26806 copies: get working copy parents from wctx, not dirstate, to make in-mem work
Martin von Zweigbergk <martinvonz@google.com>
parents: 41393
diff changeset
    55
        wdirparents = (ctxb.p1(), ctxb.p2())
41231
e3e1b0639375 copies: use node.wdirrev instead of inventing another constant for it
Martin von Zweigbergk <martinvonz@google.com>
parents: 40694
diff changeset
    56
        b = node.wdirrev
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    57
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    58
    side = {a: -1, b: 1}
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    59
    visit = [-a, -b]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    60
    heapq.heapify(visit)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    61
    interesting = len(visit)
41231
e3e1b0639375 copies: use node.wdirrev instead of inventing another constant for it
Martin von Zweigbergk <martinvonz@google.com>
parents: 40694
diff changeset
    62
    limit = node.wdirrev
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    63
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    64
    while interesting:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    65
        r = -heapq.heappop(visit)
41231
e3e1b0639375 copies: use node.wdirrev instead of inventing another constant for it
Martin von Zweigbergk <martinvonz@google.com>
parents: 40694
diff changeset
    66
        if r == node.wdirrev:
41394
75e753a26806 copies: get working copy parents from wctx, not dirstate, to make in-mem work
Martin von Zweigbergk <martinvonz@google.com>
parents: 41393
diff changeset
    67
            parents = [pctx.rev() for pctx in wdirparents]
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    68
        else:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    69
            parents = cl.parentrevs(r)
41392
b80af0707066 copies: consider nullrev a common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 41232
diff changeset
    70
        if parents[1] == node.nullrev:
b80af0707066 copies: consider nullrev a common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 41232
diff changeset
    71
            parents = parents[:1]
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    72
        for p in parents:
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    73
            if p not in side:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    74
                # first time we see p; add it to visit
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    75
                side[p] = side[r]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    76
                if side[p]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    77
                    interesting += 1
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    78
                heapq.heappush(visit, -p)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    79
            elif side[p] and side[p] != side[r]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    80
                # p was interesting but now we know better
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    81
                side[p] = 0
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    82
                interesting -= 1
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    83
        if side[r]:
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
    84
            limit = r # lowest rev visited
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    85
            interesting -= 1
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
    86
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    87
    # Consider the following flow (see test-commit-amend.t under issue4405):
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    88
    # 1/ File 'a0' committed
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    89
    # 2/ File renamed from 'a0' to 'a1' in a new commit (call it 'a1')
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    90
    # 3/ Move back to first commit
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    91
    # 4/ Create a new commit via revert to contents of 'a1' (call it 'a1-amend')
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    92
    # 5/ Rename file from 'a1' to 'a2' and commit --amend 'a1-msg'
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    93
    #
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    94
    # During the amend in step five, we will be in this state:
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    95
    #
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    96
    # @  3 temporary amend commit for a1-amend
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    97
    # |
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    98
    # o  2 a1-amend
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
    99
    # |
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
   100
    # | o  1 a1
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
   101
    # |/
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
   102
    # o  0 a0
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
   103
    #
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23071
diff changeset
   104
    # When _findlimit is called, a and b are revs 3 and 0, so limit will be 2,
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
   105
    # yet the filelog has the copy information in rev 1 and we will not look
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
   106
    # back far enough unless we also look at the a and b as candidates.
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
   107
    # This only occurs when a is a descendent of b or visa-versa.
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
   108
    return min(limit, a, b)
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
   109
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   110
def _chain(src, dst, a, b):
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
   111
    """chain two sets of copies a->b"""
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   112
    t = a.copy()
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   113
    for k, v in b.iteritems():
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   114
        if v in t:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   115
            # found a chain
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   116
            if t[v] != k:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   117
                # file wasn't renamed back to itself
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   118
                t[k] = t[v]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   119
            if v not in dst:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   120
                # chain was a rename, not a copy
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   121
                del t[v]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   122
        if v in src:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   123
            # file is a copy of an existing file
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   124
            t[k] = v
15976
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
   125
36117
c02771617a70 py3: avoid changing dictionary during iteration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35423
diff changeset
   126
    for k, v in list(t.items()):
41754
d5edb5d3a337 copies: filter out copies when target is not in destination manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 41753
diff changeset
   127
        # remove criss-crossed copies
15976
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
   128
        if k in src and v in dst:
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
   129
            del t[k]
41754
d5edb5d3a337 copies: filter out copies when target is not in destination manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 41753
diff changeset
   130
        # remove copies to files that were then removed
d5edb5d3a337 copies: filter out copies when target is not in destination manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 41753
diff changeset
   131
        elif k not in dst:
d5edb5d3a337 copies: filter out copies when target is not in destination manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 41753
diff changeset
   132
            del t[k]
15976
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
   133
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   134
    return t
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   135
41232
f3f5bfbf7e04 copies: use node.nullrev instead of literal -1
Martin von Zweigbergk <martinvonz@google.com>
parents: 41231
diff changeset
   136
def _tracefile(fctx, am, limit=node.nullrev):
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
   137
    """return file context that is the ancestor of fctx present in ancestor
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
   138
    manifest am, stopping after the first ancestor lower than limit"""
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   139
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   140
    for f in fctx.ancestors():
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   141
        if am.get(f.path(), None) == f.filenode():
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   142
            return f
40694
8a0136f69027 context: introduce an `isintroducedafter` method and use it in copies
Boris Feld <boris.feld@octobus.net>
parents: 40450
diff changeset
   143
        if limit >= 0 and not f.isintroducedafter(limit):
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   144
            return None
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   145
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
   146
def _dirstatecopies(repo, match=None):
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
   147
    ds = repo.dirstate
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   148
    c = ds.copies().copy()
34348
1a5abc45e2fa py3: explicitly convert dict.keys() and dict.items() into a list
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34311
diff changeset
   149
    for k in list(c):
35420
7ddc1e96d9b0 copies: always respect matcher arg to _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 34846
diff changeset
   150
        if ds[k] not in 'anm' or (match and not match(k)):
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   151
            del c[k]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   152
    return c
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   153
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   154
def _computeforwardmissing(a, b, match=None):
24011
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
   155
    """Computes which files are in b but not a.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
   156
    This is its own function so extensions can easily wrap this call to see what
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
   157
    files _forwardcopies is about to process.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
   158
    """
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   159
    ma = a.manifest()
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   160
    mb = b.manifest()
31256
5a909a8098a1 copies: remove use of manifest.matches
Durham Goode <durham@fb.com>
parents: 30581
diff changeset
   161
    return mb.filesnotin(ma, match=match)
24011
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
   162
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
   163
def usechangesetcentricalgo(repo):
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
   164
    """Checks if we should use changeset-centric copy algorithms"""
42142
5382d8f8530b changelog: parse copy metadata if available in extras
Martin von Zweigbergk <martinvonz@google.com>
parents: 42118
diff changeset
   165
    return (repo.ui.config('experimental', 'copies.read-from') in
5382d8f8530b changelog: parse copy metadata if available in extras
Martin von Zweigbergk <martinvonz@google.com>
parents: 42118
diff changeset
   166
            ('changeset-only', 'compatibility'))
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
   167
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   168
def _committedforwardcopies(a, b, match):
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   169
    """Like _forwardcopies(), but b.rev() cannot be None (working copy)"""
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
   170
    # files might have to be traced back to the fctx parent of the last
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
   171
    # one-side-only changeset, but not further back than that
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   172
    repo = a._repo
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   173
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
   174
    if usechangesetcentricalgo(repo):
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   175
        return _changesetforwardcopies(a, b, match)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   176
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   177
    debug = repo.ui.debugflag and repo.ui.configbool('devel', 'debug.copies')
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   178
    dbg = repo.ui.debug
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   179
    if debug:
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   180
        dbg('debug.copies:    looking into rename from %s to %s\n'
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   181
            % (a, b))
41393
dc50121126ae copies: pass contexts into _findlimit()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41392
diff changeset
   182
    limit = _findlimit(repo, a, b)
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   183
    if debug:
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   184
        dbg('debug.copies:      search limit: %d\n' % limit)
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
   185
    am = a.manifest()
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
   186
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   187
    # find where new files came from
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   188
    # we currently don't try to find where old files went, too expensive
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   189
    # this means we can miss a case like 'hg rm b; hg cp a b'
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   190
    cm = {}
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   191
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   192
    # Computing the forward missing is quite expensive on large manifests, since
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   193
    # it compares the entire manifests. We can optimize it in the common use
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   194
    # case of computing what copies are in a commit versus its parent (like
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   195
    # during a rebase or histedit). Note, we exclude merge commits from this
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   196
    # optimization, since the ctx.files() for a merge commit is not correct for
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   197
    # this comparison.
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   198
    forwardmissingmatch = match
33867
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 33822
diff changeset
   199
    if b.p1() == a and b.p2().node() == node.nullid:
41936
a791623458ef copies: remove dependency on scmutil by directly using match.exact()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41932
diff changeset
   200
        filesmatcher = matchmod.exact(b.files())
33867
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 33822
diff changeset
   201
        forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   202
    missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   203
23980
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   204
    ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   205
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   206
    if debug:
42210
390ec72b8ea4 copies: process files in deterministic order for stable tests
Martin von Zweigbergk <martinvonz@google.com>
parents: 42169
diff changeset
   207
        dbg('debug.copies:      missing files to search: %d\n' % len(missing))
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   208
42210
390ec72b8ea4 copies: process files in deterministic order for stable tests
Martin von Zweigbergk <martinvonz@google.com>
parents: 42169
diff changeset
   209
    for f in sorted(missing):
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   210
        if debug:
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   211
            dbg('debug.copies:        tracing file: %s\n' % f)
23980
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   212
        fctx = b[f]
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   213
        fctx._ancestrycontext = ancestrycontext
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   214
40058
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
   215
        if debug:
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
   216
            start = util.timer()
23980
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   217
        ofctx = _tracefile(fctx, am, limit)
18878
3cfaace0441e copies._forwardcopies: use set operations to find missing files
Siddharth Agarwal <sid0@fb.com>
parents: 18362
diff changeset
   218
        if ofctx:
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   219
            if debug:
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   220
                dbg('debug.copies:          rename of: %s\n' % ofctx._path)
18878
3cfaace0441e copies._forwardcopies: use set operations to find missing files
Siddharth Agarwal <sid0@fb.com>
parents: 18362
diff changeset
   221
            cm[f] = ofctx.path()
40058
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
   222
        if debug:
40076
2e9378f62232 py3: use '%f' for floats instead of '%s'
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40058
diff changeset
   223
            dbg('debug.copies:          time: %f seconds\n'
40058
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
   224
                % (util.timer() - start))
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   225
    return cm
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   226
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   227
def _changesetforwardcopies(a, b, match):
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   228
    if a.rev() == node.nullrev:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   229
        return {}
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   230
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   231
    repo = a.repo()
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   232
    children = {}
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   233
    cl = repo.changelog
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   234
    missingrevs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   235
    for r in missingrevs:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   236
        for p in cl.parentrevs(r):
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   237
            if p == node.nullrev:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   238
                continue
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   239
            if p not in children:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   240
                children[p] = [r]
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   241
            else:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   242
                children[p].append(r)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   243
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   244
    roots = set(children) - set(missingrevs)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   245
    # 'work' contains 3-tuples of a (revision number, parent number, copies).
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   246
    # The parent number is only used for knowing which parent the copies dict
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   247
    # came from.
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   248
    work = [(r, 1, {}) for r in roots]
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   249
    heapq.heapify(work)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   250
    while work:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   251
        r, i1, copies1 = heapq.heappop(work)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   252
        if work and work[0][0] == r:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   253
            # We are tracing copies from both parents
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   254
            r, i2, copies2 = heapq.heappop(work)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   255
            copies = {}
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   256
            ctx = repo[r]
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   257
            p1man, p2man = ctx.p1().manifest(), ctx.p2().manifest()
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   258
            allcopies = set(copies1) | set(copies2)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   259
            # TODO: perhaps this filtering should be done as long as ctx
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   260
            # is merge, whether or not we're tracing from both parent.
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   261
            for dst in allcopies:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   262
                if not match(dst):
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   263
                    continue
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   264
                if dst not in copies2:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   265
                    # Copied on p1 side: mark as copy from p1 side if it didn't
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   266
                    # already exist on p2 side
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   267
                    if dst not in p2man:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   268
                        copies[dst] = copies1[dst]
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   269
                elif dst not in copies1:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   270
                    # Copied on p2 side: mark as copy from p2 side if it didn't
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   271
                    # already exist on p1 side
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   272
                    if dst not in p1man:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   273
                        copies[dst] = copies2[dst]
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   274
                else:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   275
                    # Copied on both sides: mark as copy from p1 side
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   276
                    copies[dst] = copies1[dst]
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   277
        else:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   278
            copies = copies1
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   279
        if r == b.rev():
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   280
            return copies
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   281
        for c in children[r]:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   282
            childctx = repo[c]
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   283
            if r == childctx.p1().rev():
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   284
                parent = 1
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   285
                childcopies = childctx.p1copies()
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   286
            else:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   287
                assert r == childctx.p2().rev()
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   288
                parent = 2
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   289
                childcopies = childctx.p2copies()
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   290
            if not match.always():
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   291
                childcopies = {dst: src for dst, src in childcopies.items()
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   292
                               if match(dst)}
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   293
            childcopies = _chain(a, childctx, copies, childcopies)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   294
            heapq.heappush(work, (c, parent, childcopies))
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   295
    assert False
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   296
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   297
def _forwardcopies(a, b, match=None):
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   298
    """find {dst@b: src@a} copy mapping where a is an ancestor of b"""
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   299
40448
873f3682c8af narrow: make copies.pathcopies() filter with narrowspec again
Martin von Zweigbergk <martinvonz@google.com>
parents: 40076
diff changeset
   300
    match = a.repo().narrowmatch(match)
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   301
    # check for working copy
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   302
    if b.rev() is None:
35423
e54f02ec6a05 copies: group wdir-handling in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 35422
diff changeset
   303
        if a == b.p1():
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   304
            # short-circuit to avoid issues with merge states
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
   305
            return _dirstatecopies(b._repo, match)
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   306
35423
e54f02ec6a05 copies: group wdir-handling in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 35422
diff changeset
   307
        cm = _committedforwardcopies(a, b.p1(), match)
e54f02ec6a05 copies: group wdir-handling in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 35422
diff changeset
   308
        # combine copies from dirstate if necessary
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
   309
        return _chain(a, b, cm, _dirstatecopies(b._repo, match))
35423
e54f02ec6a05 copies: group wdir-handling in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 35422
diff changeset
   310
    return _committedforwardcopies(a, b, match)
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   311
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   312
def _backwardrenames(a, b, match):
34077
26531db4647a copytrace: replace experimental.disablecopytrace config with copytrace (BC)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33880
diff changeset
   313
    if a._repo.ui.config('experimental', 'copytrace') == 'off':
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   314
        return {}
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   315
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   316
    # Even though we're not taking copies into account, 1:n rename situations
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   317
    # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   318
    # arbitrarily pick one of the renames.
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   319
    # We don't want to pass in "match" here, since that would filter
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   320
    # the destination by it. Since we're reversing the copies, we want
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   321
    # to filter the source instead.
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   322
    f = _forwardcopies(b, a)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   323
    r = {}
18355
2330d97e7707 copies: make the loss in _backwardcopies more stable
Mads Kiilerich <mads@kiilerich.com>
parents: 18136
diff changeset
   324
    for k, v in sorted(f.iteritems()):
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   325
        if match and not match(v):
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   326
            continue
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   327
        # remove copies
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   328
        if v in a:
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   329
            continue
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   330
        r[v] = k
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   331
    return r
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   332
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   333
def pathcopies(x, y, match=None):
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
   334
    """find {dst@y: src@x} copy mapping for directed compare"""
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   335
    repo = x._repo
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   336
    debug = repo.ui.debugflag and repo.ui.configbool('devel', 'debug.copies')
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   337
    if debug:
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   338
        repo.ui.debug('debug.copies: searching copies from %s to %s\n'
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   339
                      % (x, y))
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   340
    if x == y or not x or not y:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   341
        return {}
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   342
    a = y.ancestor(x)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   343
    if a == x:
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   344
        if debug:
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   345
            repo.ui.debug('debug.copies: search mode: forward\n')
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   346
        return _forwardcopies(x, y, match=match)
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   347
    if a == y:
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   348
        if debug:
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   349
            repo.ui.debug('debug.copies: search mode: backward\n')
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   350
        return _backwardrenames(x, y, match=match)
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   351
    if debug:
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   352
        repo.ui.debug('debug.copies: search mode: combined\n')
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   353
    return _chain(x, y, _backwardrenames(x, a, match=match),
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   354
                  _forwardcopies(a, y, match=match))
15774
0bd17a4bed88 copies: split the copies api for "normal" and merge cases (API)
Matt Mackall <mpm@selenic.com>
parents: 14494
diff changeset
   355
42168
341bddf88ac5 copies: delete debug message about changes since common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 42167
diff changeset
   356
def _computenonoverlap(repo, c1, c2, addedinm1, addedinm2, debug=True):
24625
2cebf17c0fcc copies: pass changectx instead of manifest to _computenonoverlap
Durham Goode <durham@fb.com>
parents: 24415
diff changeset
   357
    """Computes, based on addedinm1 and addedinm2, the files exclusive to c1
2cebf17c0fcc copies: pass changectx instead of manifest to _computenonoverlap
Durham Goode <durham@fb.com>
parents: 24415
diff changeset
   358
    and c2. This is its own function so extensions can easily wrap this call
24187
30219bd46ed7 copies: only calculate 'addedinm[12]' sets once
Martin von Zweigbergk <martinvonz@google.com>
parents: 24186
diff changeset
   359
    to see what files mergecopies is about to process.
24273
ce847603040b copies: added manifests to computenonoverlap
Durham Goode <durham@fb.com>
parents: 24187
diff changeset
   360
24625
2cebf17c0fcc copies: pass changectx instead of manifest to _computenonoverlap
Durham Goode <durham@fb.com>
parents: 24415
diff changeset
   361
    Even though c1 and c2 are not used in this function, they are useful in
24273
ce847603040b copies: added manifests to computenonoverlap
Durham Goode <durham@fb.com>
parents: 24187
diff changeset
   362
    other extensions for being able to read the file nodes of the changed files.
24010
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
   363
    """
24185
3a3806fe3ddf copies: replace _nonoverlap() by calls to manifestdict.filesnotin()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24184
diff changeset
   364
    u1 = sorted(addedinm1 - addedinm2)
3a3806fe3ddf copies: replace _nonoverlap() by calls to manifestdict.filesnotin()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24184
diff changeset
   365
    u2 = sorted(addedinm2 - addedinm1)
24010
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
   366
42168
341bddf88ac5 copies: delete debug message about changes since common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 42167
diff changeset
   367
    if debug:
341bddf88ac5 copies: delete debug message about changes since common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 42167
diff changeset
   368
        header = "  unmatched files in %s"
341bddf88ac5 copies: delete debug message about changes since common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 42167
diff changeset
   369
        if u1:
341bddf88ac5 copies: delete debug message about changes since common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 42167
diff changeset
   370
            repo.ui.debug("%s:\n   %s\n" % (header % 'local', "\n   ".join(u1)))
341bddf88ac5 copies: delete debug message about changes since common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 42167
diff changeset
   371
        if u2:
341bddf88ac5 copies: delete debug message about changes since common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 42167
diff changeset
   372
            repo.ui.debug("%s:\n   %s\n" % (header % 'other', "\n   ".join(u2)))
38046
ee7b6fa52d9d narrow: filter copies in core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37448
diff changeset
   373
24010
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
   374
    return u1, u2
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
   375
26656
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   376
def _makegetfctx(ctx):
30048
91a3c58ecf93 copies: mark checkcopies as internal with the _ prefix
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30047
diff changeset
   377
    """return a 'getfctx' function suitable for _checkcopies usage
26656
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   378
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   379
    We have to re-setup the function building 'filectx' for each
30048
91a3c58ecf93 copies: mark checkcopies as internal with the _ prefix
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30047
diff changeset
   380
    '_checkcopies' to ensure the linkrev adjustment is properly setup for
26656
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   381
    each. Linkrev adjustment is important to avoid bug in rename
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   382
    detection. Moreover, having a proper '_ancestrycontext' setup ensures
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   383
    the performance impact of this adjustment is kept limited. Without it,
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   384
    each file could do a full dag traversal making the time complexity of
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   385
    the operation explode (see issue4537).
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   386
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   387
    This function exists here mostly to limit the impact on stable. Feel
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   388
    free to refactor on default.
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   389
    """
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   390
    rev = ctx.rev()
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   391
    repo = ctx._repo
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   392
    ac = getattr(ctx, '_ancestrycontext', None)
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   393
    if ac is None:
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   394
        revs = [rev]
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   395
        if rev is None:
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   396
            revs = [p.rev() for p in ctx.parents()]
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   397
        ac = repo.changelog.ancestors(revs, inclusive=True)
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   398
        ctx._ancestrycontext = ac
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   399
    def makectx(f, n):
37448
d7114f883505 node: rename wdirnodes to clarify they are for manifest/filelogs
Yuya Nishihara <yuya@tcha.org>
parents: 37392
diff changeset
   400
        if n in node.wdirfilenodeids:  # in a working context?
26656
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   401
            if ctx.rev() is None:
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   402
                return ctx.filectx(f)
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   403
            return repo[None][f]
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   404
        fctx = repo.filectx(f, fileid=n)
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   405
        # setup only needed for filectx not create from a changectx
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   406
        fctx._ancestrycontext = ac
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   407
        fctx._descendantrev = rev
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   408
        return fctx
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   409
    return util.lrucachefunc(makectx)
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 26655
diff changeset
   410
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   411
def _combinecopies(copyfrom, copyto, finalcopy, diverge, incompletediverge):
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   412
    """combine partial copy paths"""
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   413
    remainder = {}
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   414
    for f in copyfrom:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   415
        if f in copyto:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   416
            finalcopy[copyto[f]] = copyfrom[f]
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   417
            del copyto[f]
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   418
    for f in incompletediverge:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   419
        assert f not in diverge
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   420
        ic = incompletediverge[f]
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   421
        if ic[0] in copyto:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   422
            diverge[f] = [copyto[ic[0]], ic[1]]
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   423
        else:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   424
            remainder[f] = ic
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   425
    return remainder
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   426
30186
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30185
diff changeset
   427
def mergecopies(repo, c1, c2, base):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   428
    """
42118
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
   429
    Finds moves and copies between context c1 and c2 that are relevant for
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   430
    merging. 'base' will be used as the merge base.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   431
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   432
    Copytracing is used in commands like rebase, merge, unshelve, etc to merge
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   433
    files that were moved/ copied in one merge parent and modified in another.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   434
    For example:
33822
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   435
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   436
    o          ---> 4 another commit
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   437
    |
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   438
    |   o      ---> 3 commit that modifies a.txt
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   439
    |  /
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   440
    o /        ---> 2 commit that moves a.txt to b.txt
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   441
    |/
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   442
    o          ---> 1 merge base
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   443
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   444
    If we try to rebase revision 3 on revision 4, since there is no a.txt in
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   445
    revision 4, and if user have copytrace disabled, we prints the following
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   446
    message:
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   447
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   448
    ```other changed <file> which local deleted```
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   449
30581
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
   450
    Returns five dicts: "copy", "movewithdir", "diverge", "renamedelete" and
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
   451
    "dirmove".
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
   452
16177
b8c1a8a57540 copies: fix mergecopies doc mapping direction
Matt Mackall <mpm@selenic.com>
parents: 16169
diff changeset
   453
    "copy" is a mapping from destination name -> source name,
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
   454
    where source is in c1 and destination is in c2 or vice-versa.
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
   455
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
   456
    "movewithdir" is a mapping from source name -> destination name,
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
   457
    where the file at source present in one context but not the other
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
   458
    needs to be moved to destination by the merge process, because the
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
   459
    other context moved the directory it is in.
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
   460
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
   461
    "diverge" is a mapping of source name -> list of destination names
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
   462
    for divergent renames.
16794
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
   463
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
   464
    "renamedelete" is a mapping of source name -> list of destination
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
   465
    names for files deleted in c1 that were renamed in c2 or vice-versa.
30581
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
   466
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
   467
    "dirmove" is a mapping of detected source dir -> destination dir renames.
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
   468
    This is needed for handling changes to new files previously grafted into
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
   469
    renamed directories.
42118
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
   470
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
   471
    This function calls different copytracing algorithms based on config.
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   472
    """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   473
    # avoid silly behavior for update from empty dir
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
   474
    if not c1 or not c2 or c1 == c2:
30581
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
   475
        return {}, {}, {}, {}, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   476
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
   477
    narrowmatch = c1.repo().narrowmatch()
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
   478
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
   479
    # avoid silly behavior for parent -> working dir
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 12683
diff changeset
   480
    if c2.node() is None and c1.node() == repo.dirstate.p1():
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
   481
        return _dirstatecopies(repo, narrowmatch), {}, {}, {}, {}
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
   482
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   483
    copytracing = repo.ui.config('experimental', 'copytrace')
39366
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
   484
    boolctrace = stringutil.parsebool(copytracing)
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   485
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   486
    # Copy trace disabling is explicitly below the node == p1 logic above
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   487
    # because the logic above is required for a simple copy to be kept across a
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   488
    # rebase.
39366
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
   489
    if copytracing == 'heuristics':
34366
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
   490
        # Do full copytracing if only non-public revisions are involved as
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
   491
        # that will be fast enough and will also cover the copies which could
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
   492
        # be missed by heuristics
34311
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   493
        if _isfullcopytraceable(repo, c1, base):
34288
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34179
diff changeset
   494
            return _fullcopytracing(repo, c1, c2, base)
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   495
        return _heuristicscopytracing(repo, c1, c2, base)
39366
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
   496
    elif boolctrace is False:
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
   497
        # stringutil.parsebool() returns None when it is unable to parse the
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
   498
        # value, so we should rely on making sure copytracing is on such cases
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
   499
        return {}, {}, {}, {}, {}
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   500
    else:
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   501
        return _fullcopytracing(repo, c1, c2, base)
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   502
34311
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   503
def _isfullcopytraceable(repo, c1, base):
34366
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
   504
    """ Checks that if base, source and destination are all no-public branches,
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
   505
    if yes let's use the full copytrace algorithm for increased capabilities
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
   506
    since it will be fast enough.
34516
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34366
diff changeset
   507
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34366
diff changeset
   508
    `experimental.copytrace.sourcecommitlimit` can be used to set a limit for
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34366
diff changeset
   509
    number of changesets from c1 to base such that if number of changesets are
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34366
diff changeset
   510
    more than the limit, full copytracing algorithm won't be used.
34288
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34179
diff changeset
   511
    """
34311
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   512
    if c1.rev() is None:
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   513
        c1 = c1.p1()
34366
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
   514
    if c1.mutable() and base.mutable():
34311
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   515
        sourcecommitlimit = repo.ui.configint('experimental',
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   516
                                              'copytrace.sourcecommitlimit')
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   517
        commits = len(repo.revs('%d::%d', base.rev(), c1.rev()))
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   518
        return commits < sourcecommitlimit
34288
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34179
diff changeset
   519
    return False
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34179
diff changeset
   520
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   521
def _fullcopytracing(repo, c1, c2, base):
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   522
    """ The full copytracing algorithm which finds all the new files that were
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   523
    added from merge base up to the top commit and for each file it checks if
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   524
    this file was copied from another file.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   525
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   526
    This is pretty slow when a lot of changesets are involved but will track all
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   527
    the copies.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   528
    """
30193
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   529
    # In certain scenarios (e.g. graft, update or rebase), base can be
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   530
    # overridden We still need to know a real common ancestor in this case We
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   531
    # can't just compute _c1.ancestor(_c2) and compare it to ca, because there
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   532
    # can be multiple common ancestors, e.g. in case of bidmerge.  Because our
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   533
    # caller may not know if the revision passed in lieu of the CA is a genuine
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   534
    # common ancestor or not without explicitly checking it, it's better to
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   535
    # determine that here.
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   536
    #
38670
fbec9c0b32d3 context: rename descendant() to isancestorof()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38669
diff changeset
   537
    # base.isancestorof(wc) is False, work around that
30193
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   538
    _c1 = c1.p1() if c1.rev() is None else c1
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   539
    _c2 = c2.p1() if c2.rev() is None else c2
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   540
    # an endpoint is "dirty" if it isn't a descendant of the merge base
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   541
    # if we have a dirty endpoint, we need to trigger graft logic, and also
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   542
    # keep track of which endpoint is dirty
38670
fbec9c0b32d3 context: rename descendant() to isancestorof()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38669
diff changeset
   543
    dirtyc1 = not base.isancestorof(_c1)
fbec9c0b32d3 context: rename descendant() to isancestorof()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38669
diff changeset
   544
    dirtyc2 = not base.isancestorof(_c2)
30193
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30188
diff changeset
   545
    graft = dirtyc1 or dirtyc2
30194
8c69c52ced98 copies: compute a suitable TCA if base turns out to be unsuitable
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30193
diff changeset
   546
    tca = base
8c69c52ced98 copies: compute a suitable TCA if base turns out to be unsuitable
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30193
diff changeset
   547
    if graft:
8c69c52ced98 copies: compute a suitable TCA if base turns out to be unsuitable
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30193
diff changeset
   548
        tca = _c1.ancestor(_c2)
8c69c52ced98 copies: compute a suitable TCA if base turns out to be unsuitable
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30193
diff changeset
   549
41393
dc50121126ae copies: pass contexts into _findlimit()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41392
diff changeset
   550
    limit = _findlimit(repo, c1, c2)
26319
4b9bb1616195 copies: move debug statement to appropriate place
Matt Mackall <mpm@selenic.com>
parents: 26317
diff changeset
   551
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   552
    m1 = c1.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   553
    m2 = c2.manifest()
30186
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30185
diff changeset
   554
    mb = base.manifest()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   555
30185
e2bfe2d52d7a copies: move variable document from checkcopies to mergecopies
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30184
diff changeset
   556
    # gather data from _checkcopies:
e2bfe2d52d7a copies: move variable document from checkcopies to mergecopies
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30184
diff changeset
   557
    # - diverge = record all diverges in this dict
e2bfe2d52d7a copies: move variable document from checkcopies to mergecopies
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30184
diff changeset
   558
    # - copy = record all non-divergent copies in this dict
e2bfe2d52d7a copies: move variable document from checkcopies to mergecopies
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30184
diff changeset
   559
    # - fullcopy = record all copies in this dict
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   560
    # - incomplete = record non-divergent partial copies here
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   561
    # - incompletediverge = record divergent partial copies here
30184
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30183
diff changeset
   562
    diverge = {} # divergence data is shared
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   563
    incompletediverge  = {}
30184
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30183
diff changeset
   564
    data1 = {'copy': {},
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30183
diff changeset
   565
             'fullcopy': {},
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   566
             'incomplete': {},
30184
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30183
diff changeset
   567
             'diverge': diverge,
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   568
             'incompletediverge': incompletediverge,
30184
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30183
diff changeset
   569
            }
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30183
diff changeset
   570
    data2 = {'copy': {},
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30183
diff changeset
   571
             'fullcopy': {},
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   572
             'incomplete': {},
30184
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30183
diff changeset
   573
             'diverge': diverge,
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   574
             'incompletediverge': incompletediverge,
30184
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30183
diff changeset
   575
            }
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   576
26659
df66736a128e copies: group bothnew with other sets
Matt Mackall <mpm@selenic.com>
parents: 26658
diff changeset
   577
    # find interesting file sets from manifests
39966
707c3804e607 narrow: move copies overrides to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 39945
diff changeset
   578
    addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
707c3804e607 narrow: move copies overrides to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 39945
diff changeset
   579
    addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
26659
df66736a128e copies: group bothnew with other sets
Matt Mackall <mpm@selenic.com>
parents: 26658
diff changeset
   580
    bothnew = sorted(addedinm1 & addedinm2)
30197
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30196
diff changeset
   581
    if tca == base:
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30196
diff changeset
   582
        # unmatched file from base
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30196
diff changeset
   583
        u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30196
diff changeset
   584
        u1u, u2u = u1r, u2r
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30196
diff changeset
   585
    else:
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30196
diff changeset
   586
        # unmatched file from base (DAG rotation in the graft case)
42168
341bddf88ac5 copies: delete debug message about changes since common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 42167
diff changeset
   587
        u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
30197
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30196
diff changeset
   588
        # unmatched file from topological common ancestors (no DAG rotation)
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30196
diff changeset
   589
        # need to recompute this for directory move handling when grafting
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30196
diff changeset
   590
        mta = tca.manifest()
40450
07a66c1387d1 narrow: fix copies._fullcopytracing() narrowspec filtering in graft case
Martin von Zweigbergk <martinvonz@google.com>
parents: 40448
diff changeset
   591
        u1u, u2u = _computenonoverlap(repo, c1, c2,
07a66c1387d1 narrow: fix copies._fullcopytracing() narrowspec filtering in graft case
Martin von Zweigbergk <martinvonz@google.com>
parents: 40448
diff changeset
   592
                                      m1.filesnotin(mta, repo.narrowmatch()),
07a66c1387d1 narrow: fix copies._fullcopytracing() narrowspec filtering in graft case
Martin von Zweigbergk <martinvonz@google.com>
parents: 40448
diff changeset
   593
                                      m2.filesnotin(mta, repo.narrowmatch()),
42168
341bddf88ac5 copies: delete debug message about changes since common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 42167
diff changeset
   594
                                      debug=False)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   595
30047
d13a7c8bf0a5 copies: split u1/u2 to u1u/u2u and u1r/u2r
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30046
diff changeset
   596
    for f in u1u:
32563
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 32562
diff changeset
   597
        _checkcopies(c1, c2, f, base, tca, dirtyc1, limit, data1)
20989
e8533ec2d222 copies: remove _checkcopies wrapper - it does no good
Mads Kiilerich <madski@unity3d.com>
parents: 20641
diff changeset
   598
30047
d13a7c8bf0a5 copies: split u1/u2 to u1u/u2u and u1r/u2r
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30046
diff changeset
   599
    for f in u2u:
32563
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 32562
diff changeset
   600
        _checkcopies(c2, c1, f, base, tca, dirtyc2, limit, data2)
26316
d5618e210191 copies: begin separating mergecopies sides
Matt Mackall <mpm@selenic.com>
parents: 26315
diff changeset
   601
32640
aeac3cbcbbc1 py3: use dict.update() instead of constructing lists and adding them
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32565
diff changeset
   602
    copy = dict(data1['copy'])
aeac3cbcbbc1 py3: use dict.update() instead of constructing lists and adding them
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32565
diff changeset
   603
    copy.update(data2['copy'])
aeac3cbcbbc1 py3: use dict.update() instead of constructing lists and adding them
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32565
diff changeset
   604
    fullcopy = dict(data1['fullcopy'])
aeac3cbcbbc1 py3: use dict.update() instead of constructing lists and adding them
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32565
diff changeset
   605
    fullcopy.update(data2['fullcopy'])
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   606
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   607
    if dirtyc1:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   608
        _combinecopies(data2['incomplete'], data1['incomplete'], copy, diverge,
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   609
                       incompletediverge)
41932
7694b685bb10 copies: handle a case when both merging csets are not descendant of merge base
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 41756
diff changeset
   610
    if dirtyc2:
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   611
        _combinecopies(data1['incomplete'], data2['incomplete'], copy, diverge,
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   612
                       incompletediverge)
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   613
16794
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
   614
    renamedelete = {}
26658
aabfa0fb7e3e copies: rename renamedelete to renamedeleteset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26657
diff changeset
   615
    renamedeleteset = set()
26317
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26316
diff changeset
   616
    divergeset = set()
34348
1a5abc45e2fa py3: explicitly convert dict.keys() and dict.items() into a list
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34311
diff changeset
   617
    for of, fl in list(diverge.items()):
16792
ad394c897b16 merge: do not warn about copy and rename in the same transaction (issue2113)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16178
diff changeset
   618
        if len(fl) == 1 or of in c1 or of in c2:
12683
ada47c38f4e5 copies: don't detect copies as "divergent renames"
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10874
diff changeset
   619
            del diverge[of] # not actually divergent, or not a rename
16794
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
   620
            if of not in c1 and of not in c2:
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
   621
                # renamed on one side, deleted on the other side, but filter
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
   622
                # out files that have been renamed and then deleted
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
   623
                renamedelete[of] = [f for f in fl if f in c1 or f in c2]
26658
aabfa0fb7e3e copies: rename renamedelete to renamedeleteset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26657
diff changeset
   624
                renamedeleteset.update(fl) # reverse map for below
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   625
        else:
26317
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26316
diff changeset
   626
            divergeset.update(fl) # reverse map for below
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   627
30184
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30183
diff changeset
   628
    bothdiverge = {}
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   629
    bothincompletediverge = {}
30208
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30204
diff changeset
   630
    remainder = {}
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   631
    both1 = {'copy': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   632
             'fullcopy': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   633
             'incomplete': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   634
             'diverge': bothdiverge,
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   635
             'incompletediverge': bothincompletediverge
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   636
            }
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   637
    both2 = {'copy': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   638
             'fullcopy': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   639
             'incomplete': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   640
             'diverge': bothdiverge,
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   641
             'incompletediverge': bothincompletediverge
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   642
            }
20641
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
   643
    for f in bothnew:
32563
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 32562
diff changeset
   644
        _checkcopies(c1, c2, f, base, tca, dirtyc1, limit, both1)
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 32562
diff changeset
   645
        _checkcopies(c2, c1, f, base, tca, dirtyc2, limit, both2)
41932
7694b685bb10 copies: handle a case when both merging csets are not descendant of merge base
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 41756
diff changeset
   646
    if dirtyc1 and dirtyc2:
7694b685bb10 copies: handle a case when both merging csets are not descendant of merge base
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 41756
diff changeset
   647
        remainder = _combinecopies(both2['incomplete'], both1['incomplete'],
7694b685bb10 copies: handle a case when both merging csets are not descendant of merge base
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 41756
diff changeset
   648
                                   copy, bothdiverge, bothincompletediverge)
7694b685bb10 copies: handle a case when both merging csets are not descendant of merge base
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 41756
diff changeset
   649
        remainder1 = _combinecopies(both1['incomplete'], both2['incomplete'],
7694b685bb10 copies: handle a case when both merging csets are not descendant of merge base
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 41756
diff changeset
   650
                                   copy, bothdiverge, bothincompletediverge)
7694b685bb10 copies: handle a case when both merging csets are not descendant of merge base
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 41756
diff changeset
   651
        remainder.update(remainder1)
7694b685bb10 copies: handle a case when both merging csets are not descendant of merge base
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 41756
diff changeset
   652
    elif dirtyc1:
30208
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30204
diff changeset
   653
        # incomplete copies may only be found on the "dirty" side for bothnew
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30204
diff changeset
   654
        assert not both2['incomplete']
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   655
        remainder = _combinecopies({}, both1['incomplete'], copy, bothdiverge,
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   656
                                   bothincompletediverge)
30208
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30204
diff changeset
   657
    elif dirtyc2:
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30204
diff changeset
   658
        assert not both1['incomplete']
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30204
diff changeset
   659
        remainder = _combinecopies({}, both2['incomplete'], copy, bothdiverge,
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30204
diff changeset
   660
                                   bothincompletediverge)
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   661
    else:
30208
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30204
diff changeset
   662
        # incomplete copies and divergences can't happen outside grafts
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30204
diff changeset
   663
        assert not both1['incomplete']
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30204
diff changeset
   664
        assert not both2['incomplete']
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30204
diff changeset
   665
        assert not bothincompletediverge
30202
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   666
    for f in remainder:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   667
        assert f not in bothdiverge
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   668
        ic = remainder[f]
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   669
        if ic[0] in (m1 if dirtyc1 else m2):
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   670
            # backed-out rename on one side, but watch out for deleted files
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30201
diff changeset
   671
            bothdiverge[f] = ic
20641
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
   672
    for of, fl in bothdiverge.items():
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
   673
        if len(fl) == 2 and fl[0] == fl[1]:
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
   674
            copy[fl[0]] = of # not actually divergent, just matching renames
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
   675
42162
31abb9d713af copies: don't include copies that are not in source in directory move
Martin von Zweigbergk <martinvonz@google.com>
parents: 42142
diff changeset
   676
    # Sometimes we get invalid copies here (the "and not remotebase" in
31abb9d713af copies: don't include copies that are not in source in directory move
Martin von Zweigbergk <martinvonz@google.com>
parents: 42142
diff changeset
   677
    # _checkcopies() seems suspicious). Filter them out.
31abb9d713af copies: don't include copies that are not in source in directory move
Martin von Zweigbergk <martinvonz@google.com>
parents: 42142
diff changeset
   678
    for dst, src in fullcopy.copy().items():
31abb9d713af copies: don't include copies that are not in source in directory move
Martin von Zweigbergk <martinvonz@google.com>
parents: 42142
diff changeset
   679
        if src not in mb:
31abb9d713af copies: don't include copies that are not in source in directory move
Martin von Zweigbergk <martinvonz@google.com>
parents: 42142
diff changeset
   680
            del fullcopy[dst]
42164
96bd75e67a94 copies: fix up "fullcopy" with missing entries from "copy"
Martin von Zweigbergk <martinvonz@google.com>
parents: 42162
diff changeset
   681
    # Sometimes we forget to add entries from "copy" to "fullcopy", so fix
96bd75e67a94 copies: fix up "fullcopy" with missing entries from "copy"
Martin von Zweigbergk <martinvonz@google.com>
parents: 42162
diff changeset
   682
    # that up here
96bd75e67a94 copies: fix up "fullcopy" with missing entries from "copy"
Martin von Zweigbergk <martinvonz@google.com>
parents: 42162
diff changeset
   683
    for dst, src in copy.items():
96bd75e67a94 copies: fix up "fullcopy" with missing entries from "copy"
Martin von Zweigbergk <martinvonz@google.com>
parents: 42162
diff changeset
   684
        fullcopy[dst] = src
42165
22c9ffdf8ef6 copies: fix up "fullcopy" with missing entries from "diverge"
Martin von Zweigbergk <martinvonz@google.com>
parents: 42164
diff changeset
   685
    # Sometimes we forget to add entries from "diverge" to "fullcopy", so fix
22c9ffdf8ef6 copies: fix up "fullcopy" with missing entries from "diverge"
Martin von Zweigbergk <martinvonz@google.com>
parents: 42164
diff changeset
   686
    # that up here
22c9ffdf8ef6 copies: fix up "fullcopy" with missing entries from "diverge"
Martin von Zweigbergk <martinvonz@google.com>
parents: 42164
diff changeset
   687
    for src, dsts in diverge.items():
22c9ffdf8ef6 copies: fix up "fullcopy" with missing entries from "diverge"
Martin von Zweigbergk <martinvonz@google.com>
parents: 42164
diff changeset
   688
        for dst in dsts:
22c9ffdf8ef6 copies: fix up "fullcopy" with missing entries from "diverge"
Martin von Zweigbergk <martinvonz@google.com>
parents: 42164
diff changeset
   689
            fullcopy[dst] = src
42166
85f5934016f9 copies: move early return for "no copies" case a little earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42165
diff changeset
   690
85f5934016f9 copies: move early return for "no copies" case a little earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42165
diff changeset
   691
    if not fullcopy:
85f5934016f9 copies: move early return for "no copies" case a little earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42165
diff changeset
   692
        return copy, {}, diverge, renamedelete, {}
85f5934016f9 copies: move early return for "no copies" case a little earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42165
diff changeset
   693
85f5934016f9 copies: move early return for "no copies" case a little earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42165
diff changeset
   694
    if repo.ui.debugflag:
16795
e9ae770eff1c merge: show renamed on one and deleted on the other side in debug output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16794
diff changeset
   695
        repo.ui.debug("  all copies found (* = to merge, ! = divergent, "
e9ae770eff1c merge: show renamed on one and deleted on the other side in debug output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16794
diff changeset
   696
                      "% = renamed and deleted):\n")
18362
5a4f220fbfca copies: report found copies sorted
Mads Kiilerich <mads@kiilerich.com>
parents: 18355
diff changeset
   697
        for f in sorted(fullcopy):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   698
            note = ""
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   699
            if f in copy:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   700
                note += "*"
26317
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26316
diff changeset
   701
            if f in divergeset:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   702
                note += "!"
26658
aabfa0fb7e3e copies: rename renamedelete to renamedeleteset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26657
diff changeset
   703
            if f in renamedeleteset:
16795
e9ae770eff1c merge: show renamed on one and deleted on the other side in debug output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16794
diff changeset
   704
                note += "%"
18135
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
   705
            repo.ui.debug("   src: '%s' -> dst: '%s' %s\n" % (fullcopy[f], f,
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
   706
                                                              note))
26317
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26316
diff changeset
   707
    del divergeset
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   708
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
   709
    repo.ui.debug("  checking for directory renames\n")
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   710
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   711
    # generate a directory move map
16178
828fe2ca7cbb copies: use ctx.dirs() for directory rename detection
Matt Mackall <mpm@selenic.com>
parents: 16177
diff changeset
   712
    d1, d2 = c1.dirs(), c2.dirs()
25288
947771ad5174 copies: document hack for adding '' to set of dirs
Martin von Zweigbergk <martinvonz@google.com>
parents: 25282
diff changeset
   713
    # Hack for adding '', which is not otherwise added, to d1 and d2
18899
d8ff607ef721 scmutil: use new dirs class in dirstate and context
Bryan O'Sullivan <bryano@fb.com>
parents: 18878
diff changeset
   714
    d1.addpath('/')
d8ff607ef721 scmutil: use new dirs class in dirstate and context
Bryan O'Sullivan <bryano@fb.com>
parents: 18878
diff changeset
   715
    d2.addpath('/')
17055
8b7cd9a998f0 copies: re-include root directory in directory rename detection (issue3511)
Matt Mackall <mpm@selenic.com>
parents: 16795
diff changeset
   716
    invalid = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   717
    dirmove = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   718
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   719
    # examine each file copy for a potential directory move, which is
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   720
    # when all the files in a directory are moved to a new directory
7622
4dd7b28003d2 use dict.iteritems() rather than dict.items()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6762
diff changeset
   721
    for dst, src in fullcopy.iteritems():
25282
0f28815ef066 copies: switch to using pathutil.dirname
Durham Goode <durham@fb.com>
parents: 24782
diff changeset
   722
        dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   723
        if dsrc in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   724
            # already seen to be uninteresting
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   725
            continue
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   726
        elif dsrc in d1 and ddst in d1:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   727
            # directory wasn't entirely moved locally
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
   728
            invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   729
        elif dsrc in d2 and ddst in d2:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   730
            # directory wasn't entirely moved remotely
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
   731
            invalid.add(dsrc)
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
   732
        elif dsrc in dirmove and dirmove[dsrc] != ddst:
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   733
            # files from the same directory moved to two different places
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
   734
            invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   735
        else:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   736
            # looks good so far
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
   737
            dirmove[dsrc] = ddst
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   738
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   739
    for i in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   740
        if i in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   741
            del dirmove[i]
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   742
    del d1, d2, invalid
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   743
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   744
    if not dirmove:
30581
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
   745
        return copy, {}, diverge, renamedelete, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   746
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
   747
    dirmove = {k + "/": v + "/" for k, v in dirmove.iteritems()}
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
   748
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   749
    for d in dirmove:
18135
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
   750
        repo.ui.debug("   discovered dir src: '%s' -> dst: '%s'\n" %
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
   751
                      (d, dirmove[d]))
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   752
30183
0106f93ca1d5 checkcopies: move 'movewithdir' initialisation right before its usage
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30138
diff changeset
   753
    movewithdir = {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   754
    # check unaccounted nonoverlapping files against directory moves
30047
d13a7c8bf0a5 copies: split u1/u2 to u1u/u2u and u1r/u2r
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30046
diff changeset
   755
    for f in u1r + u2r:
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   756
        if f not in fullcopy:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   757
            for d in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   758
                if f.startswith(d):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   759
                    # new file added in a directory that was moved, move it
6425
2d9328a2f81f copies: skip directory rename checks when not merging
Matt Mackall <mpm@selenic.com>
parents: 6424
diff changeset
   760
                    df = dirmove[d] + f[len(d):]
6426
e2c49ef2dd6e copies: don't double-detect items in the directory copy check
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   761
                    if df not in copy:
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
   762
                        movewithdir[f] = df
18135
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
   763
                        repo.ui.debug(("   pending file src: '%s' -> "
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
   764
                                       "dst: '%s'\n") % (f, df))
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   765
                    break
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   766
30581
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
   767
    return copy, movewithdir, diverge, renamedelete, dirmove
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   768
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   769
def _heuristicscopytracing(repo, c1, c2, base):
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   770
    """ Fast copytracing using filename heuristics
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   771
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   772
    Assumes that moves or renames are of following two types:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   773
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   774
    1) Inside a directory only (same directory name but different filenames)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   775
    2) Move from one directory to another
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   776
                    (same filenames but different directory names)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   777
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   778
    Works only when there are no merge commits in the "source branch".
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   779
    Source branch is commits from base up to c2 not including base.
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   780
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   781
    If merge is involved it fallbacks to _fullcopytracing().
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   782
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   783
    Can be used by setting the following config:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   784
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   785
        [experimental]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   786
        copytrace = heuristics
34846
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   787
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   788
    In some cases the copy/move candidates found by heuristics can be very large
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   789
    in number and that will make the algorithm slow. The number of possible
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   790
    candidates to check can be limited by using the config
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   791
    `experimental.copytrace.movecandidateslimit` which defaults to 100.
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   792
    """
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   793
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   794
    if c1.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   795
        c1 = c1.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   796
    if c2.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   797
        c2 = c2.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   798
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   799
    copies = {}
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   800
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   801
    changedfiles = set()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   802
    m1 = c1.manifest()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   803
    if not repo.revs('%d::%d', base.rev(), c2.rev()):
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   804
        # If base is not in c2 branch, we switch to fullcopytracing
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   805
        repo.ui.debug("switching to full copytracing as base is not "
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   806
                      "an ancestor of c2\n")
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   807
        return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   808
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   809
    ctx = c2
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   810
    while ctx != base:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   811
        if len(ctx.parents()) == 2:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   812
            # To keep things simple let's not handle merges
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   813
            repo.ui.debug("switching to full copytracing because of merges\n")
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   814
            return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   815
        changedfiles.update(ctx.files())
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   816
        ctx = ctx.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   817
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   818
    cp = _forwardcopies(base, c2)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   819
    for dst, src in cp.iteritems():
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   820
        if src in m1:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   821
            copies[dst] = src
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   822
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   823
    # file is missing if it isn't present in the destination, but is present in
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   824
    # the base and present in the source.
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   825
    # Presence in the base is important to exclude added files, presence in the
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   826
    # source is important to exclude removed files.
36346
f62369667a7c py3: use list comprehensions instead of filter where we need to eagerly filter
Augie Fackler <augie@google.com>
parents: 36117
diff changeset
   827
    filt = lambda f: f not in m1 and f in base and f in c2
f62369667a7c py3: use list comprehensions instead of filter where we need to eagerly filter
Augie Fackler <augie@google.com>
parents: 36117
diff changeset
   828
    missingfiles = [f for f in changedfiles if filt(f)]
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   829
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   830
    if missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   831
        basenametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   832
        dirnametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   833
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   834
        for f in m1.filesnotin(base.manifest()):
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   835
            basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   836
            dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   837
            basenametofilename[basename].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   838
            dirnametofilename[dirname].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   839
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   840
        for f in missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   841
            basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   842
            dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   843
            samebasename = basenametofilename[basename]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   844
            samedirname = dirnametofilename[dirname]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   845
            movecandidates = samebasename + samedirname
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   846
            # f is guaranteed to be present in c2, that's why
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   847
            # c2.filectx(f) won't fail
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   848
            f2 = c2.filectx(f)
34846
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   849
            # we can have a lot of candidates which can slow down the heuristics
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   850
            # config value to limit the number of candidates moves to check
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   851
            maxcandidates = repo.ui.configint('experimental',
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   852
                                              'copytrace.movecandidateslimit')
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   853
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   854
            if len(movecandidates) > maxcandidates:
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   855
                repo.ui.status(_("skipping copytracing for '%s', more "
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   856
                                 "candidates than the limit: %d\n")
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   857
                               % (f, len(movecandidates)))
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   858
                continue
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
   859
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   860
            for candidate in movecandidates:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   861
                f1 = c1.filectx(candidate)
37392
a4f02a17420d copies: clean up _related logic
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 36346
diff changeset
   862
                if _related(f1, f2):
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   863
                    # if there are a few related copies then we'll merge
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   864
                    # changes into all of them. This matches the behaviour
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   865
                    # of upstream copytracing
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   866
                    copies[candidate] = f
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   867
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   868
    return copies, {}, {}, {}, {}
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   869
37392
a4f02a17420d copies: clean up _related logic
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 36346
diff changeset
   870
def _related(f1, f2):
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   871
    """return True if f1 and f2 filectx have a common ancestor
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   872
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   873
    Walk back to common ancestor to see if the two files originate
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   874
    from the same file. Since workingfilectx's rev() is None it messes
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   875
    up the integer comparison logic, hence the pre-step check for
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   876
    None (f1 and f2 can only be workingfilectx's initially).
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   877
    """
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   878
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   879
    if f1 == f2:
41724
35158796f52f copies: return True instead of filename as it is expected to return boolean
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 41394
diff changeset
   880
        return True # a match
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   881
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   882
    g1, g2 = f1.ancestors(), f2.ancestors()
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   883
    try:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   884
        f1r, f2r = f1.linkrev(), f2.linkrev()
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   885
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   886
        if f1r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   887
            f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   888
        if f2r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   889
            f2 = next(g2)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   890
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   891
        while True:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   892
            f1r, f2r = f1.linkrev(), f2.linkrev()
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   893
            if f1r > f2r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   894
                f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   895
            elif f2r > f1r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   896
                f2 = next(g2)
37392
a4f02a17420d copies: clean up _related logic
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 36346
diff changeset
   897
            else: # f1 and f2 point to files in the same linkrev
a4f02a17420d copies: clean up _related logic
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 36346
diff changeset
   898
                return f1 == f2 # true if they point to the same file
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   899
    except StopIteration:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   900
        return False
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
   901
32563
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 32562
diff changeset
   902
def _checkcopies(srcctx, dstctx, f, base, tca, remotebase, limit, data):
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   903
    """
32560
931b7707179f copies: rename m2 to mdst
Stanislau Hlebik <stash@fb.com>
parents: 32559
diff changeset
   904
    check possible copies of f from msrc to mdst
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   905
32561
52cdbdd208d8 copies: rename ctx to srcctx
Stanislau Hlebik <stash@fb.com>
parents: 32560
diff changeset
   906
    srcctx = starting context for f in msrc
32562
e4d1bc14e39a copies: add dstctx parameter
Stanislau Hlebik <stash@fb.com>
parents: 32561
diff changeset
   907
    dstctx = destination context for f in mdst
32559
c8c9feffbd35 copies: rename m1 to msrc
Stanislau Hlebik <stash@fb.com>
parents: 32291
diff changeset
   908
    f = the filename to check (as in msrc)
30135
3eae81c0a09d checkcopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30075
diff changeset
   909
    base = the changectx used as a merge base
30195
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   910
    tca = topological common ancestor for graft-like scenarios
32561
52cdbdd208d8 copies: rename ctx to srcctx
Stanislau Hlebik <stash@fb.com>
parents: 32560
diff changeset
   911
    remotebase = True if base is outside tca::srcctx, False otherwise
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   912
    limit = the rev number to not search beyond
30185
e2bfe2d52d7a copies: move variable document from checkcopies to mergecopies
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30184
diff changeset
   913
    data = dictionary of dictionary to store copy data. (see mergecopies)
30045
12cac1e4d6d9 copies: limit is an optimization, and doesn't provide guarantees
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29216
diff changeset
   914
33879
169baf3d1d3c copies: fix typo in comment
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 33867
diff changeset
   915
    note: limit is only an optimization, and provides no guarantee that
169baf3d1d3c copies: fix typo in comment
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 33867
diff changeset
   916
    irrelevant revisions will not be visited
30045
12cac1e4d6d9 copies: limit is an optimization, and doesn't provide guarantees
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29216
diff changeset
   917
    there is no easy way to make this algorithm stop in a guaranteed way
12cac1e4d6d9 copies: limit is an optimization, and doesn't provide guarantees
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29216
diff changeset
   918
    once it "goes behind a certain revision".
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   919
    """
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   920
32563
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 32562
diff changeset
   921
    msrc = srcctx.manifest()
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 32562
diff changeset
   922
    mdst = dstctx.manifest()
30135
3eae81c0a09d checkcopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30075
diff changeset
   923
    mb = base.manifest()
30204
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   924
    mta = tca.manifest()
30195
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   925
    # Might be true if this call is about finding backward renames,
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   926
    # This happens in the case of grafts because the DAG is then rotated.
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   927
    # If the file exists in both the base and the source, we are not looking
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   928
    # for a rename on the source side, but on the part of the DAG that is
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   929
    # traversed backwards.
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   930
    #
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   931
    # In the case there is both backward and forward renames (before and after
30201
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30197
diff changeset
   932
    # the base) this is more complicated as we must detect a divergence.
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30197
diff changeset
   933
    # We use 'backwards = False' in that case.
30203
b94b92f0c683 checkcopies: add logic to handle remotebase
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30202
diff changeset
   934
    backwards = not remotebase and base != tca and f in mb
32564
6966e42f833a copies: rename getfctx to getsrcfctx
Stanislau Hlebik <stash@fb.com>
parents: 32563
diff changeset
   935
    getsrcfctx = _makegetfctx(srcctx)
32565
5313d98089f5 copies: introduce getdstfctx
Stanislau Hlebik <stash@fb.com>
parents: 32564
diff changeset
   936
    getdstfctx = _makegetfctx(dstctx)
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   937
32559
c8c9feffbd35 copies: rename m1 to msrc
Stanislau Hlebik <stash@fb.com>
parents: 32291
diff changeset
   938
    if msrc[f] == mb.get(f) and not remotebase:
30229
69ffbbe73dd0 merge: avoid superfluous filemerges when grafting through renames (issue5407)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30208
diff changeset
   939
        # Nothing to merge
69ffbbe73dd0 merge: avoid superfluous filemerges when grafting through renames (issue5407)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30208
diff changeset
   940
        return
69ffbbe73dd0 merge: avoid superfluous filemerges when grafting through renames (issue5407)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30208
diff changeset
   941
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   942
    of = None
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 31256
diff changeset
   943
    seen = {f}
32564
6966e42f833a copies: rename getfctx to getsrcfctx
Stanislau Hlebik <stash@fb.com>
parents: 32563
diff changeset
   944
    for oc in getsrcfctx(f, msrc[f]).ancestors():
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   945
        of = oc.path()
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   946
        if of in seen:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   947
            # check limit late - grab last rename before
39945
85c8ff26d698 copies: inline a variable that's used only once
Martin von Zweigbergk <martinvonz@google.com>
parents: 39366
diff changeset
   948
            if oc.linkrev() < limit:
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   949
                break
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   950
            continue
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   951
        seen.add(of)
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   952
30195
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   953
        # remember for dir rename detection
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   954
        if backwards:
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   955
            data['fullcopy'][of] = f # grafting backwards through renames
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   956
        else:
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   957
            data['fullcopy'][f] = of
32560
931b7707179f copies: rename m2 to mdst
Stanislau Hlebik <stash@fb.com>
parents: 32559
diff changeset
   958
        if of not in mdst:
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   959
            continue # no match, keep looking
32560
931b7707179f copies: rename m2 to mdst
Stanislau Hlebik <stash@fb.com>
parents: 32559
diff changeset
   960
        if mdst[of] == mb.get(of):
30075
2c8ec8c2ddfe copies: don't record divergence for files needing no merge
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30048
diff changeset
   961
            return # no merge needed, quit early
32565
5313d98089f5 copies: introduce getdstfctx
Stanislau Hlebik <stash@fb.com>
parents: 32564
diff changeset
   962
        c2 = getdstfctx(of, mdst[of])
30137
f85f9e069e09 checkcopies: add an inline comment about the '_related' call
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30136
diff changeset
   963
        # c2 might be a plain new file on added on destination side that is
f85f9e069e09 checkcopies: add an inline comment about the '_related' call
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30136
diff changeset
   964
        # unrelated to the droids we are looking for.
37392
a4f02a17420d copies: clean up _related logic
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 36346
diff changeset
   965
        cr = _related(oc, c2)
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   966
        if cr and (of == f or of == c2.path()): # non-divergent
30195
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   967
            if backwards:
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   968
                data['copy'][of] = f
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30194
diff changeset
   969
            elif of in mb:
30188
8a864844d5a0 checkcopies: add a sanity check against false-positive copies
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30186
diff changeset
   970
                data['copy'][f] = of
30203
b94b92f0c683 checkcopies: add logic to handle remotebase
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30202
diff changeset
   971
            elif remotebase: # special case: a <- b <- a -> b "ping-pong" rename
b94b92f0c683 checkcopies: add logic to handle remotebase
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30202
diff changeset
   972
                data['copy'][of] = f
b94b92f0c683 checkcopies: add logic to handle remotebase
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30202
diff changeset
   973
                del data['fullcopy'][f]
b94b92f0c683 checkcopies: add logic to handle remotebase
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30202
diff changeset
   974
                data['fullcopy'][of] = f
30201
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30197
diff changeset
   975
            else: # divergence w.r.t. graft CA on one side of topological CA
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30197
diff changeset
   976
                for sf in seen:
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30197
diff changeset
   977
                    if sf in mb:
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30197
diff changeset
   978
                        assert sf not in data['diverge']
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30197
diff changeset
   979
                        data['diverge'][sf] = [f, of]
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30197
diff changeset
   980
                        break
30075
2c8ec8c2ddfe copies: don't record divergence for files needing no merge
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30048
diff changeset
   981
            return
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
   982
30204
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   983
    if of in mta:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   984
        if backwards or remotebase:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   985
            data['incomplete'][of] = f
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   986
        else:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   987
            for sf in seen:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   988
                if sf in mb:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   989
                    if tca == base:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   990
                        data['diverge'].setdefault(sf, []).append(f)
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   991
                    else:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   992
                        data['incompletediverge'][sf] = [of, f]
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30203
diff changeset
   993
                    return
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
   994
34787
754b5117622f context: add workingfilectx.markcopied
Phil Cohen <phillco@fb.com>
parents: 34516
diff changeset
   995
def duplicatecopies(repo, wctx, rev, fromrev, skiprev=None):
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
   996
    """reproduce copies from fromrev to rev in the dirstate
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
   997
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
   998
    If skiprev is specified, it's a revision that should be used to
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
   999
    filter copy records. Any copies that occur between fromrev and
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
  1000
    skiprev will not be duplicated, even if they appear in the set of
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
  1001
    copies between fromrev and rev.
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
  1002
    """
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
  1003
    exclude = {}
39366
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
  1004
    ctraceconfig = repo.ui.config('experimental', 'copytrace')
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
  1005
    bctrace = stringutil.parsebool(ctraceconfig)
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
  1006
    if (skiprev is not None and
39366
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
  1007
        (ctraceconfig == 'heuristics' or bctrace or bctrace is None)):
34077
26531db4647a copytrace: replace experimental.disablecopytrace config with copytrace (BC)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33880
diff changeset
  1008
        # copytrace='off' skips this line, but not the entire function because
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
  1009
        # the line below is O(size of the repo) during a rebase, while the rest
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
  1010
        # of the function is much faster (and is required for carrying copy
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
  1011
        # metadata across the rebase anyway).
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
  1012
        exclude = pathcopies(repo[fromrev], repo[skiprev])
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
  1013
    for dst, src in pathcopies(repo[fromrev], repo[rev]).iteritems():
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
  1014
        # copies.pathcopies returns backward renames, so dst might not
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
  1015
        # actually be in the dirstate
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
  1016
        if dst in exclude:
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
  1017
            continue
34787
754b5117622f context: add workingfilectx.markcopied
Phil Cohen <phillco@fb.com>
parents: 34516
diff changeset
  1018
        wctx[dst].markcopied(src)