mercurial/localrepo.py
changeset 11654 898a5305f342
parent 11653 eefa362d0b45
child 11659 deecf1953e7b
equal deleted inserted replaced
11653:eefa362d0b45 11654:898a5305f342
  1347         # also assume the recipient will have all the parents.  This function
  1347         # also assume the recipient will have all the parents.  This function
  1348         # prunes them from the set of missing nodes.
  1348         # prunes them from the set of missing nodes.
  1349         def prune_parents(revlog, hasset, msngset):
  1349         def prune_parents(revlog, hasset, msngset):
  1350             for r in revlog.ancestors(*[revlog.rev(n) for n in hasset]):
  1350             for r in revlog.ancestors(*[revlog.rev(n) for n in hasset]):
  1351                 msngset.pop(revlog.node(r), None)
  1351                 msngset.pop(revlog.node(r), None)
  1352 
       
  1353         # Use the information collected in changegroup.collector() to say
       
  1354         # which changenode any manifestnode belongs to.
       
  1355         def lookup_manifest_link(mnfstnode):
       
  1356             return msng_mnfst_set[mnfstnode]
       
  1357 
  1352 
  1358         # A function generating function that sets up the initial environment
  1353         # A function generating function that sets up the initial environment
  1359         # the inner function.
  1354         # the inner function.
  1360         def filenode_collector(changedfiles):
  1355         def filenode_collector(changedfiles):
  1361             # This gathers information from each manifestnode included in the
  1356             # This gathers information from each manifestnode included in the
  1398                             ndset.setdefault(fnode, clnode)
  1393                             ndset.setdefault(fnode, clnode)
  1399             return collect_msng_filenodes
  1394             return collect_msng_filenodes
  1400 
  1395 
  1401         # We have a list of filenodes we think we need for a file, lets remove
  1396         # We have a list of filenodes we think we need for a file, lets remove
  1402         # all those we know the recipient must have.
  1397         # all those we know the recipient must have.
  1403         def prune_filenodes(f, filerevlog):
  1398         def prune_filenodes(f, filerevlog, missingnodes):
  1404             msngset = msng_filenode_set[f]
       
  1405             hasset = set()
  1399             hasset = set()
  1406             # If a 'missing' filenode thinks it belongs to a changenode we
  1400             # If a 'missing' filenode thinks it belongs to a changenode we
  1407             # assume the recipient must have, then the recipient must have
  1401             # assume the recipient must have, then the recipient must have
  1408             # that filenode.
  1402             # that filenode.
  1409             for n in msngset:
  1403             for n in missingnodes:
  1410                 clnode = cl.node(filerevlog.linkrev(filerevlog.rev(n)))
  1404                 clnode = cl.node(filerevlog.linkrev(filerevlog.rev(n)))
  1411                 if clnode in has_cl_set:
  1405                 if clnode in has_cl_set:
  1412                     hasset.add(n)
  1406                     hasset.add(n)
  1413             prune_parents(filerevlog, hasset, msngset)
  1407             prune_parents(filerevlog, hasset, missingnodes)
  1414 
       
  1415         # A function generator function that sets up the a context for the
       
  1416         # inner function.
       
  1417         def lookup_filenode_link_func(fname):
       
  1418             msngset = msng_filenode_set[fname]
       
  1419             # Lookup the changenode the filenode belongs to.
       
  1420             def lookup_filenode_link(fnode):
       
  1421                 return msngset[fnode]
       
  1422             return lookup_filenode_link
       
  1423 
  1408 
  1424         # Add the nodes that were explicitly requested.
  1409         # Add the nodes that were explicitly requested.
  1425         def add_extra_nodes(name, nodes):
  1410         def add_extra_nodes(name, nodes):
  1426             if not extranodes or name not in extranodes:
  1411             if not extranodes or name not in extranodes:
  1427                 return
  1412                 return
  1464             msng_mnfst_lst = msng_mnfst_set.keys()
  1449             msng_mnfst_lst = msng_mnfst_set.keys()
  1465             # Sort the manifestnodes by revision number.
  1450             # Sort the manifestnodes by revision number.
  1466             msng_mnfst_lst.sort(key=mnfst.rev)
  1451             msng_mnfst_lst.sort(key=mnfst.rev)
  1467             # Create a generator for the manifestnodes that calls our lookup
  1452             # Create a generator for the manifestnodes that calls our lookup
  1468             # and data collection functions back.
  1453             # and data collection functions back.
  1469             group = mnfst.group(msng_mnfst_lst, lookup_manifest_link,
  1454             group = mnfst.group(msng_mnfst_lst,
       
  1455                                 lambda mnode: msng_mnfst_set[mnode],
  1470                                 filenode_collector(changedfiles))
  1456                                 filenode_collector(changedfiles))
  1471             cnt = 0
  1457             cnt = 0
  1472             for chnk in group:
  1458             for chnk in group:
  1473                 yield chnk
  1459                 yield chnk
  1474                 self.ui.progress(_('bundling manifests'), cnt, unit=_('chunks'))
  1460                 self.ui.progress(_('bundling manifests'), cnt, unit=_('chunks'))
  1492                 filerevlog = self.file(fname)
  1478                 filerevlog = self.file(fname)
  1493                 if not len(filerevlog):
  1479                 if not len(filerevlog):
  1494                     raise util.Abort(_("empty or missing revlog for %s") % fname)
  1480                     raise util.Abort(_("empty or missing revlog for %s") % fname)
  1495                 # Toss out the filenodes that the recipient isn't really
  1481                 # Toss out the filenodes that the recipient isn't really
  1496                 # missing.
  1482                 # missing.
  1497                 if fname in msng_filenode_set:
  1483                 missingfnodes = msng_filenode_set.pop(fname, {})
  1498                     prune_filenodes(fname, filerevlog)
  1484                 prune_filenodes(fname, filerevlog, missingfnodes)
  1499                     add_extra_nodes(fname, msng_filenode_set[fname])
  1485                 add_extra_nodes(fname, missingfnodes)
  1500                     msng_filenode_lst = msng_filenode_set[fname].keys()
       
  1501                 else:
       
  1502                     msng_filenode_lst = []
       
  1503                 # If any filenodes are left, generate the group for them,
  1486                 # If any filenodes are left, generate the group for them,
  1504                 # otherwise don't bother.
  1487                 # otherwise don't bother.
  1505                 if len(msng_filenode_lst) > 0:
  1488                 if missingfnodes:
  1506                     yield changegroup.chunkheader(len(fname))
  1489                     yield changegroup.chunkheader(len(fname))
  1507                     yield fname
  1490                     yield fname
  1508                     # Sort the filenodes by their revision #
  1491                     # Sort the filenodes by their revision # (topological order)
  1509                     msng_filenode_lst.sort(key=filerevlog.rev)
  1492                     nodeiter = list(missingfnodes)
       
  1493                     nodeiter.sort(key=filerevlog.rev)
  1510                     # Create a group generator and only pass in a changenode
  1494                     # Create a group generator and only pass in a changenode
  1511                     # lookup function as we need to collect no information
  1495                     # lookup function as we need to collect no information
  1512                     # from filenodes.
  1496                     # from filenodes.
  1513                     group = filerevlog.group(msng_filenode_lst,
  1497                     group = filerevlog.group(nodeiter,
  1514                                              lookup_filenode_link_func(fname))
  1498                                              lambda fnode: missingfnodes[fnode])
  1515                     for chnk in group:
  1499                     for chnk in group:
  1516                         self.ui.progress(
  1500                         self.ui.progress(
  1517                             _('bundling files'), cnt, item=fname, unit=_('chunks'))
  1501                             _('bundling files'), cnt, item=fname, unit=_('chunks'))
  1518                         cnt += 1
  1502                         cnt += 1
  1519                         yield chnk
  1503                         yield chnk
  1520                 if fname in msng_filenode_set:
       
  1521                     # Don't need this anymore, toss it to free memory.
       
  1522                     del msng_filenode_set[fname]
       
  1523             # Signal that no more groups are left.
  1504             # Signal that no more groups are left.
  1524             yield changegroup.closechunk()
  1505             yield changegroup.closechunk()
  1525             self.ui.progress(_('bundling files'), None)
  1506             self.ui.progress(_('bundling files'), None)
  1526 
  1507 
  1527             if msng_cl_lst:
  1508             if msng_cl_lst: