diff -r dcb51f156fa6 -r b51bf961b3cb mercurial/localrepo.py --- 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):