comparison 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
comparison
equal deleted inserted replaced
13740:dcb51f156fa6 13741:b51bf961b3cb
19 import weakref, errno, os, time, inspect 19 import weakref, errno, os, time, inspect
20 propertycache = util.propertycache 20 propertycache = util.propertycache
21 21
22 class localrepository(repo.repository): 22 class localrepository(repo.repository):
23 capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey', 23 capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey',
24 'known')) 24 'known', 'getbundle'))
25 supportedformats = set(('revlogv1', 'parentdelta')) 25 supportedformats = set(('revlogv1', 'parentdelta'))
26 supported = supportedformats | set(('store', 'fncache', 'shared', 26 supported = supportedformats | set(('store', 'fncache', 'shared',
27 'dotencode')) 27 'dotencode'))
28 28
29 def __init__(self, baseui, path=None, create=0): 29 def __init__(self, baseui, path=None, create=0):
1441 is non-trivial. 1441 is non-trivial.
1442 1442
1443 Another wrinkle is doing the reverse, figuring out which changeset in 1443 Another wrinkle is doing the reverse, figuring out which changeset in
1444 the changegroup a particular filenode or manifestnode belongs to. 1444 the changegroup a particular filenode or manifestnode belongs to.
1445 """ 1445 """
1446 cl = self.changelog
1447 if not bases:
1448 bases = [nullid]
1449 csets, bases, heads = cl.nodesbetween(bases, heads)
1450 # We assume that all ancestors of bases are known
1451 common = set(cl.ancestors(*[cl.rev(n) for n in bases]))
1452 return self._changegroupsubset(common, csets, heads, source)
1453
1454 def getbundle(self, source, heads=None, common=None):
1455 """Like changegroupsubset, but returns the set difference between the
1456 ancestors of heads and the ancestors common.
1457
1458 If heads is None, use the local heads. If common is None, use [nullid].
1459
1460 The nodes in common might not all be known locally due to the way the
1461 current discovery protocol works.
1462 """
1463 cl = self.changelog
1464 if common:
1465 nm = cl.nodemap
1466 common = [n for n in common if n in nm]
1467 else:
1468 common = [nullid]
1469 if not heads:
1470 heads = cl.heads()
1471 common, missing = cl.findcommonmissing(common, heads)
1472 return self._changegroupsubset(common, missing, heads, source)
1473
1474 def _changegroupsubset(self, commonrevs, csets, heads, source):
1446 1475
1447 cl = self.changelog 1476 cl = self.changelog
1448 mf = self.manifest 1477 mf = self.manifest
1449 mfs = {} # needed manifests 1478 mfs = {} # needed manifests
1450 fnodes = {} # needed file nodes 1479 fnodes = {} # needed file nodes
1451 1480
1452 if not bases:
1453 bases = [nullid]
1454 csets, bases, heads = cl.nodesbetween(bases, heads)
1455
1456 # can we go through the fast path ? 1481 # can we go through the fast path ?
1457 heads.sort() 1482 heads.sort()
1458 if heads == sorted(self.heads()): 1483 if heads == sorted(self.heads()):
1459 return self._changegroup(csets, source) 1484 return self._changegroup(csets, source)
1460 1485
1461 # slow path 1486 # slow path
1462 self.hook('preoutgoing', throw=True, source=source) 1487 self.hook('preoutgoing', throw=True, source=source)
1463 self.changegroupinfo(csets, source) 1488 self.changegroupinfo(csets, source)
1464
1465 # We assume that all ancestors of bases are known
1466 commonrevs = set(cl.ancestors(*[cl.rev(n) for n in bases]))
1467 1489
1468 # A function generating function that sets up the initial environment 1490 # A function generating function that sets up the initial environment
1469 # the inner function. 1491 # the inner function.
1470 def filenode_collector(changedfiles): 1492 def filenode_collector(changedfiles):
1471 # This gathers information from each manifestnode included in the 1493 # This gathers information from each manifestnode included in the