changeset 45642:2693659c2b34

copies: directly pass a changes object to the copy tracing code The object contains all the data we need. For example, the `is_merged` callback can now use the associated precomputed data. This will be useful again soon when the `salvaged` set will be introduce to solve the issue with delete file reverted during a merge. See 4b582a93316a and 14be07d5603c for details. Differential Revision: https://phab.mercurial-scm.org/D9117
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Fri, 25 Sep 2020 15:05:08 +0200
parents 7a757e893532
children 65cb924a1430
files mercurial/copies.py
diffstat 1 files changed, 12 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/copies.py	Fri Sep 25 14:54:43 2020 +0200
+++ b/mercurial/copies.py	Fri Sep 25 15:05:08 2020 +0200
@@ -171,34 +171,15 @@
 
 
 def _revinfo_getter(repo):
-    """return a function that return multiple data given a <rev>"i
+    """returns a function that returns the following data given a <rev>"
 
     * p1: revision number of first parent
     * p2: revision number of first parent
-    * p1copies: mapping of copies from p1
-    * p2copies: mapping of copies from p2
-    * removed: a list of removed files
-    * ismerged: a callback to know if file was merged in that revision
+    * changes: a ChangingFiles object
     """
     cl = repo.changelog
     parents = cl.parentrevs
 
-    def get_ismerged(rev):
-        ctx = repo[rev]
-
-        def ismerged(path):
-            if path not in ctx.files():
-                return False
-            fctx = ctx[path]
-            parents = fctx._filelog.parents(fctx._filenode)
-            nb_parents = 0
-            for n in parents:
-                if n != node.nullid:
-                    nb_parents += 1
-            return nb_parents >= 2
-
-        return ismerged
-
     changelogrevision = cl.changelogrevision
 
     # A small cache to avoid doing the work twice for merges
@@ -232,23 +213,10 @@
         e = merge_caches.pop(rev, None)
         if e is not None:
             return e
-        c = changelogrevision(rev)
-        p1copies = c.p1copies
-        p2copies = c.p2copies
-        removed = c.filesremoved
+        value = (p1, p2, changelogrevision(rev).changes)
         if p1 != node.nullrev and p2 != node.nullrev:
             # XXX some case we over cache, IGNORE
-            value = merge_caches[rev] = (
-                p1,
-                p2,
-                p1copies,
-                p2copies,
-                removed,
-                get_ismerged(rev),
-            )
-
-        if value is None:
-            value = (p1, p2, p1copies, p2copies, removed, get_ismerged(rev))
+            merge_caches[rev] = value
         return value
 
     return revinfo
@@ -324,14 +292,14 @@
             # this is a root
             copies = {}
         for i, c in enumerate(children[r]):
-            p1, p2, p1copies, p2copies, removed, ismerged = revinfo(c)
+            p1, p2, changes = revinfo(c)
             if r == p1:
                 parent = 1
-                childcopies = p1copies
+                childcopies = changes.copied_from_p1
             else:
                 assert r == p2
                 parent = 2
-                childcopies = p2copies
+                childcopies = changes.copied_from_p2
             if not alwaysmatch:
                 childcopies = {
                     dst: src for dst, src in childcopies.items() if match(dst)
@@ -345,7 +313,7 @@
                         source = prev[1]
                     newcopies[dest] = (c, source)
                 assert newcopies is not copies
-            for f in removed:
+            for f in changes.removed:
                 if f in newcopies:
                     if newcopies is copies:
                         # copy on write to avoid affecting potential other
@@ -366,11 +334,11 @@
                 # potential filelog related behavior.
                 if parent == 1:
                     _merge_copies_dict(
-                        othercopies, newcopies, isancestor, ismerged
+                        othercopies, newcopies, isancestor, changes
                     )
                 else:
                     _merge_copies_dict(
-                        newcopies, othercopies, isancestor, ismerged
+                        newcopies, othercopies, isancestor, changes
                     )
                     all_copies[c] = newcopies
 
@@ -381,7 +349,7 @@
     return final_copies
 
 
-def _merge_copies_dict(minor, major, isancestor, ismerged):
+def _merge_copies_dict(minor, major, isancestor, changes):
     """merge two copies-mapping together, minor and major
 
     In case of conflict, value from "major" will be picked.
@@ -406,7 +374,7 @@
             if (
                 new_tt == other_tt
                 or not isancestor(new_tt, other_tt)
-                or ismerged(dest)
+                or dest in changes.merged
             ):
                 minor[dest] = value