D7858: copies: replace duplicatecopies() by function that takes contexts

martinvonz (Martin von Zweigbergk) phabricator at mercurial-scm.org
Tue Jan 14 12:08:15 EST 2020


martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  The callers mostly have context objects, so let's avoid looking up the
  same context objects inside `duplicatecopies()`.
  
  I also renamed the function to `graftcopies()` since I think that
  better matches its purpose. I did it in the same commit so it's easier
  for extensions to switch between the functions.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  hgext/fix.py
  hgext/rebase.py
  mercurial/copies.py
  mercurial/merge.py
  relnotes/next

CHANGE DETAILS

diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -28,3 +28,7 @@
    * `n in revlog.nodemap` becomes `revlog.index.has_node(n)`,
    * `revlog.nodemap[n]` becomes `revlog.index.rev(n)`,
    * `revlog.nodemap.get(n)` becomes `revlog.index.get_rev(n)`.
+
+ * `copies.duplicatecopies()` was renamed to
+   `copies.graftcopies()`. Its arguments changed from revision numbers
+   to context objects.
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -2635,7 +2635,7 @@
         repo.setparents(pctx.node(), pother)
         repo.dirstate.write(repo.currenttransaction())
         # fix up dirstate for copies and renames
-        copies.duplicatecopies(repo, wctx, ctx.rev(), base.rev())
+        copies.graftcopies(repo, wctx, ctx, base)
     return stats
 
 
diff --git a/mercurial/copies.py b/mercurial/copies.py
--- a/mercurial/copies.py
+++ b/mercurial/copies.py
@@ -856,26 +856,26 @@
         return False
 
 
-def duplicatecopies(repo, wctx, rev, fromrev, skiprev=None):
-    """reproduce copies from fromrev to rev in the dirstate
+def graftcopies(repo, wctx, ctx, base, skip=None):
+    """reproduce copies between base and ctx in the wctx
 
-    If skiprev is specified, it's a revision that should be used to
-    filter copy records. Any copies that occur between fromrev and
-    skiprev will not be duplicated, even if they appear in the set of
-    copies between fromrev and rev.
+    If skip is specified, it's a revision that should be used to
+    filter copy records. Any copies that occur between base and
+    skip will not be duplicated, even if they appear in the set of
+    copies between base and ctx.
     """
     exclude = {}
     ctraceconfig = repo.ui.config(b'experimental', b'copytrace')
     bctrace = stringutil.parsebool(ctraceconfig)
-    if skiprev is not None and (
+    if skip is not None and (
         ctraceconfig == b'heuristics' or bctrace or bctrace is None
     ):
         # copytrace='off' skips this line, but not the entire function because
         # the line below is O(size of the repo) during a rebase, while the rest
         # of the function is much faster (and is required for carrying copy
         # metadata across the rebase anyway).
-        exclude = pathcopies(repo[fromrev], repo[skiprev])
-    for dst, src in pycompat.iteritems(pathcopies(repo[fromrev], repo[rev])):
+        exclude = pathcopies(base, skip)
+    for dst, src in pycompat.iteritems(pathcopies(base, ctx)):
         if dst in exclude:
             continue
         if dst in wctx:
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -1481,7 +1481,8 @@
         # as well as other data we litter on it in other places.
         wctx = repo[None]
         repo.dirstate.write(repo.currenttransaction())
-    repo.ui.debug(b" merge against %d:%s\n" % (rev, repo[rev]))
+    ctx = repo[rev]
+    repo.ui.debug(b" merge against %d:%s\n" % (rev, ctx))
     if base is not None:
         repo.ui.debug(b"   detach base %d:%s\n" % (base, repo[base]))
     # When collapsing in-place, the parent is the common ancestor, we
@@ -1496,16 +1497,16 @@
         labels=[b'dest', b'source'],
         wc=wctx,
     )
+    destctx = repo[dest]
     if collapse:
-        copies.duplicatecopies(repo, wctx, rev, dest)
+        copies.graftcopies(repo, wctx, ctx, destctx)
     else:
         # If we're not using --collapse, we need to
         # duplicate copies between the revision we're
         # rebasing and its first parent, but *not*
         # duplicate any copies that have already been
         # performed in the destination.
-        p1rev = repo[rev].p1().rev()
-        copies.duplicatecopies(repo, wctx, rev, p1rev, skiprev=dest)
+        copies.graftcopies(repo, wctx, ctx, ctx.p1(), skip=destctx)
     return stats
 
 
diff --git a/hgext/fix.py b/hgext/fix.py
--- a/hgext/fix.py
+++ b/hgext/fix.py
@@ -734,7 +734,8 @@
     extra[b'fix_source'] = ctx.hex()
 
     wctx = context.overlayworkingctx(repo)
-    wctx.setbase(repo[newp1node])
+    newp1ctx = repo[newp1node]
+    wctx.setbase(newp1ctx)
     merge.update(
         repo,
         ctx.rev(),
@@ -744,9 +745,7 @@
         mergeancestor=False,
         wc=wctx,
     )
-    copies.duplicatecopies(
-        repo, wctx, ctx.rev(), ctx.p1().rev(), skiprev=newp1node
-    )
+    copies.graftcopies(repo, wctx, ctx, ctx.p1(), skip=newp1ctx)
 
     for path in filedata.keys():
         fctx = ctx[path]



To: martinvonz, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list