Mercurial > public > mercurial-scm > hg-stable
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 |