Patchwork D9117: copies: directly pass a changes object to the copy tracing code

login
register
mail settings
Submitter phabricator
Date Sept. 28, 2020, 4:33 p.m.
Message ID <differential-rev-PHID-DREV-tj47jt6e66usrhduh3zj-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47332/
State Superseded
Headers show

Comments

phabricator - Sept. 28, 2020, 4:33 p.m.
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  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 <https://phab.mercurial-scm.org/rHG4b582a93316a23263b6e815f8e8ad0c0f56d01de> and
  14be07d5603c <https://phab.mercurial-scm.org/rHG14be07d5603c10df913dd48cd2392e565f0f29aa> for details.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9117

AFFECTED FILES
  mercurial/copies.py

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/mercurial/copies.py b/mercurial/copies.py
--- a/mercurial/copies.py
+++ b/mercurial/copies.py
@@ -171,34 +171,15 @@ 
 
 
 def _revinfo_getter(repo):
-    """return a function that return multiple data given a <rev>"i
+    """return a function that return multiple 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 ChangingGiles 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