annotate mercurial/copies.py @ 10364:de1e7099d100

dispatch: provide help for disabled extensions and commands Before a command is declared unknown, each extension in hgext is searched, starting with hgext.<cmdname>. If there's a matching command, a help message suggests the appropriate extension and how to enable it. Every extension could potentially be imported, but for cases like rebase, relink, etc. only one extension is imported. For the case of "hg help disabledext", if the extension is in hgext, the extension description is read and a similar help suggestion is printed. No extension import occurs.
author Brodie Rao <me+hg@dackz.net>
date Sun, 07 Feb 2010 14:01:43 +0100
parents 31141fd7c9cc
children 5ddde896a19d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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
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
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
31 def _findlimit(repo, a, b):
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
32 """Find the earliest revision that's an ancestor of a or b but not both,
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
33 None if no such revision exists.
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
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
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6646
diff changeset
47 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
48 if a is None:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
49 a = working
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
50 if b is None:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
51 b = working
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
52
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
53 side = {a: -1, b: 1}
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
54 visit = [-a, -b]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
55 heapq.heapify(visit)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
56 interesting = len(visit)
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
57 hascommonancestor = False
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
58 limit = working
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
59
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
60 while interesting:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
61 r = -heapq.heappop(visit)
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
62 if r == working:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
63 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
64 else:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
65 parents = cl.parentrevs(r)
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
66 for p in parents:
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
67 if p < 0:
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
68 continue
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
69 if p not in side:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
70 # first time we see p; add it to visit
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
71 side[p] = side[r]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
72 if side[p]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
73 interesting += 1
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
74 heapq.heappush(visit, -p)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
75 elif side[p] and side[p] != side[r]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
76 # p was interesting but now we know better
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
77 side[p] = 0
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
78 interesting -= 1
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
79 hascommonancestor = True
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
80 if side[r]:
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
81 limit = r # lowest rev visited
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
82 interesting -= 1
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
83
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
84 if not hascommonancestor:
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
85 return None
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
86 return limit
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
87
6425
2d9328a2f81f copies: skip directory rename checks when not merging
Matt Mackall <mpm@selenic.com>
parents: 6424
diff changeset
88 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
89 """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
90 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
91 """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
92 # 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
93 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
94 return {}, {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
95
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
96 # 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
97 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
98 return repo.dirstate.copies(), {}
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
99
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
100 limit = _findlimit(repo, c1.rev(), c2.rev())
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
101 if limit is None:
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
102 # no common ancestor, no copies
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
103 return {}, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
104 m1 = c1.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
105 m2 = c2.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
106 ma = ca.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
107
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
108 def makectx(f, n):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
109 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
110 if c1.rev() is None:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
111 return c1.filectx(f)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
112 return c2.filectx(f)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
113 return repo.filectx(f, fileid=n)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
114
9097
431462bd8478 fix memory usage of revlog caches by limiting cache size [issue1639]
Matt Mackall <mpm@selenic.com>
parents: 8527
diff changeset
115 ctx = util.lrucachefunc(makectx)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
116 copy = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
117 fullcopy = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
118 diverge = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
119
10262
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
120 def related(f1, f2, limit):
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
121 g1, g2 = f1.ancestors(), f2.ancestors()
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
122 try:
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
123 while 1:
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
124 f1r, f2r = f1.rev(), f2.rev()
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
125 if f1r > f2r:
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
126 f1 = g1.next()
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
127 elif f2r > f1r:
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
128 f2 = g2.next()
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
129 elif f1 == f2:
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
130 return f1 # a match
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
131 elif f1r == f2r or f1r < limit or f2r < limit:
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
132 return False # copy no longer relevant
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
133 except StopIteration:
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
134 return False
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
135
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
136 def checkcopies(f, m1, m2):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
137 '''check possible copies of f from m1 to m2'''
10262
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
138 of = None
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
139 seen = set([f])
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
140 for oc in ctx(f, m1[f]).ancestors():
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
141 ocr = oc.rev()
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
142 of = oc.path()
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
143 if of in seen:
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
144 # check limit late - grab last rename before
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
145 if ocr < limit:
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
146 break
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
147 continue
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
148 seen.add(of)
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
149
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
150 fullcopy[f] = of # remember for dir rename detection
10262
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
151 if of not in m2:
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
152 continue # no match, keep looking
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
153 if m2[of] == ma.get(of):
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
154 break # no merge needed, quit early
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
155 c2 = ctx(of, m2[of])
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
156 cr = related(oc, c2, ca.rev())
10313
31141fd7c9cc copies: check if revisions are related (bug found with pylint)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10302
diff changeset
157 if cr and (of == f or of == c2.path()): # non-divergent
10262
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
158 copy[f] = of
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
159 of = None
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
160 break
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
161
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
162 if of in ma:
eb243551cbd8 copies: speed up copy detection
Matt Mackall <mpm@selenic.com>
parents: 10179
diff changeset
163 diverge.setdefault(of, []).append(f)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
164
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
165 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
166
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
167 u1 = _nonoverlap(m1, m2, ma)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
168 u2 = _nonoverlap(m2, m1, ma)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
169
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
170 if u1:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
171 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
172 % "\n ".join(u1))
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
173 if u2:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
174 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
175 % "\n ".join(u2))
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
176
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
177 for f in u1:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
178 checkcopies(f, m1, m2)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
179 for f in u2:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
180 checkcopies(f, m2, m1)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
181
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
182 diverge2 = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
183 for of, fl in diverge.items():
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
184 if len(fl) == 1:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
185 del diverge[of] # not actually divergent
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
186 else:
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
187 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
188
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
189 if fullcopy:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
190 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
191 for f in fullcopy:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
192 note = ""
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
193 if f in copy:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
194 note += "*"
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
195 if f in diverge2:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
196 note += "!"
8337
0e73e21d81ff copies: don't translate untranslatable string
Martin Geisler <mg@lazybytes.net>
parents: 8312
diff changeset
197 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
198 del diverge2
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
199
6425
2d9328a2f81f copies: skip directory rename checks when not merging
Matt Mackall <mpm@selenic.com>
parents: 6424
diff changeset
200 if not fullcopy or not checkdirs:
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
201 return copy, diverge
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
202
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
203 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
204
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
205 # generate a directory move map
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
206 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
207 invalid = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
208 dirmove = {}
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 # 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
211 # 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
212 for dst, src in fullcopy.iteritems():
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
213 dsrc, ddst = _dirname(src), _dirname(dst)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
214 if dsrc in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
215 # already seen to be uninteresting
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
216 continue
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
217 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
218 # 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
219 invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
220 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
221 # 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
222 invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
223 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
224 # 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
225 invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
226 else:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
227 # looks good so far
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
228 dirmove[dsrc + "/"] = ddst + "/"
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
229
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
230 for i in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
231 if i in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
232 del dirmove[i]
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
233 del d1, d2, invalid
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
234
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
235 if not dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
236 return copy, diverge
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
237
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
238 for d in dirmove:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
239 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
240
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
241 # check unaccounted nonoverlapping files against directory moves
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
242 for f in u1 + u2:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
243 if f not in fullcopy:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
244 for d in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
245 if f.startswith(d):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
246 # 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
247 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
248 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
249 copy[f] = df
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
250 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
251 break
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
252
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
253 return copy, diverge