1339 |
1339 |
1340 # A changeset always belongs to itself, so the changenode lookup |
1340 # A changeset always belongs to itself, so the changenode lookup |
1341 # function for a changenode is identity. |
1341 # function for a changenode is identity. |
1342 def identity(x): |
1342 def identity(x): |
1343 return x |
1343 return x |
1344 |
|
1345 # If we determine that a particular file or manifest node must be a |
|
1346 # node that the recipient of the changegroup will already have, we can |
|
1347 # also assume the recipient will have all the parents. This function |
|
1348 # prunes them from the set of missing nodes. |
|
1349 def prune_parents(revlog, hasset, msngset): |
|
1350 for r in revlog.ancestors(*[revlog.rev(n) for n in hasset]): |
|
1351 msngset.pop(revlog.node(r), None) |
|
1352 |
1344 |
1353 # A function generating function that sets up the initial environment |
1345 # A function generating function that sets up the initial environment |
1354 # the inner function. |
1346 # the inner function. |
1355 def filenode_collector(changedfiles): |
1347 def filenode_collector(changedfiles): |
1356 # This gathers information from each manifestnode included in the |
1348 # This gathers information from each manifestnode included in the |
1391 clnode = msng_mnfst_set[mnfstnode] |
1383 clnode = msng_mnfst_set[mnfstnode] |
1392 ndset = msng_filenode_set.setdefault(f, {}) |
1384 ndset = msng_filenode_set.setdefault(f, {}) |
1393 ndset.setdefault(fnode, clnode) |
1385 ndset.setdefault(fnode, clnode) |
1394 return collect_msng_filenodes |
1386 return collect_msng_filenodes |
1395 |
1387 |
1396 # We have a list of filenodes we think we need for a file, lets remove |
1388 # If we determine that a particular file or manifest node must be a |
1397 # all those we know the recipient must have. |
1389 # node that the recipient of the changegroup will already have, we can |
1398 def prune_filenodes(f, filerevlog, missingnodes): |
1390 # also assume the recipient will have all the parents. This function |
|
1391 # prunes them from the set of missing nodes. |
|
1392 # XXX is it even useful? the testsuite doesn't trigger it |
|
1393 def prune(revlog, missingnodes): |
1399 hasset = set() |
1394 hasset = set() |
1400 # If a 'missing' filenode thinks it belongs to a changenode we |
1395 # If a 'missing' filenode thinks it belongs to a changenode we |
1401 # assume the recipient must have, then the recipient must have |
1396 # assume the recipient must have, then the recipient must have |
1402 # that filenode. |
1397 # that filenode. |
1403 for n in missingnodes: |
1398 for n in missingnodes: |
1404 clnode = cl.node(filerevlog.linkrev(filerevlog.rev(n))) |
1399 clnode = cl.node(revlog.linkrev(revlog.rev(n))) |
1405 if clnode in has_cl_set: |
1400 if clnode in has_cl_set: |
1406 hasset.add(n) |
1401 hasset.add(n) |
1407 prune_parents(filerevlog, hasset, missingnodes) |
1402 for r in revlog.ancestors(*[revlog.rev(n) for n in hasset]): |
|
1403 missingnodes.pop(revlog.node(r), None) |
1408 |
1404 |
1409 # Add the nodes that were explicitly requested. |
1405 # Add the nodes that were explicitly requested. |
1410 def add_extra_nodes(name, nodes): |
1406 def add_extra_nodes(name, nodes): |
1411 if not extranodes or name not in extranodes: |
1407 if not extranodes or name not in extranodes: |
1412 return |
1408 return |
1430 yield chnk |
1426 yield chnk |
1431 self.ui.progress(_('bundling changes'), cnt, unit=_('chunks')) |
1427 self.ui.progress(_('bundling changes'), cnt, unit=_('chunks')) |
1432 cnt += 1 |
1428 cnt += 1 |
1433 self.ui.progress(_('bundling changes'), None) |
1429 self.ui.progress(_('bundling changes'), None) |
1434 |
1430 |
1435 |
1431 prune(mnfst, msng_mnfst_set) |
1436 # Figure out which manifest nodes (of the ones we think might be |
|
1437 # part of the changegroup) the recipient must know about and |
|
1438 # remove them from the changegroup. |
|
1439 has_mnfst_set = set() |
|
1440 for n in msng_mnfst_set: |
|
1441 # If a 'missing' manifest thinks it belongs to a changenode |
|
1442 # the recipient is assumed to have, obviously the recipient |
|
1443 # must have that manifest. |
|
1444 linknode = cl.node(mnfst.linkrev(mnfst.rev(n))) |
|
1445 if linknode in has_cl_set: |
|
1446 has_mnfst_set.add(n) |
|
1447 prune_parents(mnfst, has_mnfst_set, msng_mnfst_set) |
|
1448 add_extra_nodes(1, msng_mnfst_set) |
1432 add_extra_nodes(1, msng_mnfst_set) |
1449 msng_mnfst_lst = msng_mnfst_set.keys() |
1433 msng_mnfst_lst = msng_mnfst_set.keys() |
1450 # Sort the manifestnodes by revision number. |
1434 # Sort the manifestnodes by revision number. |
1451 msng_mnfst_lst.sort(key=mnfst.rev) |
1435 msng_mnfst_lst.sort(key=mnfst.rev) |
1452 # Create a generator for the manifestnodes that calls our lookup |
1436 # Create a generator for the manifestnodes that calls our lookup |
1479 if not len(filerevlog): |
1463 if not len(filerevlog): |
1480 raise util.Abort(_("empty or missing revlog for %s") % fname) |
1464 raise util.Abort(_("empty or missing revlog for %s") % fname) |
1481 # Toss out the filenodes that the recipient isn't really |
1465 # Toss out the filenodes that the recipient isn't really |
1482 # missing. |
1466 # missing. |
1483 missingfnodes = msng_filenode_set.pop(fname, {}) |
1467 missingfnodes = msng_filenode_set.pop(fname, {}) |
1484 prune_filenodes(fname, filerevlog, missingfnodes) |
1468 prune(filerevlog, missingfnodes) |
1485 add_extra_nodes(fname, missingfnodes) |
1469 add_extra_nodes(fname, missingfnodes) |
1486 # If any filenodes are left, generate the group for them, |
1470 # If any filenodes are left, generate the group for them, |
1487 # otherwise don't bother. |
1471 # otherwise don't bother. |
1488 if missingfnodes: |
1472 if missingfnodes: |
1489 yield changegroup.chunkheader(len(fname)) |
1473 yield changegroup.chunkheader(len(fname)) |