Show More
@@ -523,6 +523,37 b' class revisiondelta(object):' | |||
|
523 | 523 | # Iterable of chunks holding raw delta data. |
|
524 | 524 | deltachunks = attr.ib() |
|
525 | 525 | |
|
526 | def _sortnodesnormal(store, nodes, reorder): | |
|
527 | """Sort nodes for changegroup generation and turn into revnums.""" | |
|
528 | # for generaldelta revlogs, we linearize the revs; this will both be | |
|
529 | # much quicker and generate a much smaller bundle | |
|
530 | if (store._generaldelta and reorder is None) or reorder: | |
|
531 | dag = dagutil.revlogdag(store) | |
|
532 | return dag.linearize(set(store.rev(n) for n in nodes)) | |
|
533 | else: | |
|
534 | return sorted([store.rev(n) for n in nodes]) | |
|
535 | ||
|
536 | def _sortnodesellipsis(store, nodes, clnodetorev, lookup): | |
|
537 | """Sort nodes for changegroup generation and turn into revnums.""" | |
|
538 | # Ellipses serving mode. | |
|
539 | # | |
|
540 | # In a perfect world, we'd generate better ellipsis-ified graphs | |
|
541 | # for non-changelog revlogs. In practice, we haven't started doing | |
|
542 | # that yet, so the resulting DAGs for the manifestlog and filelogs | |
|
543 | # are actually full of bogus parentage on all the ellipsis | |
|
544 | # nodes. This has the side effect that, while the contents are | |
|
545 | # correct, the individual DAGs might be completely out of whack in | |
|
546 | # a case like 882681bc3166 and its ancestors (back about 10 | |
|
547 | # revisions or so) in the main hg repo. | |
|
548 | # | |
|
549 | # The one invariant we *know* holds is that the new (potentially | |
|
550 | # bogus) DAG shape will be valid if we order the nodes in the | |
|
551 | # order that they're introduced in dramatis personae by the | |
|
552 | # changelog, so what we do is we sort the non-changelog histories | |
|
553 | # by the order in which they are used by the changelog. | |
|
554 | key = lambda n: clnodetorev[lookup(n)] | |
|
555 | return [store.rev(n) for n in sorted(nodes, key=key)] | |
|
556 | ||
|
526 | 557 | class cgpacker(object): |
|
527 | 558 | def __init__(self, repo, filematcher, version, allowreorder, |
|
528 | 559 | deltaparentfn, builddeltaheader, manifestsend, |
@@ -610,38 +641,7 b' class cgpacker(object):' | |||
|
610 | 641 | |
|
611 | 642 | return closechunk() |
|
612 | 643 | |
|
613 | # Extracted both for clarity and for overriding in extensions. | |
|
614 | def _sortgroup(self, store, ischangelog, nodelist, lookup): | |
|
615 | """Sort nodes for change group and turn them into revnums.""" | |
|
616 | # Ellipses serving mode. | |
|
617 | # | |
|
618 | # In a perfect world, we'd generate better ellipsis-ified graphs | |
|
619 | # for non-changelog revlogs. In practice, we haven't started doing | |
|
620 | # that yet, so the resulting DAGs for the manifestlog and filelogs | |
|
621 | # are actually full of bogus parentage on all the ellipsis | |
|
622 | # nodes. This has the side effect that, while the contents are | |
|
623 | # correct, the individual DAGs might be completely out of whack in | |
|
624 | # a case like 882681bc3166 and its ancestors (back about 10 | |
|
625 | # revisions or so) in the main hg repo. | |
|
626 | # | |
|
627 | # The one invariant we *know* holds is that the new (potentially | |
|
628 | # bogus) DAG shape will be valid if we order the nodes in the | |
|
629 | # order that they're introduced in dramatis personae by the | |
|
630 | # changelog, so what we do is we sort the non-changelog histories | |
|
631 | # by the order in which they are used by the changelog. | |
|
632 | if self._ellipses and not ischangelog: | |
|
633 | key = lambda n: self._clnodetorev[lookup(n)] | |
|
634 | return [store.rev(n) for n in sorted(nodelist, key=key)] | |
|
635 | ||
|
636 | # for generaldelta revlogs, we linearize the revs; this will both be | |
|
637 | # much quicker and generate a much smaller bundle | |
|
638 | if (store._generaldelta and self._reorder is None) or self._reorder: | |
|
639 | dag = dagutil.revlogdag(store) | |
|
640 | return dag.linearize(set(store.rev(n) for n in nodelist)) | |
|
641 | else: | |
|
642 | return sorted([store.rev(n) for n in nodelist]) | |
|
643 | ||
|
644 | def group(self, nodelist, store, ischangelog, lookup, units=None): | |
|
644 | def group(self, revs, store, ischangelog, lookup, units=None): | |
|
645 | 645 | """Calculate a delta group, yielding a sequence of changegroup chunks |
|
646 | 646 | (strings). |
|
647 | 647 | |
@@ -656,12 +656,10 b' class cgpacker(object):' | |||
|
656 | 656 | the type of revlog that is touched (changelog, manifest, etc.). |
|
657 | 657 | """ |
|
658 | 658 | # if we don't have any revisions touched by these changesets, bail |
|
659 |
if len( |
|
|
659 | if len(revs) == 0: | |
|
660 | 660 | yield self._close() |
|
661 | 661 | return |
|
662 | 662 | |
|
663 | revs = self._sortgroup(store, ischangelog, nodelist, lookup) | |
|
664 | ||
|
665 | 663 | # add the parent of the first rev |
|
666 | 664 | p = store.parentrevs(revs[0])[0] |
|
667 | 665 | revs.insert(0, p) |
@@ -693,20 +691,17 b' class cgpacker(object):' | |||
|
693 | 691 | rr, rl = store.rev, store.linkrev |
|
694 | 692 | return [n for n in missing if rl(rr(n)) not in commonrevs] |
|
695 | 693 | |
|
696 |
def _packmanifests(self, dir, |
|
|
694 | def _packmanifests(self, dir, dirlog, revs, lookuplinknode): | |
|
697 | 695 | """Pack manifests into a changegroup stream. |
|
698 | 696 | |
|
699 | 697 | Encodes the directory name in the output so multiple manifests |
|
700 | 698 | can be sent. Multiple manifests is not supported by cg1 and cg2. |
|
701 | 699 | """ |
|
702 | ||
|
703 | 700 | if dir: |
|
704 | 701 | assert self.version == b'03' |
|
705 | 702 | yield _fileheader(dir) |
|
706 | 703 | |
|
707 | # TODO violates storage abstractions by assuming revlogs. | |
|
708 | dirlog = self._repo.manifestlog._revlog.dirlog(dir) | |
|
709 | for chunk in self.group(mfnodes, dirlog, False, lookuplinknode, | |
|
704 | for chunk in self.group(revs, dirlog, False, lookuplinknode, | |
|
710 | 705 | units=_('manifests')): |
|
711 | 706 | yield chunk |
|
712 | 707 | |
@@ -850,13 +845,17 b' class cgpacker(object):' | |||
|
850 | 845 | |
|
851 | 846 | return x |
|
852 | 847 | |
|
848 | # Changelog doesn't benefit from reordering revisions. So send out | |
|
849 | # revisions in store order. | |
|
850 | revs = sorted(cl.rev(n) for n in nodes) | |
|
851 | ||
|
853 | 852 | state = { |
|
854 | 853 | 'clrevorder': clrevorder, |
|
855 | 854 | 'mfs': mfs, |
|
856 | 855 | 'changedfiles': changedfiles, |
|
857 | 856 | } |
|
858 | 857 | |
|
859 |
gen = self.group( |
|
|
858 | gen = self.group(revs, cl, True, lookupcl, units=_('changesets')) | |
|
860 | 859 | |
|
861 | 860 | return state, gen |
|
862 | 861 | |
@@ -917,10 +916,19 b' class cgpacker(object):' | |||
|
917 | 916 | size = 0 |
|
918 | 917 | while tmfnodes: |
|
919 | 918 | dir, nodes = tmfnodes.popitem() |
|
920 | prunednodes = self._prune(dirlog(dir), nodes, commonrevs) | |
|
919 | store = dirlog(dir) | |
|
920 | prunednodes = self._prune(store, nodes, commonrevs) | |
|
921 | 921 | if not dir or prunednodes: |
|
922 | for x in self._packmanifests(dir, prunednodes, | |
|
923 | makelookupmflinknode(dir, nodes)): | |
|
922 | lookupfn = makelookupmflinknode(dir, nodes) | |
|
923 | ||
|
924 | if self._ellipses: | |
|
925 | revs = _sortnodesellipsis(store, prunednodes, | |
|
926 | self._clnodetorev, lookupfn) | |
|
927 | else: | |
|
928 | revs = _sortnodesnormal(store, prunednodes, | |
|
929 | self._reorder) | |
|
930 | ||
|
931 | for x in self._packmanifests(dir, store, revs, lookupfn): | |
|
924 | 932 | size += len(x) |
|
925 | 933 | yield x |
|
926 | 934 | self._verbosenote(_('%8.i (manifests)\n') % size) |
@@ -981,12 +989,18 b' class cgpacker(object):' | |||
|
981 | 989 | |
|
982 | 990 | filenodes = self._prune(filerevlog, linkrevnodes, commonrevs) |
|
983 | 991 | if filenodes: |
|
992 | if self._ellipses: | |
|
993 | revs = _sortnodesellipsis(filerevlog, filenodes, | |
|
994 | self._clnodetorev, lookupfilelog) | |
|
995 | else: | |
|
996 | revs = _sortnodesnormal(filerevlog, filenodes, | |
|
997 | self._reorder) | |
|
998 | ||
|
984 | 999 | progress.update(i + 1, item=fname) |
|
985 | 1000 | h = _fileheader(fname) |
|
986 | 1001 | size = len(h) |
|
987 | 1002 | yield h |
|
988 |
for chunk in self.group( |
|
|
989 | lookupfilelog): | |
|
1003 | for chunk in self.group(revs, filerevlog, False, lookupfilelog): | |
|
990 | 1004 | size += len(chunk) |
|
991 | 1005 | yield chunk |
|
992 | 1006 | self._verbosenote(_('%8.i %s\n') % (size, fname)) |
General Comments 0
You need to be logged in to leave comments.
Login now