[PATCH 5 of 9] localrepo: changegroupsubset collects shallow changeset, manifest and file nodes

Vishakh H vsh426 at gmail.com
Tue Jul 6 05:47:04 CDT 2010


# HG changeset patch
# User Vishakh H <vsh426 at gmail.com>
# Date 1278412035 -19800
# Branch stable
# Node ID e9de925ecfaf793340e787d8255f3a4571cfb813
# Parent  b3c06c23e6b618dc4ad6a94036d49c19432c2441
localrepo: changegroupsubset collects shallow changeset, manifest and file nodes

while generating groups of revisions, we collect the corresponsing nodes
using the collector functions. it is needed to ensure that we dont miss
nodes that are referenced by more than one changeset.

this is very slow going through all revisions. otoh doing it in _changegroup
is a bit redundant.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1304,7 +1304,7 @@
             bases = [nullid]
         msng_cl_lst, bases, heads = cl.nodesbetween(bases, heads)
 
-        if extranodes is None:
+        if extranodes is None and shallowroot is None:
             # can we go through the fast path ?
             heads.sort()
             allheads = self.heads()
@@ -1348,6 +1348,15 @@
         msng_mnfst_set = {}
         # Nor do we know which filenodes are missing.
         msng_filenode_set = {}
+        # revs needed in shallow clone
+        if shallowroot is not None:
+            sh_cl = set([shallowroot])
+            sh_mnfst = [cl.read(shallowroot)[0]]
+            sh_filenode = {}
+        else:
+            sh_cl = None
+            sh_mnfst = None
+            sh_filenode = {}
 
         junk = mnfst.index[len(mnfst) - 1] # Get around a bug in lazyindex
         junk = None
@@ -1382,7 +1391,9 @@
             # the first manifest that references it belongs to.
             def collect_msng_filenodes(mnfstnode):
                 r = mnfst.rev(mnfstnode)
-                if r - 1 in mnfst.parentrevs(r):
+                if extranodes is None and shallowroot is None:
+                    return
+                if r - 1 in mnfst.parentrevs(r) and mnfstnode not in sh_mnfst:
                     # If the previous rev is one of the parents,
                     # we only need to see a diff.
                     deltamf = mnfst.readdelta(mnfstnode)
@@ -1412,6 +1423,10 @@
                             clnode = msng_mnfst_set[mnfstnode]
                             ndset = msng_filenode_set.setdefault(f, {})
                             ndset.setdefault(fnode, clnode)
+                    if sh_mnfst is not None and mnfstnode in sh_mnfst:
+                        # Get all important filenodes
+                        for f in m:
+                            sh_filenode.setdefault(f, []).append(m[f])
             return collect_msng_filenodes
 
         # We have a list of filenodes we think we need for a file, lets remove
@@ -1446,12 +1461,19 @@
                 if node not in nodes:
                     nodes[node] = linknode
 
+        #find nodes to punch
+        def prune_shallow(nodes, sh_nodes):
+            if shallowroot is not None:
+                return [n for n in nodes if n not in sh_nodes]
+            return None
+
         # Now that we have all theses utility functions to help out and
         # logically divide up the task, generate the group.
         def gengroup():
             # The set of changed files starts empty.
             changedfiles = {}
-            collect = changegroup.collector(cl, msng_mnfst_set, changedfiles)
+            collect = changegroup.collector(cl, msng_mnfst_set, changedfiles,
+                                sh_cl, sh_mnfst)
 
             # Create a changenode group generator that will call our functions
             # back to lookup the owning changenode and collect information.
@@ -1480,10 +1502,12 @@
             msng_mnfst_lst = msng_mnfst_set.keys()
             # Sort the manifestnodes by revision number.
             msng_mnfst_lst.sort(key=mnfst.rev)
+            sh_nodes = prune_shallow(msng_mnfst_lst, sh_mnfst)
             # Create a generator for the manifestnodes that calls our lookup
             # and data collection functions back.
             group = mnfst.group(msng_mnfst_lst, lookup_manifest_link,
-                                filenode_collector(changedfiles))
+                                filenode_collector(changedfiles),
+                                shallownodes=sh_nodes)
             cnt = 0
             for chnk in group:
                 yield chnk
@@ -1523,11 +1547,14 @@
                     yield fname
                     # Sort the filenodes by their revision #
                     msng_filenode_lst.sort(key=filerevlog.rev)
+                    sh_nodes = prune_shallow(msng_filenode_lst,
+                                             sh_filenode.get(fname, []))
                     # Create a group generator and only pass in a changenode
                     # lookup function as we need to collect no information
                     # from filenodes.
                     group = filerevlog.group(msng_filenode_lst,
-                                             lookup_filenode_link_func(fname))
+                                             lookup_filenode_link_func(fname),
+                                             shallownodes=sh_nodes)
                     for chnk in group:
                         self.ui.progress(
                             _('bundling files'), cnt, item=fname, unit=_('chunks'))


More information about the Mercurial-devel mailing list