##// END OF EJS Templates
copies: refactor checkcopies() into a top level method...
Durham Goode -
r19178:4327687c default
parent child Browse files
Show More
@@ -222,65 +222,8 b' def mergecopies(repo, c1, c2, ca):'
222 fullcopy = {}
222 fullcopy = {}
223 diverge = {}
223 diverge = {}
224
224
225 def related(f1, f2, limit):
225 def _checkcopies(f, m1, m2):
226 # Walk back to common ancestor to see if the two files originate
226 checkcopies(ctx, f, m1, m2, ca, limit, diverge, copy, fullcopy)
227 # from the same file. Since workingfilectx's rev() is None it messes
228 # up the integer comparison logic, hence the pre-step check for
229 # None (f1 and f2 can only be workingfilectx's initially).
230
231 if f1 == f2:
232 return f1 # a match
233
234 g1, g2 = f1.ancestors(), f2.ancestors()
235 try:
236 f1r, f2r = f1.rev(), f2.rev()
237
238 if f1r is None:
239 f1 = g1.next()
240 if f2r is None:
241 f2 = g2.next()
242
243 while True:
244 f1r, f2r = f1.rev(), f2.rev()
245 if f1r > f2r:
246 f1 = g1.next()
247 elif f2r > f1r:
248 f2 = g2.next()
249 elif f1 == f2:
250 return f1 # a match
251 elif f1r == f2r or f1r < limit or f2r < limit:
252 return False # copy no longer relevant
253 except StopIteration:
254 return False
255
256 def checkcopies(f, m1, m2):
257 '''check possible copies of f from m1 to m2'''
258 of = None
259 seen = set([f])
260 for oc in ctx(f, m1[f]).ancestors():
261 ocr = oc.rev()
262 of = oc.path()
263 if of in seen:
264 # check limit late - grab last rename before
265 if ocr < limit:
266 break
267 continue
268 seen.add(of)
269
270 fullcopy[f] = of # remember for dir rename detection
271 if of not in m2:
272 continue # no match, keep looking
273 if m2[of] == ma.get(of):
274 break # no merge needed, quit early
275 c2 = ctx(of, m2[of])
276 cr = related(oc, c2, ca.rev())
277 if cr and (of == f or of == c2.path()): # non-divergent
278 copy[f] = of
279 of = None
280 break
281
282 if of in ma:
283 diverge.setdefault(of, []).append(f)
284
227
285 repo.ui.debug(" searching for copies back to rev %d\n" % limit)
228 repo.ui.debug(" searching for copies back to rev %d\n" % limit)
286
229
@@ -295,9 +238,9 b' def mergecopies(repo, c1, c2, ca):'
295 % "\n ".join(u2))
238 % "\n ".join(u2))
296
239
297 for f in u1:
240 for f in u1:
298 checkcopies(f, m1, m2)
241 _checkcopies(f, m1, m2)
299 for f in u2:
242 for f in u2:
300 checkcopies(f, m2, m1)
243 _checkcopies(f, m2, m1)
301
244
302 renamedelete = {}
245 renamedelete = {}
303 renamedelete2 = set()
246 renamedelete2 = set()
@@ -386,3 +329,78 b' def mergecopies(repo, c1, c2, ca):'
386 break
329 break
387
330
388 return copy, movewithdir, diverge, renamedelete
331 return copy, movewithdir, diverge, renamedelete
332
333 def checkcopies(ctx, f, m1, m2, ca, limit, diverge, copy, fullcopy):
334 """
335 check possible copies of f from m1 to m2
336
337 ctx = function accepting (filename, node) that returns a filectx.
338 f = the filename to check
339 m1 = the source manifest
340 m2 = the destination manifest
341 ca = the changectx of the common ancestor
342 limit = the rev number to not search beyond
343 diverge = record all diverges in this dict
344 copy = record all non-divergent copies in this dict
345 fullcopy = record all copies in this dict
346 """
347
348 ma = ca.manifest()
349
350 def _related(f1, f2, limit):
351 # Walk back to common ancestor to see if the two files originate
352 # from the same file. Since workingfilectx's rev() is None it messes
353 # up the integer comparison logic, hence the pre-step check for
354 # None (f1 and f2 can only be workingfilectx's initially).
355
356 if f1 == f2:
357 return f1 # a match
358
359 g1, g2 = f1.ancestors(), f2.ancestors()
360 try:
361 f1r, f2r = f1.rev(), f2.rev()
362
363 if f1r is None:
364 f1 = g1.next()
365 if f2r is None:
366 f2 = g2.next()
367
368 while True:
369 f1r, f2r = f1.rev(), f2.rev()
370 if f1r > f2r:
371 f1 = g1.next()
372 elif f2r > f1r:
373 f2 = g2.next()
374 elif f1 == f2:
375 return f1 # a match
376 elif f1r == f2r or f1r < limit or f2r < limit:
377 return False # copy no longer relevant
378 except StopIteration:
379 return False
380
381 of = None
382 seen = set([f])
383 for oc in ctx(f, m1[f]).ancestors():
384 ocr = oc.rev()
385 of = oc.path()
386 if of in seen:
387 # check limit late - grab last rename before
388 if ocr < limit:
389 break
390 continue
391 seen.add(of)
392
393 fullcopy[f] = of # remember for dir rename detection
394 if of not in m2:
395 continue # no match, keep looking
396 if m2[of] == ma.get(of):
397 break # no merge needed, quit early
398 c2 = ctx(of, m2[of])
399 cr = _related(oc, c2, ca.rev())
400 if cr and (of == f or of == c2.path()): # non-divergent
401 copy[f] = of
402 of = None
403 break
404
405 if of in ma:
406 diverge.setdefault(of, []).append(f)
General Comments 0
You need to be logged in to leave comments. Login now