283 fctx._ancestrycontext = ac |
283 fctx._ancestrycontext = ac |
284 fctx._descendantrev = rev |
284 fctx._descendantrev = rev |
285 return fctx |
285 return fctx |
286 return util.lrucachefunc(makectx) |
286 return util.lrucachefunc(makectx) |
287 |
287 |
288 def mergecopies(repo, c1, c2, ca): |
288 def mergecopies(repo, c1, c2, base): |
289 """ |
289 """ |
290 Find moves and copies between context c1 and c2 that are relevant |
290 Find moves and copies between context c1 and c2 that are relevant |
291 for merging. |
291 for merging. 'base' will be used as the merge base. |
292 |
292 |
293 Returns four dicts: "copy", "movewithdir", "diverge", and |
293 Returns four dicts: "copy", "movewithdir", "diverge", and |
294 "renamedelete". |
294 "renamedelete". |
295 |
295 |
296 "copy" is a mapping from destination name -> source name, |
296 "copy" is a mapping from destination name -> source name, |
327 return {}, {}, {}, {} |
327 return {}, {}, {}, {} |
328 repo.ui.debug(" searching for copies back to rev %d\n" % limit) |
328 repo.ui.debug(" searching for copies back to rev %d\n" % limit) |
329 |
329 |
330 m1 = c1.manifest() |
330 m1 = c1.manifest() |
331 m2 = c2.manifest() |
331 m2 = c2.manifest() |
332 ma = ca.manifest() |
332 mb = base.manifest() |
333 |
333 |
334 # gather data from _checkcopies: |
334 # gather data from _checkcopies: |
335 # - diverge = record all diverges in this dict |
335 # - diverge = record all diverges in this dict |
336 # - copy = record all non-divergent copies in this dict |
336 # - copy = record all non-divergent copies in this dict |
337 # - fullcopy = record all copies in this dict |
337 # - fullcopy = record all copies in this dict |
344 'fullcopy': {}, |
344 'fullcopy': {}, |
345 'diverge': diverge, |
345 'diverge': diverge, |
346 } |
346 } |
347 |
347 |
348 # find interesting file sets from manifests |
348 # find interesting file sets from manifests |
349 addedinm1 = m1.filesnotin(ma) |
349 addedinm1 = m1.filesnotin(mb) |
350 addedinm2 = m2.filesnotin(ma) |
350 addedinm2 = m2.filesnotin(mb) |
351 u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2) |
351 u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2) |
352 u1u, u2u = u1r, u2r |
352 u1u, u2u = u1r, u2r |
353 bothnew = sorted(addedinm1 & addedinm2) |
353 bothnew = sorted(addedinm1 & addedinm2) |
354 |
354 |
355 for f in u1u: |
355 for f in u1u: |
356 _checkcopies(c1, f, m1, m2, ca, limit, data1) |
356 _checkcopies(c1, f, m1, m2, base, limit, data1) |
357 |
357 |
358 for f in u2u: |
358 for f in u2u: |
359 _checkcopies(c2, f, m2, m1, ca, limit, data2) |
359 _checkcopies(c2, f, m2, m1, base, limit, data2) |
360 |
360 |
361 copy = dict(data1['copy'].items() + data2['copy'].items()) |
361 copy = dict(data1['copy'].items() + data2['copy'].items()) |
362 fullcopy = dict(data1['fullcopy'].items() + data2['fullcopy'].items()) |
362 fullcopy = dict(data1['fullcopy'].items() + data2['fullcopy'].items()) |
363 |
363 |
364 renamedelete = {} |
364 renamedelete = {} |
382 bothdata = {'copy': {}, |
382 bothdata = {'copy': {}, |
383 'fullcopy': {}, |
383 'fullcopy': {}, |
384 'diverge': bothdiverge, |
384 'diverge': bothdiverge, |
385 } |
385 } |
386 for f in bothnew: |
386 for f in bothnew: |
387 _checkcopies(c1, f, m1, m2, ca, limit, bothdata) |
387 _checkcopies(c1, f, m1, m2, base, limit, bothdata) |
388 _checkcopies(c2, f, m2, m1, ca, limit, bothdata) |
388 _checkcopies(c2, f, m2, m1, base, limit, bothdata) |
389 for of, fl in bothdiverge.items(): |
389 for of, fl in bothdiverge.items(): |
390 if len(fl) == 2 and fl[0] == fl[1]: |
390 if len(fl) == 2 and fl[0] == fl[1]: |
391 copy[fl[0]] = of # not actually divergent, just matching renames |
391 copy[fl[0]] = of # not actually divergent, just matching renames |
392 |
392 |
393 if fullcopy and repo.ui.debugflag: |
393 if fullcopy and repo.ui.debugflag: |