comparison mercurial/copies.py @ 24415:1cfded2fa1a9

merge with stable
author Matt Mackall <mpm@selenic.com>
date Fri, 20 Mar 2015 17:30:38 -0500
parents ce847603040b 9372180b8c9b
children 2cebf17c0fcc
comparison
equal deleted inserted replaced
24414:f247fbfe07f3 24415:1cfded2fa1a9
264 return {}, {}, {}, {} 264 return {}, {}, {}, {}
265 m1 = c1.manifest() 265 m1 = c1.manifest()
266 m2 = c2.manifest() 266 m2 = c2.manifest()
267 ma = ca.manifest() 267 ma = ca.manifest()
268 268
269 def makectx(f, n): 269
270 if len(n) != 20: # in a working context? 270 def setupctx(ctx):
271 if c1.rev() is None: 271 """return a 'makectx' function suitable for checkcopies usage from ctx
272 return c1.filectx(f) 272
273 return c2.filectx(f) 273 We have to re-setup the function building 'filectx' for each
274 return repo.filectx(f, fileid=n) 274 'checkcopies' to ensure the linkrev adjustement is properly setup for
275 275 each. Linkrev adjustment is important to avoid bug in rename
276 ctx = util.lrucachefunc(makectx) 276 detection. Moreover, having a proper '_ancestrycontext' setup ensures
277 the performance impact of this adjustment is kept limited. Without it,
278 each file could do a full dag traversal making the time complexity of
279 the operation explode (see issue4537).
280
281 This function exists here mostly to limit the impact on stable. Feel
282 free to refactor on default.
283 """
284 rev = ctx.rev()
285 ac = getattr(ctx, '_ancestrycontext', None)
286 if ac is None:
287 revs = [rev]
288 if rev is None:
289 revs = [p.rev() for p in ctx.parents()]
290 ac = ctx._repo.changelog.ancestors(revs, inclusive=True)
291 ctx._ancestrycontext = ac
292 def makectx(f, n):
293 if len(n) != 20: # in a working context?
294 if c1.rev() is None:
295 return c1.filectx(f)
296 return c2.filectx(f)
297 fctx = repo.filectx(f, fileid=n)
298 # setup only needed for filectx not create from a changectx
299 fctx._ancestrycontext = ac
300 fctx._descendantrev = rev
301 return fctx
302 return util.lrucachefunc(makectx)
303
277 copy = {} 304 copy = {}
278 movewithdir = {} 305 movewithdir = {}
279 fullcopy = {} 306 fullcopy = {}
280 diverge = {} 307 diverge = {}
281 308
284 addedinm1 = m1.filesnotin(ma) 311 addedinm1 = m1.filesnotin(ma)
285 addedinm2 = m2.filesnotin(ma) 312 addedinm2 = m2.filesnotin(ma)
286 u1, u2 = _computenonoverlap(repo, m1, m2, addedinm1, addedinm2) 313 u1, u2 = _computenonoverlap(repo, m1, m2, addedinm1, addedinm2)
287 314
288 for f in u1: 315 for f in u1:
316 ctx = setupctx(c1)
289 checkcopies(ctx, f, m1, m2, ca, limit, diverge, copy, fullcopy) 317 checkcopies(ctx, f, m1, m2, ca, limit, diverge, copy, fullcopy)
290 318
291 for f in u2: 319 for f in u2:
320 ctx = setupctx(c2)
292 checkcopies(ctx, f, m2, m1, ca, limit, diverge, copy, fullcopy) 321 checkcopies(ctx, f, m2, m1, ca, limit, diverge, copy, fullcopy)
293 322
294 renamedelete = {} 323 renamedelete = {}
295 renamedelete2 = set() 324 renamedelete2 = set()
296 diverge2 = set() 325 diverge2 = set()
309 if bothnew: 338 if bothnew:
310 repo.ui.debug(" unmatched files new in both:\n %s\n" 339 repo.ui.debug(" unmatched files new in both:\n %s\n"
311 % "\n ".join(bothnew)) 340 % "\n ".join(bothnew))
312 bothdiverge, _copy, _fullcopy = {}, {}, {} 341 bothdiverge, _copy, _fullcopy = {}, {}, {}
313 for f in bothnew: 342 for f in bothnew:
343 ctx = setupctx(c1)
314 checkcopies(ctx, f, m1, m2, ca, limit, bothdiverge, _copy, _fullcopy) 344 checkcopies(ctx, f, m1, m2, ca, limit, bothdiverge, _copy, _fullcopy)
345 ctx = setupctx(c2)
315 checkcopies(ctx, f, m2, m1, ca, limit, bothdiverge, _copy, _fullcopy) 346 checkcopies(ctx, f, m2, m1, ca, limit, bothdiverge, _copy, _fullcopy)
316 for of, fl in bothdiverge.items(): 347 for of, fl in bothdiverge.items():
317 if len(fl) == 2 and fl[0] == fl[1]: 348 if len(fl) == 2 and fl[0] == fl[1]:
318 copy[fl[0]] = of # not actually divergent, just matching renames 349 copy[fl[0]] = of # not actually divergent, just matching renames
319 350