mercurial/copies.py
author Sune Foldager <cryo@cyanite.org>
Mon, 02 Nov 2009 10:19:14 +0100
changeset 9693 c40a1ee20aa5
parent 9467 4c041f1ee1b4
child 10179 83cfa1baf8ad
permissions -rw-r--r--
transaction: always remove empty journal on abort When transactions without entries were aborted, the journal (of size 0) was not unlinked, which prevents subsequent operations until hg recover is run on the repository. We also make sure the journal is unlinked when committing, even if the provided hook doesn't do so.
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
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
     6
# GNU General Public License version 2, incorporated herein by reference.
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
from i18n import _
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8225
diff changeset
     9
import util
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8225
diff changeset
    10
import heapq
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
def _nonoverlap(d1, d2, d3):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
    "Return list of elements in d1 not in d2 or d3"
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 8152
diff changeset
    14
    return sorted([d for d in d1 if d not in d3 and d not in d2])
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
def _dirname(f):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
    s = f.rfind("/")
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
    if s == -1:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
        return ""
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
    return f[:s]
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
def _dirs(files):
8468
b35d11d10646 copies: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8337
diff changeset
    23
    d = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
    for f in files:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
        f = _dirname(f)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
        while f not in d:
8468
b35d11d10646 copies: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8337
diff changeset
    27
            d.add(f)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
            f = _dirname(f)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
    return d
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
def _findoldnames(fctx, limit):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
    "find files that path was copied from, back to linkrev limit"
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
    old = {}
8468
b35d11d10646 copies: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8337
diff changeset
    34
    seen = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
    orig = fctx.path()
6424
d8f44384c3ee copies: sort old names by depth
Matt Mackall <mpm@selenic.com>
parents: 6422
diff changeset
    36
    visit = [(fctx, 0)]
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
    while visit:
6424
d8f44384c3ee copies: sort old names by depth
Matt Mackall <mpm@selenic.com>
parents: 6422
diff changeset
    38
        fc, depth = visit.pop()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
        s = str(fc)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    40
        if s in seen:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    41
            continue
8468
b35d11d10646 copies: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8337
diff changeset
    42
        seen.add(s)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
        if fc.path() != orig and fc.path() not in old:
6424
d8f44384c3ee copies: sort old names by depth
Matt Mackall <mpm@selenic.com>
parents: 6422
diff changeset
    44
            old[fc.path()] = (depth, fc.path()) # remember depth
9030
3f56055ff1d7 compat: can't compare two values of unequal datatypes
Alejandro Santos <alejolp@alejolp.com>
parents: 8527
diff changeset
    45
        if fc.rev() is not None and fc.rev() < limit:
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
            continue
6424
d8f44384c3ee copies: sort old names by depth
Matt Mackall <mpm@selenic.com>
parents: 6422
diff changeset
    47
        visit += [(p, depth - 1) for p in fc.parents()]
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
6424
d8f44384c3ee copies: sort old names by depth
Matt Mackall <mpm@selenic.com>
parents: 6422
diff changeset
    49
    # return old names sorted by depth
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 8152
diff changeset
    50
    return [o[1] for o in sorted(old.values())]
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
    52
def _findlimit(repo, a, b):
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
    53
    "find the earliest revision that's an ancestor of a or b but not both"
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    54
    # basic idea:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    55
    # - mark a and b with different sides
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    56
    # - 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
    57
    #   on that side, otherwise it is on no side
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    58
    # - 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
    59
    #   - add unseen parents to side map
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    60
    #   - 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
    61
    #   - 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
    62
    #   - track the lowest interesting rev seen
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
    63
    #   - quit when interesting revs is zero
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    64
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    65
    cl = repo.changelog
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6646
diff changeset
    66
    working = len(cl) # pseudo rev for the working directory
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    67
    if a is None:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    68
        a = working
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    69
    if b is None:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    70
        b = working
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    71
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    72
    side = {a: -1, b: 1}
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    73
    visit = [-a, -b]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    74
    heapq.heapify(visit)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    75
    interesting = len(visit)
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
    76
    limit = working
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    77
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    78
    while interesting:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    79
        r = -heapq.heappop(visit)
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    80
        if r == working:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    81
            parents = [cl.rev(p) for p in repo.dirstate.parents()]
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    82
        else:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    83
            parents = cl.parentrevs(r)
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    84
        for p in parents:
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    85
            if p not in side:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    86
                # first time we see p; add it to visit
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    87
                side[p] = side[r]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    88
                if side[p]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    89
                    interesting += 1
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    90
                heapq.heappush(visit, -p)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    91
            elif side[p] and side[p] != side[r]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    92
                # p was interesting but now we know better
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    93
                side[p] = 0
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    94
                interesting -= 1
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    95
        if side[r]:
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
    96
            limit = r # lowest rev visited
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
    97
            interesting -= 1
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
    98
    return limit
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
    99
6425
2d9328a2f81f copies: skip directory rename checks when not merging
Matt Mackall <mpm@selenic.com>
parents: 6424
diff changeset
   100
