comparison mercurial/localrepo.py @ 13703:48d606d7192b

changegroupsubset: extranodes are no longer needed
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Sun, 20 Mar 2011 01:16:57 +0100
parents 80d6e1f63ed9
children 7beb9834d185
comparison
equal deleted inserted replaced
13702:ffd370aa050b 13703:48d606d7192b
1423 if self.ui.debugflag: 1423 if self.ui.debugflag:
1424 self.ui.debug("list of changesets:\n") 1424 self.ui.debug("list of changesets:\n")
1425 for node in nodes: 1425 for node in nodes:
1426 self.ui.debug("%s\n" % hex(node)) 1426 self.ui.debug("%s\n" % hex(node))
1427 1427
1428 def changegroupsubset(self, bases, heads, source, extranodes=None): 1428 def changegroupsubset(self, bases, heads, source):
1429 """Compute a changegroup consisting of all the nodes that are 1429 """Compute a changegroup consisting of all the nodes that are
1430 descendents of any of the bases and ancestors of any of the heads. 1430 descendents of any of the bases and ancestors of any of the heads.
1431 Return a chunkbuffer object whose read() method will return 1431 Return a chunkbuffer object whose read() method will return
1432 successive changegroup chunks. 1432 successive changegroup chunks.
1433 1433
1435 manifest nodes need to be included for the changeset to be complete 1435 manifest nodes need to be included for the changeset to be complete
1436 is non-trivial. 1436 is non-trivial.
1437 1437
1438 Another wrinkle is doing the reverse, figuring out which changeset in 1438 Another wrinkle is doing the reverse, figuring out which changeset in
1439 the changegroup a particular filenode or manifestnode belongs to. 1439 the changegroup a particular filenode or manifestnode belongs to.
1440
1441 The caller can specify some nodes that must be included in the
1442 changegroup using the extranodes argument. It should be a dict
1443 where the keys are the filenames (or 1 for the manifest), and the
1444 values are lists of (node, linknode) tuples, where node is a wanted
1445 node and linknode is the changelog node that should be transmitted as
1446 the linkrev.
1447 """ 1440 """
1448 1441
1449 # Set up some initial variables 1442 # Set up some initial variables
1450 # Make it easy to refer to self.changelog 1443 # Make it easy to refer to self.changelog
1451 cl = self.changelog 1444 cl = self.changelog
1455 # necessary to re-create the changegroup. 1448 # necessary to re-create the changegroup.
1456 if not bases: 1449 if not bases:
1457 bases = [nullid] 1450 bases = [nullid]
1458 msng_cl_lst, bases, heads = cl.nodesbetween(bases, heads) 1451 msng_cl_lst, bases, heads = cl.nodesbetween(bases, heads)
1459 1452
1460 if extranodes is None: 1453 # can we go through the fast path ?
1461 # can we go through the fast path ? 1454 heads.sort()
1462 heads.sort() 1455 allheads = self.heads()
1463 allheads = self.heads() 1456 allheads.sort()
1464 allheads.sort() 1457 if heads == allheads:
1465 if heads == allheads: 1458 return self._changegroup(msng_cl_lst, source)
1466 return self._changegroup(msng_cl_lst, source)
1467 1459
1468 # slow path 1460 # slow path
1469 self.hook('preoutgoing', throw=True, source=source) 1461 self.hook('preoutgoing', throw=True, source=source)
1470 1462
1471 self.changegroupinfo(msng_cl_lst, source) 1463 self.changegroupinfo(msng_cl_lst, source)
1544 for n in hasset: 1536 for n in hasset:
1545 missingnodes.pop(n, None) 1537 missingnodes.pop(n, None)
1546 for r in revlog.ancestors(*[revlog.rev(n) for n in hasset]): 1538 for r in revlog.ancestors(*[revlog.rev(n) for n in hasset]):
1547 missingnodes.pop(revlog.node(r), None) 1539 missingnodes.pop(revlog.node(r), None)
1548 1540
1549 # Add the nodes that were explicitly requested.
1550 def add_extra_nodes(name, nodes):
1551 if not extranodes or name not in extranodes:
1552 return
1553
1554 for node, linknode in extranodes[name]:
1555 if node not in nodes:
1556 nodes[node] = linknode
1557
1558 # Now that we have all theses utility functions to help out and 1541 # Now that we have all theses utility functions to help out and
1559 # logically divide up the task, generate the group. 1542 # logically divide up the task, generate the group.
1560 def gengroup(): 1543 def gengroup():
1561 # The set of changed files starts empty. 1544 # The set of changed files starts empty.
1562 changedfiles = set() 1545 changedfiles = set()
1574 unit=_('changesets')) 1557 unit=_('changesets'))
1575 changecount = cnt / 3 1558 changecount = cnt / 3
1576 self.ui.progress(_('bundling'), None) 1559 self.ui.progress(_('bundling'), None)
1577 1560
1578 prune(mnfst, msng_mnfst_set) 1561 prune(mnfst, msng_mnfst_set)
1579 add_extra_nodes(1, msng_mnfst_set)
1580 msng_mnfst_lst = msng_mnfst_set.keys() 1562 msng_mnfst_lst = msng_mnfst_set.keys()
1581 # Sort the manifestnodes by revision number. 1563 # Sort the manifestnodes by revision number.
1582 msng_mnfst_lst.sort(key=mnfst.rev) 1564 msng_mnfst_lst.sort(key=mnfst.rev)
1583 # Create a generator for the manifestnodes that calls our lookup 1565 # Create a generator for the manifestnodes that calls our lookup
1584 # and data collection functions back. 1566 # and data collection functions back.
1600 # These are no longer needed, dereference and toss the memory for 1582 # These are no longer needed, dereference and toss the memory for
1601 # them. 1583 # them.
1602 msng_mnfst_lst = None 1584 msng_mnfst_lst = None
1603 msng_mnfst_set.clear() 1585 msng_mnfst_set.clear()
1604 1586
1605 if extranodes:
1606 for fname in extranodes:
1607 if isinstance(fname, int):
1608 continue
1609 msng_filenode_set.setdefault(fname, {})
1610 changedfiles.add(fname)
1611 # Go through all our files in order sorted by name. 1587 # Go through all our files in order sorted by name.
1612 for idx, fname in enumerate(sorted(changedfiles)): 1588 for idx, fname in enumerate(sorted(changedfiles)):
1613 filerevlog = self.file(fname) 1589 filerevlog = self.file(fname)
1614 if not len(filerevlog): 1590 if not len(filerevlog):
1615 raise util.Abort(_("empty or missing revlog for %s") % fname) 1591 raise util.Abort(_("empty or missing revlog for %s") % fname)
1616 # Toss out the filenodes that the recipient isn't really 1592 # Toss out the filenodes that the recipient isn't really
1617 # missing. 1593 # missing.
1618 missingfnodes = msng_filenode_set.pop(fname, {}) 1594 missingfnodes = msng_filenode_set.pop(fname, {})
1619 prune(filerevlog, missingfnodes) 1595 prune(filerevlog, missingfnodes)
1620 add_extra_nodes(fname, missingfnodes)
1621 # If any filenodes are left, generate the group for them, 1596 # If any filenodes are left, generate the group for them,
1622 # otherwise don't bother. 1597 # otherwise don't bother.
1623 if missingfnodes: 1598 if missingfnodes:
1624 yield changegroup.chunkheader(len(fname)) 1599 yield changegroup.chunkheader(len(fname))
1625 yield fname 1600 yield fname