##// END OF EJS Templates
merge: privatize some functions, unnest some others
Matt Mackall -
r6269:ffdf70e7 default
parent child Browse files
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