annotate mercurial/copies.py @ 6858:8f256bf98219

Add support for multiple possible bisect results (issue1228, issue1182) The real reason for both issue is that bisect can not handle cases where there are multiple possibilities for the result. Example (from issue1228): rev 0 -> good rev 1 -> skipped rev 2 -> skipped rev 3 -> skipped rev 4 -> bad Note that this patch does not only fix the reported Assertion Error but also the problem of a non converging bisect: hg init for i in `seq 3`; do echo $i > $i; hg add $i; hg ci -m$i; done hg bisect -b 2 hg bisect -g 0 hg bisect -s From this state on, you can: a) mark as bad forever (non converging!) b) mark as good to get an inconsistent state c) skip for the Assertion Error Minor description and code edits by pmezard.
author Bernhard Leiner <bleiner@gmail.com>
date Sat, 02 Aug 2008 22:10:10 +0200
parents a42d8d3e6ea9
children 9eb274d773d9
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 #
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"
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
14 l = [d for d in d1 if d not in d3 and d not in d2]
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
15 l.sort()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
16 return l
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
17
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
18 def _dirname(f):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
19 s = f.rfind("/")
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
20 if s == -1:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
21 return ""
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
22 return f[:s]
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
23
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
24 def _dirs(files):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
25 d = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
26 for f in files:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
27 f = _dirname(f)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
28 while f not in d:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
29 d[f] = True
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
30 f = _dirname(f)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
31 return d
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
32
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
33 def _findoldnames(fctx, limit):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
34 "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
35 old = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
36 seen = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
37 orig = fctx.path()
6424
d8f44384c3ee copies: sort old names by depth
Matt Mackall <mpm@selenic.com>
parents: 6422
diff changeset
38 visit = [(fctx, 0)]
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
39 while visit:
6424
d8f44384c3ee copies: sort old names by depth
Matt Mackall <mpm@selenic.com>
parents: 6422
diff changeset
40 fc, depth = visit.pop()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
41 s = str(fc)
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
42 if s in seen:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
43 continue
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
44 seen[s] = 1
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
45 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
46 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
47 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
48 continue
6424
d8f44384c3ee copies: sort old names by depth
Matt Mackall <mpm@selenic.com>
parents: 6422
diff changeset
49 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
50
6424
d8f44384c3ee copies: sort old names by depth
Matt Mackall <mpm@selenic.com>
parents: 6422
diff changeset
51 # return old names sorted by depth
d8f44384c3ee copies: sort old names by depth
Matt Mackall <mpm@selenic.com>
parents: 6422
diff changeset
52 old = old.values()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
53 old.sort()
6424
d8f44384c3ee copies: sort old names by depth
Matt Mackall <mpm@selenic.com>
parents: 6422
diff changeset
54 return [o[1] for o in old]
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
55
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
56 def _findlimit(repo, a, b):
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
57 "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
58 # basic idea:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
59 # - mark a and b with different sides
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
60 # - 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
61 # on that side, otherwise it is on no side
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
62 # - 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
63 # - add unseen parents to side map
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
64 # - 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
65 # - 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
66 # - track the lowest interesting rev seen
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
67 # - quit when interesting revs is zero
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
68
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
69 cl = repo.changelog
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
70 working = cl.count() # pseudo rev for the working directory
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
71 if a is None:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
72 a = working
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
73 if b is None:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
74 b = working
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
75
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
76 side = {a: -1, b: 1}
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
77 visit = [-a, -b]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
78 heapq.heapify(visit)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
79 interesting = len(visit)
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
80 limit = working
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
81
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
82 while interesting:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
83 r = -heapq.heappop(visit)
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
84 if r == working:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
85 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
86 else:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
87 parents = cl.parentrevs(r)
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
88 for p in parents:
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
89 if p not in side:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
90 # first time we see p; add it to visit
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
91 side[p] = side[r]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
92 if side[p]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
93 interesting += 1
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
94 heapq.heappush(visit, -p)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
95 elif side[p] and side[p] != side[r]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
96 # p was interesting but now we know better
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
97 side[p] = 0
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
98 interesting -= 1
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
99 if side[r]:
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
100 limit = r # lowest rev visited
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
101 interesting -= 1
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
102 return limit
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
103
6425
2d9328a2f81f copies: skip directory rename checks when not merging
Matt Mackall <mpm@selenic.com>
parents: 6424
diff changeset
104 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
105 """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
106 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
107 """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
108 # 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
109 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
110 return {}, {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
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