Mercurial > public > mercurial-scm > hg
annotate mercurial/copies.py @ 7305:c21d236ca897
hgweb: descend empty directories in web view
When a manifest has a series of directories with nothing in them but a single
directory, displaying the entire chain of empty directories allows for
navigation down to the first non-empty directory with a single click.
Because Java links package hierarchy to directory hierarchy, and because Java
conventions include at least three empty directories at the top of this
hierarchy, descending down empty directories is very common in Java web tools.
author | Ry4an Brase <ry4an-hg@ry4an.org> |
---|---|
date | Mon, 03 Nov 2008 10:20:28 +0100 |
parents | f67d1468ac50 |
children | 4dd7b28003d2 |
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 # |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
6 # of the GNU General Public License, incorporated herein by reference. |
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 node import nullid, nullrev |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
9 from i18n import _ |
6429
532ca442b903
symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents:
6426
diff
changeset
|
10 import util, 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" |
6762 | 14 return util.sort([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): |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
23 d = {} |
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: |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
27 d[f] = True |
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 = {} |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
34 seen = {} |
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 |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
42 seen[s] = 1 |
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 |
6274
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
45 if fc.rev() < limit and fc.rev() is not None: |
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 |
6762 | 50 return [o[1] for o in util.sort(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 |
9eb274d773d9
copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents:
6431
diff
changeset
|
109 if c2.node() == None and c1.node() == repo.dirstate.parents()[0]: |
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 ctx = util.cachefunc(makectx) |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
124 |
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 |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
147 repo.ui.debug(_(" searching for copies back to rev %d\n") % limit) |
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: |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
153 repo.ui.debug(_(" unmatched files in local:\n %s\n") |
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: |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
156 repo.ui.debug(_(" unmatched files in other:\n %s\n") |
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 |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
164 diverge2 = {} |
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: |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
169 diverge2.update(dict.fromkeys(fl)) # reverse map for below |
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: |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
172 repo.ui.debug(_(" all copies found (* = to merge, ! = divergent):\n")) |
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 += "!" |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
177 repo.ui.debug(_(" %s -> %s %s\n") % (f, fullcopy[f], note)) |
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 |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
183 repo.ui.debug(_(" checking for directory renames\n")) |
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) |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
187 invalid = {} |
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 |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
192 for dst, src in fullcopy.items(): |
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 |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
199 invalid[dsrc] = True |
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 |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
202 invalid[dsrc] = True |
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 |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
205 invalid[dsrc] = True |
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: |
f3f383efbeae
copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
219 repo.ui.debug(_(" dir %s -> %s\n") % (d, dirmove[d])) |
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 |
e2c49ef2dd6e
copies: don't double-detect items in the directory copy check
Matt Mackall <mpm@selenic.com>
parents:
6425
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 |