def copies(repo, c1, c2, ca, checkdirs=False):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
    """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   102
    Find moves and copies between context c1 and c2
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   103
    """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   104
    # 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
   105
    if not c1 or not c2 or c1 == c2:
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   106
        return {}, {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   107
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
   108
    # avoid silly behavior for parent -> working dir
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8468
diff changeset
   109
    if c2.node() is None and c1.node() == repo.dirstate.parents()[0]:
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
   110
        return repo.dirstate.copies(), {}
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
   111
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
   112
    limit = _findlimit(repo, c1.rev(), c2.rev())
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   113
    m1 = c1.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   114
    m2 = c2.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   115
    ma = ca.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   116
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   117
    def makectx(f, n):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   118
        if len(n) != 20: # in a working context?
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   119
            if c1.rev() is None:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   120
                return c1.filectx(f)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   121
            return c2.filectx(f)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   122
        return repo.filectx(f, fileid=n)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   123
9097
431462bd8478 fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents: 8527
diff changeset
   124
    ctx = util.lrucachefunc(makectx)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   125
    copy = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   126
    fullcopy = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   127
    diverge = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   128
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   129
    def checkcopies(f, m1, m2):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   130
        '''check possible copies of f from m1 to m2'''
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   131
        c1 = ctx(f, m1[f])
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   132
        for of in _findoldnames(c1, limit):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   133
            fullcopy[f] = of # remember for dir rename detection
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   134
            if of in m2: # original file not in other manifest?
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   135
                # if the original file is unchanged on the other branch,
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   136
                # no merge needed
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   137
                if m2[of] != ma.get(of):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   138
                    c2 = ctx(of, m2[of])
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   139
                    ca = c1.ancestor(c2)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   140
                    # related and named changed on only one side?
6422
3ee6f1fce94a copies: fix silly precedence bug
Matt Mackall <mpm@selenic.com>
parents: 6283
diff changeset
   141
                    if ca and (ca.path() == f or ca.path() == c2.path()):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   142
                        if c1 != ca or c2 != ca: # merge needed?
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   143
                            copy[f] = of
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   144
            elif of in ma:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   145
                diverge.setdefault(of, []).append(f)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   146
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
   147
    repo.ui.debug("  searching for copies back to rev %d\n" % limit)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   148
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   149
    u1 = _nonoverlap(m1, m2, ma)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   150
    u2 = _nonoverlap(m2, m1, ma)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   151
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   152
    if u1:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
   153
        repo.ui.debug("  unmatched files in local:\n   %s\n"
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   154
                      % "\n   ".join(u1))
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   155
    if u2:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
   156
        repo.ui.debug("  unmatched files in other:\n   %s\n"
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   157
                      % "\n   ".join(u2))
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   158
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   159
    for f in u1:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   160
        checkcopies(f, m1, m2)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   161
    for f in u2:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   162
        checkcopies(f, m2, m1)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   163
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
   164
    diverge2 = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   165
    for of, fl in diverge.items():
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   166
        if len(fl) == 1:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   167
            del diverge[of] # not actually divergent
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   168
        else:
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
   169
            diverge2.update(fl) # reverse map for below
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   170
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   171
    if fullcopy:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
   172
        repo.ui.debug("  all copies found (* = to merge, ! = divergent):\n")
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   173
        for f in fullcopy:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   174
            note = ""
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   175
            if f in copy: note += "*"
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   176
            if f in diverge2: note += "!"
8337
0e73e21d81ff copies: don't translate untranslatable string
Martin Geisler <mg@lazybytes.net>
parents: 8312
diff changeset
   177
            repo.ui.debug("   %s -> %s %s\n" % (f, fullcopy[f], note))
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   178
    del diverge2
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   179
6425
2d9328a2f81f copies: skip directory rename checks when not merging
Matt Mackall <mpm@selenic.com>
parents: 6424
diff changeset
   180
    if not fullcopy or not checkdirs:
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   181
        return copy, diverge
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   182
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
   183
    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
   184
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   185
    # generate a directory move map
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   186
    d1, d2 = _dirs(m1), _dirs(m2)
8468
b35d11d10646 copies: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8337
diff changeset
   187
    invalid = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   188
    dirmove = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   189
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   190
    # 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
   191
    # 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
   192
    for dst, src in fullcopy.iteritems():
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   193
        dsrc, ddst = _dirname(src), _dirname(dst)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   194
        if dsrc in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   195
            # already seen to be uninteresting
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   196
            continue
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   197
        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
   198
            # directory wasn't entirely moved locally
8468
b35d11d10646 copies: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8337
diff changeset
   199
            invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   200
        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
   201
            # directory wasn't entirely moved remotely
8468
b35d11d10646 copies: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8337
diff changeset
   202
            invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   203
        elif dsrc in dirmove and dirmove[dsrc] != ddst:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   204
            # files from the same directory moved to two different places
8468
b35d11d10646 copies: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8337
diff changeset
   205
            invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   206
        else:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   207
            # looks good so far
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   208
            dirmove[dsrc + "/"] = ddst + "/"
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   209
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   210
    for i in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   211
        if i in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   212
            del dirmove[i]
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   213
    del d1, d2, invalid
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   214
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   215
    if not dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   216
        return copy, diverge
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   217
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   218
    for d in dirmove:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
   219
        repo.ui.debug("  dir %s -> %s\n" % (d, dirmove[d]))
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   220
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   221
    # check unaccounted nonoverlapping files against directory moves
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   222
    for f in u1 + u2:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   223
        if f not in fullcopy:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   224
            for d in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   225
                if f.startswith(d):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   226
                    # 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
   227
                    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
   228
                    if df not in copy:
e2c49ef2dd6e copies: don't double-detect items in the directory copy check
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   229
                        copy[f] = df
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
   230
                        repo.ui.debug("  file %s -> %s\n" % (f, copy[f]))
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   231
                    break
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   232
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   233
    return copy, diverge