Mercurial > public > mercurial-scm > hg-stable
diff mercurial/localrepo.py @ 13741:b51bf961b3cb
wireproto: add getbundle() function
getbundle(common, heads) -> bundle
Returns the changegroup for all ancestors of heads which are not ancestors of common. For both
sets, the heads are included in the set.
Intended to eventually supercede changegroupsubset and changegroup. Uses heads of common region
to exclude unwanted changesets instead of bases of desired region, which is more useful and
easier to implement.
Designed to be extensible with new optional arguments (which will have to be guarded by
corresponding capabilities).
author | Peter Arrenbrecht <peter.arrenbrecht@gmail.com> |
---|---|
date | Wed, 23 Mar 2011 16:02:11 +0100 |
parents | e615765fdcc7 |
children | 7abab875e647 |
line wrap: on
line diff
--- a/mercurial/localrepo.py Wed Mar 23 12:38:36 2011 -0500 +++ b/mercurial/localrepo.py Wed Mar 23 16:02:11 2011 +0100 @@ -21,7 +21,7 @@ class localrepository(repo.repository): capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey', - 'known')) + 'known', 'getbundle')) supportedformats = set(('revlogv1', 'parentdelta')) supported = supportedformats | set(('store', 'fncache', 'shared', 'dotencode')) @@ -1443,16 +1443,41 @@ Another wrinkle is doing the reverse, figuring out which changeset in the changegroup a particular filenode or manifestnode belongs to. """ + cl = self.changelog + if not bases: + bases = [nullid] + csets, bases, heads = cl.nodesbetween(bases, heads) + # We assume that all ancestors of bases are known + common = set(cl.ancestors(*[cl.rev(n) for n in bases])) + return self._changegroupsubset(common, csets, heads, source) + + def getbundle(self, source, heads=None, common=None): + """Like changegroupsubset, but returns the set difference between the + ancestors of heads and the ancestors common. + + If heads is None, use the local heads. If common is None, use [nullid]. + + The nodes in common might not all be known locally due to the way the + current discovery protocol works. + """ + cl = self.changelog + if common: + nm = cl.nodemap + common = [n for n in common if n in nm] + else: + common = [nullid] + if not heads: + heads = cl.heads() + common, missing = cl.findcommonmissing(common, heads) + return self._changegroupsubset(common, missing, heads, source) + + def _changegroupsubset(self, commonrevs, csets, heads, source): cl = self.changelog mf = self.manifest mfs = {} # needed manifests fnodes = {} # needed file nodes - if not bases: - bases = [nullid] - csets, bases, heads = cl.nodesbetween(bases, heads) - # can we go through the fast path ? heads.sort() if heads == sorted(self.heads()): @@ -1462,9 +1487,6 @@ self.hook('preoutgoing', throw=True, source=source) self.changegroupinfo(csets, source) - # We assume that all ancestors of bases are known - commonrevs = set(cl.ancestors(*[cl.rev(n) for n in bases])) - # A function generating function that sets up the initial environment # the inner function. def filenode_collector(changedfiles):