Show More
@@ -9,7 +9,7 b' from node import nullid, nullrev' | |||
|
9 | 9 | from i18n import _ |
|
10 | 10 | import errno, util, os, heapq, filemerge |
|
11 | 11 | |
|
12 | def checkunknown(wctx, mctx): | |
|
12 | def _checkunknown(wctx, mctx): | |
|
13 | 13 | "check for collisions between unknown files and files in mctx" |
|
14 | 14 | man = mctx.manifest() |
|
15 | 15 | for f in wctx.unknown(): |
@@ -19,7 +19,7 b' def checkunknown(wctx, mctx):' | |||
|
19 | 19 | " from file in requested revision: '%s'") |
|
20 | 20 | % f) |
|
21 | 21 | |
|
22 | def checkcollision(mctx): | |
|
22 | def _checkcollision(mctx): | |
|
23 | 23 | "check for case folding collisions in the destination context" |
|
24 | 24 | folded = {} |
|
25 | 25 | for fn in mctx.manifest(): |
@@ -29,7 +29,7 b' def checkcollision(mctx):' | |||
|
29 | 29 | % (fn, folded[fold])) |
|
30 | 30 | folded[fold] = fn |
|
31 | 31 | |
|
32 | def forgetremoved(wctx, mctx, branchmerge): | |
|
32 | def _forgetremoved(wctx, mctx, branchmerge): | |
|
33 | 33 | """ |
|
34 | 34 | Forget removed files |
|
35 | 35 | |
@@ -58,32 +58,54 b' def forgetremoved(wctx, mctx, branchmerg' | |||
|
58 | 58 | |
|
59 | 59 | return action |
|
60 | 60 | |
|
61 | def _nonoverlap(d1, d2, d3): | |
|
62 | "Return list of elements in d1 not in d2 or d3" | |
|
63 | l = [d for d in d1 if d not in d3 and d not in d2] | |
|
64 | l.sort() | |
|
65 | return l | |
|
66 | ||
|
67 | def _dirname(f): | |
|
68 | s = f.rfind("/") | |
|
69 | if s == -1: | |
|
70 | return "" | |
|
71 | return f[:s] | |
|
72 | ||
|
73 | def _dirs(files): | |
|
74 | d = {} | |
|
75 | for f in files: | |
|
76 | f = _dirname(f) | |
|
77 | while f not in d: | |
|
78 | d[f] = True | |
|
79 | f = _dirname(f) | |
|
80 | return d | |
|
81 | ||
|
82 | def _findoldnames(fctx, limit): | |
|
83 | "find files that path was copied from, back to linkrev limit" | |
|
84 | old = {} | |
|
85 | seen = {} | |
|
86 | orig = fctx.path() | |
|
87 | visit = [fctx] | |
|
88 | while visit: | |
|
89 | fc = visit.pop() | |
|
90 | s = str(fc) | |
|
91 | if s in seen: | |
|
92 | continue | |
|
93 | seen[s] = 1 | |
|
94 | if fc.path() != orig and fc.path() not in old: | |
|
95 | old[fc.path()] = 1 | |
|
96 | if fc.rev() < limit: | |
|
97 | continue | |
|
98 | visit += fc.parents() | |
|
99 | ||
|
100 | old = old.keys() | |
|
101 | old.sort() | |
|
102 | return old | |
|
103 | ||
|
61 | 104 | def findcopies(repo, m1, m2, ma, limit): |
|
62 | 105 | """ |
|
63 | 106 | Find moves and copies between m1 and m2 back to limit linkrev |
|
64 | 107 | """ |
|
65 | 108 | |
|
66 | def nonoverlap(d1, d2, d3): | |
|
67 | "Return list of elements in d1 not in d2 or d3" | |
|
68 | l = [d for d in d1 if d not in d3 and d not in d2] | |
|
69 | l.sort() | |
|
70 | return l | |
|
71 | ||
|
72 | def dirname(f): | |
|
73 | s = f.rfind("/") | |
|
74 | if s == -1: | |
|
75 | return "" | |
|
76 | return f[:s] | |
|
77 | ||
|
78 | def dirs(files): | |
|
79 | d = {} | |
|
80 | for f in files: | |
|
81 | f = dirname(f) | |
|
82 | while f not in d: | |
|
83 | d[f] = True | |
|
84 | f = dirname(f) | |
|
85 | return d | |
|
86 | ||
|
87 | 109 | wctx = repo.workingctx() |
|
88 | 110 | |
|
89 | 111 | def makectx(f, n): |
@@ -92,35 +114,13 b' def findcopies(repo, m1, m2, ma, limit):' | |||
|
92 | 114 | return wctx.filectx(f) |
|
93 | 115 | ctx = util.cachefunc(makectx) |
|
94 | 116 | |
|
95 | def findold(fctx): | |
|
96 | "find files that path was copied from, back to linkrev limit" | |
|
97 | old = {} | |
|
98 | seen = {} | |
|
99 | orig = fctx.path() | |
|
100 | visit = [fctx] | |
|
101 | while visit: | |
|
102 | fc = visit.pop() | |
|
103 | s = str(fc) | |
|
104 | if s in seen: | |
|
105 | continue | |
|
106 | seen[s] = 1 | |
|
107 | if fc.path() != orig and fc.path() not in old: | |
|
108 | old[fc.path()] = 1 | |
|
109 | if fc.rev() < limit and fc.rev() is not None: | |
|
110 | continue | |
|
111 | visit += fc.parents() | |
|
112 | ||
|
113 | old = old.keys() | |
|
114 | old.sort() | |
|
115 | return old | |
|
116 | ||
|
117 | 117 | copy = {} |
|
118 | 118 | fullcopy = {} |
|
119 | 119 | diverge = {} |
|
120 | 120 | |
|
121 | 121 | def checkcopies(c, man, aman): |
|
122 | 122 | '''check possible copies for filectx c''' |
|
123 | for of in findold(c): | |
|
123 | for of in _findoldnames(c, limit): | |
|
124 | 124 | fullcopy[c.path()] = of # remember for dir rename detection |
|
125 | 125 | if of not in man: # original file not in other manifest? |
|
126 | 126 | if of in ma: |
@@ -149,8 +149,8 b' def findcopies(repo, m1, m2, ma, limit):' | |||
|
149 | 149 | |
|
150 | 150 | repo.ui.debug(_(" searching for copies back to rev %d\n") % limit) |
|
151 | 151 | |
|
152 | u1 = nonoverlap(m1, m2, ma) | |
|
153 | u2 = nonoverlap(m2, m1, ma) | |
|
152 | u1 = _nonoverlap(m1, m2, ma) | |
|
153 | u2 = _nonoverlap(m2, m1, ma) | |
|
154 | 154 | |
|
155 | 155 | if u1: |
|
156 | 156 | repo.ui.debug(_(" unmatched files in local:\n %s\n") |
@@ -188,14 +188,14 b' def findcopies(repo, m1, m2, ma, limit):' | |||
|
188 | 188 | repo.ui.debug(_(" checking for directory renames\n")) |
|
189 | 189 | |
|
190 | 190 | # generate a directory move map |
|
191 | d1, d2 = dirs(m1), dirs(m2) | |
|
191 | d1, d2 = _dirs(m1), _dirs(m2) | |
|
192 | 192 | invalid = {} |
|
193 | 193 | dirmove = {} |
|
194 | 194 | |
|
195 | 195 | # examine each file copy for a potential directory move, which is |
|
196 | 196 | # when all the files in a directory are moved to a new directory |
|
197 | 197 | for dst, src in fullcopy.items(): |
|
198 | dsrc, ddst = dirname(src), dirname(dst) | |
|
198 | dsrc, ddst = _dirname(src), _dirname(dst) | |
|
199 | 199 | if dsrc in invalid: |
|
200 | 200 | # already seen to be uninteresting |
|
201 | 201 | continue |
@@ -236,7 +236,7 b' def findcopies(repo, m1, m2, ma, limit):' | |||
|
236 | 236 | |
|
237 | 237 | return copy, diverge |
|
238 | 238 | |
|
239 | def symmetricdifference(repo, rev1, rev2): | |
|
239 | def _symmetricdifference(repo, rev1, rev2): | |
|
240 | 240 | """symmetric difference of the sets of ancestors of rev1 and rev2 |
|
241 | 241 | |
|
242 | 242 | I.e. revisions that are ancestors of rev1 or rev2, but not both. |
@@ -340,7 +340,7 b' def manifestmerge(repo, p1, p2, pa, over' | |||
|
340 | 340 | if rev1 is None: |
|
341 | 341 | # p1 is a workingctx |
|
342 | 342 | rev1 = p1.parents()[0].rev() |
|
343 | limit = min(symmetricdifference(repo, rev1, p2.rev())) | |
|
343 | limit = min(_symmetricdifference(repo, rev1, p2.rev())) | |
|
344 | 344 | copy, diverge = findcopies(repo, m1, m2, ma, limit) |
|
345 | 345 | |
|
346 | 346 | for of, fl in diverge.items(): |
@@ -615,10 +615,10 b' def update(repo, node, branchmerge, forc' | |||
|
615 | 615 | ### calculate phase |
|
616 | 616 | action = [] |
|
617 | 617 | if not force: |
|
618 | checkunknown(wc, p2) | |
|
618 | _checkunknown(wc, p2) | |
|
619 | 619 | if not util.checkfolding(repo.path): |
|
620 | checkcollision(p2) | |
|
621 | action += forgetremoved(wc, p2, branchmerge) | |
|
620 | _checkcollision(p2) | |
|
621 | action += _forgetremoved(wc, p2, branchmerge) | |
|
622 | 622 | action += manifestmerge(repo, wc, p2, pa, overwrite, partial) |
|
623 | 623 | |
|
624 | 624 | ### apply phase |
General Comments 0
You need to be logged in to leave comments.
Login now