[PATCH 6 of 9 changegroup-apis] changegroup: move code from changegroupsubset to changegroupemitter

Gregory Szorc gregory.szorc at gmail.com
Mon Aug 1 14:18:23 EDT 2016


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1469903240 25200
#      Sat Jul 30 11:27:20 2016 -0700
# Node ID 39ff601b7117aecdd41ec1cc1a3539063c100e99
# Parent  caf03d083a56111fc568735bd83c99150ae3be7f
changegroup: move code from changegroupsubset to changegroupemitter

We establish a "fromrootsandheads" helper API on changegroupemitter.
It contains the code from changegroupsubset. changegroupsubset has
been rewritten in terms of changegroupemitter.

diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -929,29 +929,20 @@ def changegroupsubset(repo, roots, heads
 
     It is fairly complex as determining which filenodes and which
     manifest nodes need to be included for the changeset to be complete
     is non-trivial.
 
     Another wrinkle is doing the reverse, figuring out which changeset in
     the changegroup a particular filenode or manifestnode belongs to.
     """
-    cl = repo.changelog
-    if not roots:
-        roots = [nullid]
-    discbases = []
-    for n in roots:
-        discbases.extend([p for p in cl.parents(n) if p != nullid])
-    # TODO: remove call to nodesbetween.
-    csets, roots, heads = cl.nodesbetween(roots, heads)
-    included = set(csets)
-    discbases = [n for n in discbases if n not in included]
-    outgoing = discovery.outgoing(cl, discbases, heads)
-    bundler = getbundler(version, repo)
-    return getsubset(repo, outgoing, bundler, source)
+    emitter = changegroupemitter.fromrootsandheads(repo, roots, heads)
+    data = emitter.emitchangegroupdata(version, source)
+    return getunbundler(version, util.chunkbuffer(data), None,
+                        {'clcount': emitter.changesetcount})
 
 def getlocalchangegroup(repo, source, outgoing, bundlecaps=None,
                         version='01'):
     """Like getbundle, but taking a discovery.outgoing as an argument.
 
     This is only implemented for local repos and reuses potentially
     precomputed sets in outgoing."""
     if not outgoing.missing:
@@ -1072,16 +1063,39 @@ class changegroupemitter(object):
         destination. ``common`` is a list of binary nodes that are
         common between this repo and the destination. The missing
         nodes between ``common`` and ``heads`` will be included in the
         changegroup.
         """
         outgoing = computeoutgoing(repo, heads, common)
         return changegroupemitter.fromoutgoing(repo, outgoing)
 
+    @classmethod
+    def fromrootsandheads(cls, repo, roots, heads):
+        """Create an instance with changesets between roots and heads.
+
+        The returned ``changegroupemitter`` will be configured to write
+        data for revisions that are descendants of any of the roots
+        in ``roots`` and ancestors of any of the heads in ``heads``. Both
+        are specified as a list of binary nodes.
+        """
+        cl = repo.changelog
+        if not roots:
+            roots = [nullid]
+        bases = []
+        for n in roots:
+            bases.extend([p for p in cl.parents(n) if p != nullid])
+        # TODO remove call to nodesbetween
+        nodes, roots, heads = cl.nodesbetween(roots, heads)
+        included = set(nodes)
+        bases = [n for n in bases if n not in included]
+        outgoing = discovery.outgoing(cl, bases, heads)
+
+        return changegroupemitter.fromoutgoing(repo, outgoing)
+
     @property
     def changesetcount(self):
         """The number of changesets in this changegroup."""
         return len(self._nodes)
 
     def emitchangegroupdata(self, version, source, bundlecaps=None,
                             fastpathlinkrev=False):
         """Emit raw changegroup data.


More information about the Mercurial-devel mailing list