comparison mercurial/copies.py @ 46161:3a0c41336961

copies: extract value comparison in the python copy tracing This mirror what we did in the Rust code. This is useful to prepare rework for this comparison logic that we will need to handle more advanced chaining cases (when merges are chained). Differential Revision: https://phab.mercurial-scm.org/D9590
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Mon, 14 Dec 2020 01:30:32 +0100
parents 929054848d6c
children 6b9d65298484
comparison
equal deleted inserted replaced
46160:1d6aac94e6d5 46161:3a0c41336961
444 if not match(filename): 444 if not match(filename):
445 del final_copies[filename] 445 del final_copies[filename]
446 return final_copies 446 return final_copies
447 447
448 448
449 # constant to decide which side to pick with _merge_copies_dict
450 PICK_MINOR = 0
451 PICK_MAJOR = 1
452 PICK_EITHER = 2
453
454
449 def _merge_copies_dict(minor, major, isancestor, changes): 455 def _merge_copies_dict(minor, major, isancestor, changes):
450 """merge two copies-mapping together, minor and major 456 """merge two copies-mapping together, minor and major
451 457
452 In case of conflict, value from "major" will be picked. 458 In case of conflict, value from "major" will be picked.
453 459
462 for dest, value in major.items(): 468 for dest, value in major.items():
463 other = minor.get(dest) 469 other = minor.get(dest)
464 if other is None: 470 if other is None:
465 minor[dest] = value 471 minor[dest] = value
466 else: 472 else:
467 new_tt = value[0] 473 pick = _compare_values(changes, isancestor, dest, other, value)
468 other_tt = other[0] 474 if pick == PICK_MAJOR:
469 if value[1] == other[1]:
470 continue
471 # content from "major" wins, unless it is older
472 # than the branch point or there is a merge
473 if new_tt == other_tt:
474 minor[dest] = value 475 minor[dest] = value
475 elif (
476 changes is not None
477 and value[1] is None
478 and dest in changes.salvaged
479 ):
480 pass
481 elif (
482 changes is not None
483 and other[1] is None
484 and dest in changes.salvaged
485 ):
486 minor[dest] = value
487 elif changes is not None and dest in changes.merged:
488 minor[dest] = value
489 elif not isancestor(new_tt, other_tt):
490 if value[1] is not None:
491 minor[dest] = value
492 elif isancestor(other_tt, new_tt):
493 minor[dest] = value
494 return minor 476 return minor
477
478
479 def _compare_values(changes, isancestor, dest, other, value):
480 """compare two value within a _merge_copies_dict loop iteration"""
481 new_tt = value[0]
482 other_tt = other[0]
483
484 if value[1] == other[1]:
485 return PICK_EITHER
486 # content from "major" wins, unless it is older
487 # than the branch point or there is a merge
488 if new_tt == other_tt:
489 return PICK_MAJOR
490 elif changes is not None and value[1] is None and dest in changes.salvaged:
491 return PICK_MINOR
492 elif changes is not None and other[1] is None and dest in changes.salvaged:
493 return PICK_MAJOR
494 elif changes is not None and dest in changes.merged:
495 return PICK_MAJOR
496 elif not isancestor(new_tt, other_tt):
497 if value[1] is not None:
498 return PICK_MAJOR
499 elif isancestor(other_tt, new_tt):
500 return PICK_MAJOR
501 return PICK_MINOR
495 502
496 503
497 def _revinfo_getter_extra(repo): 504 def _revinfo_getter_extra(repo):
498 """return a function that return multiple data given a <rev>"i 505 """return a function that return multiple data given a <rev>"i
499 506