Mercurial > hg
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 |