Mercurial > public > mercurial-scm > hg
comparison mercurial/copies.py @ 30202:a005c33d0bd7
mergecopies: add logic to process incomplete data
We first combine incomplete copies on the two sides of the topological CA
into complete copies.
Any leftover incomplete copies are then combined with the incomplete
divergences to reconstruct divergences spanning over the topological CA.
Finally we promote any divergences falsely flagged as incomplete to full
divergences.
Right now, there is nothing generating incomplete copy/divergence data,
so this code does nothing. Changes to _checkcopies to populate these
dicts are coming later in this series.
author | G?bor Stefanik <gabor.stefanik@nng.com> |
---|---|
date | Tue, 04 Oct 2016 12:51:54 +0200 |
parents | 856ead835f56 |
children | b94b92f0c683 |
comparison
equal
deleted
inserted
replaced
30201:856ead835f56 | 30202:a005c33d0bd7 |
---|---|
287 fctx._ancestrycontext = ac | 287 fctx._ancestrycontext = ac |
288 fctx._descendantrev = rev | 288 fctx._descendantrev = rev |
289 return fctx | 289 return fctx |
290 return util.lrucachefunc(makectx) | 290 return util.lrucachefunc(makectx) |
291 | 291 |
292 def _combinecopies(copyfrom, copyto, finalcopy, diverge, incompletediverge): | |
293 """combine partial copy paths""" | |
294 remainder = {} | |
295 for f in copyfrom: | |
296 if f in copyto: | |
297 finalcopy[copyto[f]] = copyfrom[f] | |
298 del copyto[f] | |
299 for f in incompletediverge: | |
300 assert f not in diverge | |
301 ic = incompletediverge[f] | |
302 if ic[0] in copyto: | |
303 diverge[f] = [copyto[ic[0]], ic[1]] | |
304 else: | |
305 remainder[f] = ic | |
306 return remainder | |
307 | |
292 def mergecopies(repo, c1, c2, base): | 308 def mergecopies(repo, c1, c2, base): |
293 """ | 309 """ |
294 Find moves and copies between context c1 and c2 that are relevant | 310 Find moves and copies between context c1 and c2 that are relevant |
295 for merging. 'base' will be used as the merge base. | 311 for merging. 'base' will be used as the merge base. |
296 | 312 |
358 | 374 |
359 # gather data from _checkcopies: | 375 # gather data from _checkcopies: |
360 # - diverge = record all diverges in this dict | 376 # - diverge = record all diverges in this dict |
361 # - copy = record all non-divergent copies in this dict | 377 # - copy = record all non-divergent copies in this dict |
362 # - fullcopy = record all copies in this dict | 378 # - fullcopy = record all copies in this dict |
379 # - incomplete = record non-divergent partial copies here | |
380 # - incompletediverge = record divergent partial copies here | |
363 diverge = {} # divergence data is shared | 381 diverge = {} # divergence data is shared |
382 incompletediverge = {} | |
364 data1 = {'copy': {}, | 383 data1 = {'copy': {}, |
365 'fullcopy': {}, | 384 'fullcopy': {}, |
385 'incomplete': {}, | |
366 'diverge': diverge, | 386 'diverge': diverge, |
387 'incompletediverge': incompletediverge, | |
367 } | 388 } |
368 data2 = {'copy': {}, | 389 data2 = {'copy': {}, |
369 'fullcopy': {}, | 390 'fullcopy': {}, |
391 'incomplete': {}, | |
370 'diverge': diverge, | 392 'diverge': diverge, |
393 'incompletediverge': incompletediverge, | |
371 } | 394 } |
372 | 395 |
373 # find interesting file sets from manifests | 396 # find interesting file sets from manifests |
374 addedinm1 = m1.filesnotin(mb) | 397 addedinm1 = m1.filesnotin(mb) |
375 addedinm2 = m2.filesnotin(mb) | 398 addedinm2 = m2.filesnotin(mb) |
396 _checkcopies(c2, f, m2, m1, base, tca, limit, data2) | 419 _checkcopies(c2, f, m2, m1, base, tca, limit, data2) |
397 | 420 |
398 copy = dict(data1['copy'].items() + data2['copy'].items()) | 421 copy = dict(data1['copy'].items() + data2['copy'].items()) |
399 fullcopy = dict(data1['fullcopy'].items() + data2['fullcopy'].items()) | 422 fullcopy = dict(data1['fullcopy'].items() + data2['fullcopy'].items()) |
400 | 423 |
424 if dirtyc1: | |
425 _combinecopies(data2['incomplete'], data1['incomplete'], copy, diverge, | |
426 incompletediverge) | |
427 else: | |
428 _combinecopies(data1['incomplete'], data2['incomplete'], copy, diverge, | |
429 incompletediverge) | |
430 | |
401 renamedelete = {} | 431 renamedelete = {} |
402 renamedeleteset = set() | 432 renamedeleteset = set() |
403 divergeset = set() | 433 divergeset = set() |
404 for of, fl in diverge.items(): | 434 for of, fl in diverge.items(): |
405 if len(fl) == 1 or of in c1 or of in c2: | 435 if len(fl) == 1 or of in c1 or of in c2: |
414 | 444 |
415 if bothnew: | 445 if bothnew: |
416 repo.ui.debug(" unmatched files new in both:\n %s\n" | 446 repo.ui.debug(" unmatched files new in both:\n %s\n" |
417 % "\n ".join(bothnew)) | 447 % "\n ".join(bothnew)) |
418 bothdiverge = {} | 448 bothdiverge = {} |
419 bothdata = {'copy': {}, | 449 bothincompletediverge = {} |
420 'fullcopy': {}, | 450 both1 = {'copy': {}, |
421 'diverge': bothdiverge, | 451 'fullcopy': {}, |
422 } | 452 'incomplete': {}, |
453 'diverge': bothdiverge, | |
454 'incompletediverge': bothincompletediverge | |
455 } | |
456 both2 = {'copy': {}, | |
457 'fullcopy': {}, | |
458 'incomplete': {}, | |
459 'diverge': bothdiverge, | |
460 'incompletediverge': bothincompletediverge | |
461 } | |
423 for f in bothnew: | 462 for f in bothnew: |
424 _checkcopies(c1, f, m1, m2, base, tca, limit, bothdata) | 463 _checkcopies(c1, f, m1, m2, base, tca, limit, both1) |
425 _checkcopies(c2, f, m2, m1, base, tca, limit, bothdata) | 464 _checkcopies(c2, f, m2, m1, base, tca, limit, both2) |
465 if dirtyc1: | |
466 assert both2['incomplete'] == {} | |
467 remainder = _combinecopies({}, both1['incomplete'], copy, bothdiverge, | |
468 bothincompletediverge) | |
469 else: | |
470 assert both1['incomplete'] == {} | |
471 remainder = _combinecopies({}, both2['incomplete'], copy, bothdiverge, | |
472 bothincompletediverge) | |
473 for f in remainder: | |
474 assert f not in bothdiverge | |
475 ic = remainder[f] | |
476 if ic[0] in (m1 if dirtyc1 else m2): | |
477 # backed-out rename on one side, but watch out for deleted files | |
478 bothdiverge[f] = ic | |
426 for of, fl in bothdiverge.items(): | 479 for of, fl in bothdiverge.items(): |
427 if len(fl) == 2 and fl[0] == fl[1]: | 480 if len(fl) == 2 and fl[0] == fl[1]: |
428 copy[fl[0]] = of # not actually divergent, just matching renames | 481 copy[fl[0]] = of # not actually divergent, just matching renames |
429 | 482 |
430 if fullcopy and repo.ui.debugflag: | 483 if fullcopy and repo.ui.debugflag: |