comparison mercurial/copies.py @ 46159:929054848d6c

copies: properly match result during changeset centric copy tracing By filtering "during" the iteration we were excluding rename information that were not in the matched set but that file served as base information for the matched set. We now do all copy tracing matching at the end of the process to ensure we raise proper result. If we were aggregating information top down instead of bottom up we could do filtering during processing. However, we don't. Differential Revision: https://phab.mercurial-scm.org/D9585
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Sun, 13 Dec 2020 20:16:34 +0100
parents 1fcfff09cac5
children 3a0c41336961
comparison
equal deleted inserted replaced
46158:1fcfff09cac5 46159:929054848d6c
194 194
195 HASCOPIESINFO = flagutil.REVIDX_HASCOPIESINFO 195 HASCOPIESINFO = flagutil.REVIDX_HASCOPIESINFO
196 196
197 changelogrevision = cl.changelogrevision 197 changelogrevision = cl.changelogrevision
198 198
199 alwaysmatch = match.always() 199 if rustmod is not None:
200
201 if rustmod is not None and alwaysmatch:
202 200
203 def revinfo(rev): 201 def revinfo(rev):
204 p1, p2 = parents(rev) 202 p1, p2 = parents(rev)
205 if flags(rev) & HASCOPIESINFO: 203 if flags(rev) & HASCOPIESINFO:
206 raw = changelogrevision(rev)._sidedata.get(sidedatamod.SD_FILES) 204 raw = changelogrevision(rev)._sidedata.get(sidedatamod.SD_FILES)
354 It returns the aggregated copies information for `targetrev`. 352 It returns the aggregated copies information for `targetrev`.
355 """ 353 """
356 354
357 alwaysmatch = match.always() 355 alwaysmatch = match.always()
358 356
359 if rustmod is not None and alwaysmatch: 357 if rustmod is not None:
360 final_copies = rustmod.combine_changeset_copies( 358 final_copies = rustmod.combine_changeset_copies(
361 list(revs), children_count, targetrev, revinfo, isancestor 359 list(revs), children_count, targetrev, revinfo, isancestor
362 ) 360 )
363 else: 361 else:
364 isancestor = cached_is_ancestor(isancestor) 362 isancestor = cached_is_ancestor(isancestor)
394 if parent == 1: 392 if parent == 1:
395 childcopies = changes.copied_from_p1 393 childcopies = changes.copied_from_p1
396 elif parent == 2: 394 elif parent == 2:
397 childcopies = changes.copied_from_p2 395 childcopies = changes.copied_from_p2
398 396
399 if not alwaysmatch:
400 childcopies = {
401 dst: src
402 for dst, src in childcopies.items()
403 if match(dst)
404 }
405 if childcopies: 397 if childcopies:
406 newcopies = copies.copy() 398 newcopies = copies.copy()
407 for dest, source in pycompat.iteritems(childcopies): 399 for dest, source in pycompat.iteritems(childcopies):
408 prev = copies.get(source) 400 prev = copies.get(source)
409 if prev is not None and prev[1] is not None: 401 if prev is not None and prev[1] is not None:
445 # filter out internal details and return a {dest: source mapping} 437 # filter out internal details and return a {dest: source mapping}
446 final_copies = {} 438 final_copies = {}
447 for dest, (tt, source) in all_copies[targetrev].items(): 439 for dest, (tt, source) in all_copies[targetrev].items():
448 if source is not None: 440 if source is not None:
449 final_copies[dest] = source 441 final_copies[dest] = source
442 if not alwaysmatch:
443 for filename in list(final_copies.keys()):
444 if not match(filename):
445 del final_copies[filename]
450 return final_copies 446 return final_copies
451 447
452 448
453 def _merge_copies_dict(minor, major, isancestor, changes): 449 def _merge_copies_dict(minor, major, isancestor, changes):
454 """merge two copies-mapping together, minor and major 450 """merge two copies-mapping together, minor and major