[PATCH 2 of 5] localrepo: collect changelog, manifest, file nodes needed in shallow clone
Vishakh H
vsh426 at gmail.com
Tue Jun 29 11:15:03 CDT 2010
# HG changeset patch
# User Vishakh H <vsh426 at gmail.com>
# Date 1277827720 -19800
# Branch stable
# Node ID 9fd45a923518181e097bec605b19070a517b58dd
# Parent 0e714c59e28b68feb51c84f9d77a91db9d6a0661
localrepo: collect changelog, manifest, file nodes needed in shallow clone
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1175,7 +1175,7 @@
return r
- def pull(self, remote, heads=None, force=False):
+ def pull(self, remote, heads=None, shallowroot=None, force=False):
lock = self.lock()
try:
tmp = discovery.findcommonincoming(self, remote, heads=heads,
@@ -1191,14 +1191,15 @@
# issue1320, avoid a race if remote changed after discovery
heads = rheads
- if heads is None:
+ if heads is None and shallowroot is None:
cg = remote.changegroup(fetch, 'pull')
else:
if not remote.capable('changegroupsubset'):
raise util.Abort(_("Partial pull cannot be done because "
"other repository doesn't support "
"changegroupsubset."))
- cg = remote.changegroupsubset(fetch, heads, 'pull')
+ cg = remote.changegroupsubset(fetch, heads, 'pull',
+ shallowroot=shallowroot)
return self.addchangegroup(cg, 'pull', remote.url(), lock=lock)
finally:
lock.release()
@@ -1268,7 +1269,8 @@
for node in nodes:
self.ui.debug("%s\n" % hex(node))
- def changegroupsubset(self, bases, heads, source, extranodes=None):
+ def changegroupsubset(self, bases, heads, source, extranodes=None,
+ shallowroot=None):
"""Compute a changegroup consisting of all the nodes that are
descendents of any of the bases and ancestors of any of the heads.
Return a chunkbuffer object whose read() method will return
@@ -1298,7 +1300,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()
@@ -1342,6 +1344,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
@@ -1376,7 +1387,7 @@
# 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 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)
@@ -1406,6 +1417,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
@@ -1440,12 +1455,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.
@@ -1474,10 +1496,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
@@ -1517,11 +1541,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'))
@@ -1829,7 +1856,7 @@
self.invalidate()
return len(self.heads()) + 1
- def clone(self, remote, heads=[], stream=False):
+ def clone(self, remote, heads=[], shallowroot=None, stream=False):
'''clone remote repository.
keyword arguments:
@@ -1846,7 +1873,7 @@
if stream and not heads and remote.capable('stream'):
return self.stream_in(remote)
- return self.pull(remote, heads)
+ return self.pull(remote, heads, shallowroot)
def pushkey(self, namespace, key, old, new):
return pushkey.push(self, namespace, key, old, new)
More information about the Mercurial-devel
mailing list