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