D4193: changegroup: pass clrevtolocalrev to each group

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Thu Aug 9 18:52:27 UTC 2018


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

REVISION SUMMARY
  clrevtolocalrev is a per-changegroup group mapping revisions to
  aid with shallow clone.
  
  Back when this functionality was implemented in an extension, this
  dict was added to the packer instance so monkeypatched functions
  could reference it there. Now that this code is part of core, we
  can pass the dict to each consumer properly so it doesn't have to
  live on the cgpacker instance. This commit does that.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/changegroup.py

CHANGE DETAILS

diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -658,17 +658,11 @@
         else:
             self._verbosenote = lambda s: None
 
-        # Maps CL revs to per-revlog revisions. Cleared in close() at
-        # the end of each group.
-        self._clrevtolocalrev = {}
-
     def _close(self):
-        # Ellipses serving mode.
-        self._clrevtolocalrev.clear()
-
         return closechunk()
 
-    def group(self, revs, store, ischangelog, lookup, units=None):
+    def group(self, revs, store, ischangelog, lookup, units=None,
+              clrevtolocalrev=None):
         """Calculate a delta group, yielding a sequence of changegroup chunks
         (strings).
 
@@ -706,7 +700,7 @@
 
             if self._ellipses:
                 linkrev = cl.rev(linknode)
-                self._clrevtolocalrev[linkrev] = curr
+                clrevtolocalrev[linkrev] = curr
 
                 # This is a node to send in full, because the changeset it
                 # corresponds to was a full changeset.
@@ -717,7 +711,8 @@
                     delta = None
                 else:
                     delta = self._revisiondeltanarrow(store, ischangelog,
-                                                      curr, linkrev, linknode)
+                                                      curr, linkrev, linknode,
+                                                      clrevtolocalrev)
             else:
                 delta = _revisiondeltanormal(store, curr, prev, linknode,
                                              self._deltaparentfn)
@@ -746,7 +741,8 @@
         rr, rl = store.rev, store.linkrev
         return [n for n in missing if rl(rr(n)) not in commonrevs]
 
-    def _packmanifests(self, dir, dirlog, revs, lookuplinknode):
+    def _packmanifests(self, dir, dirlog, revs, lookuplinknode,
+                       clrevtolocalrev):
         """Pack manifests into a changegroup stream.
 
         Encodes the directory name in the output so multiple manifests
@@ -757,7 +753,8 @@
             yield _fileheader(dir)
 
         for chunk in self.group(revs, dirlog, False, lookuplinknode,
-                                units=_('manifests')):
+                                units=_('manifests'),
+                                clrevtolocalrev=clrevtolocalrev):
             yield chunk
 
     def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
@@ -780,9 +777,6 @@
         mfs = clstate['mfs']
         changedfiles = clstate['changedfiles']
 
-        if self._ellipses:
-            self._clrevtolocalrev = clstate['clrevtomanifestrev']
-
         # We need to make sure that the linkrev in the changegroup refers to
         # the first changeset that introduced the manifest or file revision.
         # The fastpath is usually safer than the slowpath, because the filelogs
@@ -808,7 +802,8 @@
         fnodes = {}  # needed file nodes
 
         for chunk in self.generatemanifests(commonrevs, clrevorder,
-                fastpathlinkrev, mfs, fnodes, source):
+                fastpathlinkrev, mfs, fnodes, source,
+                clstate['clrevtomanifestrev']):
             yield chunk
 
         mfdicts = None
@@ -895,12 +890,13 @@
             'clrevtomanifestrev': clrevtomanifestrev,
         }
 
-        gen = self.group(revs, cl, True, lookupcl, units=_('changesets'))
+        gen = self.group(revs, cl, True, lookupcl, units=_('changesets'),
+                         clrevtolocalrev={})
 
         return state, gen
 
     def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs,
-                          fnodes, source):
+                          fnodes, source, clrevtolocalrev):
         """Returns an iterator of changegroup chunks containing manifests.
 
         `source` is unused here, but is used by extensions like remotefilelog to
@@ -969,7 +965,8 @@
                     revs = _sortnodesnormal(store, prunednodes,
                                             self._reorder)
 
-                for x in self._packmanifests(dir, store, revs, lookupfn):
+                for x in self._packmanifests(dir, store, revs, lookupfn,
+                                             clrevtolocalrev):
                     size += len(x)
                     yield x
         self._verbosenote(_('%8.i (manifests)\n') % size)
@@ -993,6 +990,8 @@
                 return dict((fnode(r), cln(lr))
                             for r, lr in revs if lr in clrevs)
 
+        clrevtolocalrev = {}
+
         if self._isshallow:
             # In a shallow clone, the linknodes callback needs to also include
             # those file nodes that are in the manifests we sent but weren't
@@ -1007,7 +1006,7 @@
                 for c in commonctxs:
                     try:
                         fnode = c.filenode(fname)
-                        self._clrevtolocalrev[c.rev()] = flog.rev(fnode)
+                        clrevtolocalrev[c.rev()] = flog.rev(fnode)
                     except error.ManifestLookupError:
                         pass
                 links = normallinknodes(flog, fname)
@@ -1032,6 +1031,8 @@
                 raise error.Abort(_("empty or missing file data for %s") %
                                   fname)
 
+            clrevtolocalrev.clear()
+
             linkrevnodes = linknodes(filerevlog, fname)
             # Lookup for filenodes, we collected the linkrev nodes above in the
             # fastpath case and with lookupmf in the slowpath case.
@@ -1051,13 +1052,15 @@
                 h = _fileheader(fname)
                 size = len(h)
                 yield h
-                for chunk in self.group(revs, filerevlog, False, lookupfilelog):
+                for chunk in self.group(revs, filerevlog, False, lookupfilelog,
+                                        clrevtolocalrev=clrevtolocalrev):
                     size += len(chunk)
                     yield chunk
                 self._verbosenote(_('%8.i  %s\n') % (size, fname))
         progress.complete()
 
-    def _revisiondeltanarrow(self, store, ischangelog, rev, linkrev, linknode):
+    def _revisiondeltanarrow(self, store, ischangelog, rev, linkrev, linknode,
+                             clrevtolocalrev):
         linkparents = self._precomputedellipsis[linkrev]
         def local(clrev):
             """Turn a changelog revnum into a local revnum.
@@ -1089,8 +1092,8 @@
             while walk:
                 p = walk[0]
                 walk = walk[1:]
-                if p in self._clrevtolocalrev:
-                    return self._clrevtolocalrev[p]
+                if p in clrevtolocalrev:
+                    return clrevtolocalrev[p]
                 elif p in self._fullclnodes:
                     walk.extend([pp for pp in self._repo.changelog.parentrevs(p)
                                     if pp != nullrev])



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


More information about the Mercurial-devel mailing list