--- a/mercurial/copies.py Wed Dec 02 15:37:54 2020 +0100
+++ b/mercurial/copies.py Sun Dec 13 20:26:27 2020 +0100
@@ -357,98 +357,96 @@
alwaysmatch = match.always()
if rustmod is not None and alwaysmatch:
- return rustmod.combine_changeset_copies(
+ final_copies = rustmod.combine_changeset_copies(
list(revs), children_count, targetrev, revinfo, isancestor
)
-
- isancestor = cached_is_ancestor(isancestor)
-
- all_copies = {}
- # iterate over all the "children" side of copy tracing "edge"
- for current_rev in revs:
- p1, p2, changes = revinfo(current_rev)
- current_copies = None
+ else:
+ isancestor = cached_is_ancestor(isancestor)
- # iterate over all parents to chain the existing data with the
- # data from the parent → child edge.
- for parent, parent_rev in ((1, p1), (2, p2)):
- if parent_rev == nullrev:
- continue
- remaining_children = children_count.get(parent_rev)
- if remaining_children is None:
- continue
- remaining_children -= 1
- children_count[parent_rev] = remaining_children
- if remaining_children:
- copies = all_copies.get(parent_rev, None)
- else:
- copies = all_copies.pop(parent_rev, None)
+ all_copies = {}
+ # iterate over all the "children" side of copy tracing "edge"
+ for current_rev in revs:
+ p1, p2, changes = revinfo(current_rev)
+ current_copies = None
+ # iterate over all parents to chain the existing data with the
+ # data from the parent → child edge.
+ for parent, parent_rev in ((1, p1), (2, p2)):
+ if parent_rev == nullrev:
+ continue
+ remaining_children = children_count.get(parent_rev)
+ if remaining_children is None:
+ continue
+ remaining_children -= 1
+ children_count[parent_rev] = remaining_children
+ if remaining_children:
+ copies = all_copies.get(parent_rev, None)
+ else:
+ copies = all_copies.pop(parent_rev, None)
- if copies is None:
- # this is a root
- copies = {}
+ if copies is None:
+ # this is a root
+ copies = {}
- newcopies = copies
- # chain the data in the edge with the existing data
- if changes is not None:
- childcopies = {}
- if parent == 1:
- childcopies = changes.copied_from_p1
- elif parent == 2:
- childcopies = changes.copied_from_p2
+ newcopies = copies
+ # chain the data in the edge with the existing data
+ if changes is not None:
+ childcopies = {}
+ if parent == 1:
+ childcopies = changes.copied_from_p1
+ elif parent == 2:
+ childcopies = changes.copied_from_p2
- if not alwaysmatch:
- childcopies = {
- dst: src
- for dst, src in childcopies.items()
- if match(dst)
- }
- if childcopies:
- newcopies = copies.copy()
- for dest, source in pycompat.iteritems(childcopies):
- prev = copies.get(source)
- if prev is not None and prev[1] is not None:
- source = prev[1]
- newcopies[dest] = (current_rev, source)
- assert newcopies is not copies
- if changes.removed:
- if newcopies is copies:
+ if not alwaysmatch:
+ childcopies = {
+ dst: src
+ for dst, src in childcopies.items()
+ if match(dst)
+ }
+ if childcopies:
newcopies = copies.copy()
- for f in changes.removed:
- if f in newcopies:
- if newcopies is copies:
- # copy on write to avoid affecting potential other
- # branches. when there are no other branches, this
- # could be avoided.
- newcopies = copies.copy()
- newcopies[f] = (current_rev, None)
+ for dest, source in pycompat.iteritems(childcopies):
+ prev = copies.get(source)
+ if prev is not None and prev[1] is not None:
+ source = prev[1]
+ newcopies[dest] = (current_rev, source)
+ assert newcopies is not copies
+ if changes.removed:
+ if newcopies is copies:
+ newcopies = copies.copy()
+ for f in changes.removed:
+ if f in newcopies:
+ if newcopies is copies:
+ # copy on write to avoid affecting potential other
+ # branches. when there are no other branches, this
+ # could be avoided.
+ newcopies = copies.copy()
+ newcopies[f] = (current_rev, None)
+ # check potential need to combine the data from another parent (for
+ # that child). See comment below for details.
+ if current_copies is None:
+ current_copies = newcopies
+ elif current_copies is newcopies:
+ # nothing to merge:
+ pass
+ else:
+ # we are the second parent to work on c, we need to merge our
+ # work with the other.
+ #
+ # In case of conflict, parent 1 take precedence over parent 2.
+ # This is an arbitrary choice made anew when implementing
+ # changeset based copies. It was made without regards with
+ # potential filelog related behavior.
+ assert parent == 2
+ current_copies = _merge_copies_dict(
+ newcopies, current_copies, isancestor, changes
+ )
+ all_copies[current_rev] = current_copies
- # check potential need to combine the data from another parent (for
- # that child). See comment below for details.
- if current_copies is None:
- current_copies = newcopies
- elif current_copies is newcopies:
- # nothing to merge:
- pass
- else:
- # we are the second parent to work on c, we need to merge our
- # work with the other.
- #
- # In case of conflict, parent 1 take precedence over parent 2.
- # This is an arbitrary choice made anew when implementing
- # changeset based copies. It was made without regards with
- # potential filelog related behavior.
- assert parent == 2
- current_copies = _merge_copies_dict(
- newcopies, current_copies, isancestor, changes
- )
- all_copies[current_rev] = current_copies
-
- # filter out internal details and return a {dest: source mapping}
- final_copies = {}
- for dest, (tt, source) in all_copies[targetrev].items():
- if source is not None:
- final_copies[dest] = source
+ # filter out internal details and return a {dest: source mapping}
+ final_copies = {}
+ for dest, (tt, source) in all_copies[targetrev].items():
+ if source is not None:
+ final_copies[dest] = source
return final_copies