Show More
@@ -523,6 +523,37 b' class revisiondelta(object):' | |||||
523 | # Iterable of chunks holding raw delta data. |
|
523 | # Iterable of chunks holding raw delta data. | |
524 | deltachunks = attr.ib() |
|
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 | class cgpacker(object): |
|
557 | class cgpacker(object): | |
527 | def __init__(self, repo, filematcher, version, allowreorder, |
|
558 | def __init__(self, repo, filematcher, version, allowreorder, | |
528 | deltaparentfn, builddeltaheader, manifestsend, |
|
559 | deltaparentfn, builddeltaheader, manifestsend, | |
@@ -610,38 +641,7 b' class cgpacker(object):' | |||||
610 |
|
641 | |||
611 | return closechunk() |
|
642 | return closechunk() | |
612 |
|
643 | |||
613 | # Extracted both for clarity and for overriding in extensions. |
|
644 | def group(self, revs, store, ischangelog, lookup, units=None): | |
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): |
|
|||
645 | """Calculate a delta group, yielding a sequence of changegroup chunks |
|
645 | """Calculate a delta group, yielding a sequence of changegroup chunks | |
646 | (strings). |
|
646 | (strings). | |
647 |
|
647 | |||
@@ -656,12 +656,10 b' class cgpacker(object):' | |||||
656 | the type of revlog that is touched (changelog, manifest, etc.). |
|
656 | the type of revlog that is touched (changelog, manifest, etc.). | |
657 | """ |
|
657 | """ | |
658 | # if we don't have any revisions touched by these changesets, bail |
|
658 | # if we don't have any revisions touched by these changesets, bail | |
659 |
if len( |
|
659 | if len(revs) == 0: | |
660 | yield self._close() |
|
660 | yield self._close() | |
661 | return |
|
661 | return | |
662 |
|
662 | |||
663 | revs = self._sortgroup(store, ischangelog, nodelist, lookup) |
|
|||
664 |
|
||||
665 | # add the parent of the first rev |
|
663 | # add the parent of the first rev | |
666 | p = store.parentrevs(revs[0])[0] |
|
664 | p = store.parentrevs(revs[0])[0] | |
667 | revs.insert(0, p) |
|
665 | revs.insert(0, p) | |
@@ -693,20 +691,17 b' class cgpacker(object):' | |||||
693 | rr, rl = store.rev, store.linkrev |
|
691 | rr, rl = store.rev, store.linkrev | |
694 | return [n for n in missing if rl(rr(n)) not in commonrevs] |
|
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 | """Pack manifests into a changegroup stream. |
|
695 | """Pack manifests into a changegroup stream. | |
698 |
|
696 | |||
699 | Encodes the directory name in the output so multiple manifests |
|
697 | Encodes the directory name in the output so multiple manifests | |
700 | can be sent. Multiple manifests is not supported by cg1 and cg2. |
|
698 | can be sent. Multiple manifests is not supported by cg1 and cg2. | |
701 | """ |
|
699 | """ | |
702 |
|
||||
703 | if dir: |
|
700 | if dir: | |
704 | assert self.version == b'03' |
|
701 | assert self.version == b'03' | |
705 | yield _fileheader(dir) |
|
702 | yield _fileheader(dir) | |
706 |
|
703 | |||
707 | # TODO violates storage abstractions by assuming revlogs. |
|
704 | for chunk in self.group(revs, dirlog, False, lookuplinknode, | |
708 | dirlog = self._repo.manifestlog._revlog.dirlog(dir) |
|
|||
709 | for chunk in self.group(mfnodes, dirlog, False, lookuplinknode, |
|
|||
710 | units=_('manifests')): |
|
705 | units=_('manifests')): | |
711 | yield chunk |
|
706 | yield chunk | |
712 |
|
707 | |||
@@ -850,13 +845,17 b' class cgpacker(object):' | |||||
850 |
|
845 | |||
851 | return x |
|
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 | state = { |
|
852 | state = { | |
854 | 'clrevorder': clrevorder, |
|
853 | 'clrevorder': clrevorder, | |
855 | 'mfs': mfs, |
|
854 | 'mfs': mfs, | |
856 | 'changedfiles': changedfiles, |
|
855 | 'changedfiles': changedfiles, | |
857 | } |
|
856 | } | |
858 |
|
857 | |||
859 |
gen = self.group( |
|
858 | gen = self.group(revs, cl, True, lookupcl, units=_('changesets')) | |
860 |
|
859 | |||
861 | return state, gen |
|
860 | return state, gen | |
862 |
|
861 | |||
@@ -917,10 +916,19 b' class cgpacker(object):' | |||||
917 | size = 0 |
|
916 | size = 0 | |
918 | while tmfnodes: |
|
917 | while tmfnodes: | |
919 | dir, nodes = tmfnodes.popitem() |
|
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 | if not dir or prunednodes: |
|
921 | if not dir or prunednodes: | |
922 | for x in self._packmanifests(dir, prunednodes, |
|
922 | lookupfn = makelookupmflinknode(dir, nodes) | |
923 | 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 | size += len(x) |
|
932 | size += len(x) | |
925 | yield x |
|
933 | yield x | |
926 | self._verbosenote(_('%8.i (manifests)\n') % size) |
|
934 | self._verbosenote(_('%8.i (manifests)\n') % size) | |
@@ -981,12 +989,18 b' class cgpacker(object):' | |||||
981 |
|
989 | |||
982 | filenodes = self._prune(filerevlog, linkrevnodes, commonrevs) |
|
990 | filenodes = self._prune(filerevlog, linkrevnodes, commonrevs) | |
983 | if filenodes: |
|
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 | progress.update(i + 1, item=fname) |
|
999 | progress.update(i + 1, item=fname) | |
985 | h = _fileheader(fname) |
|
1000 | h = _fileheader(fname) | |
986 | size = len(h) |
|
1001 | size = len(h) | |
987 | yield h |
|
1002 | yield h | |
988 |
for chunk in self.group( |
|
1003 | for chunk in self.group(revs, filerevlog, False, lookupfilelog): | |
989 | lookupfilelog): |
|
|||
990 | size += len(chunk) |
|
1004 | size += len(chunk) | |
991 | yield chunk |
|
1005 | yield chunk | |
992 | self._verbosenote(_('%8.i %s\n') % (size, fname)) |
|
1006 | self._verbosenote(_('%8.i %s\n') % (size, fname)) |
General Comments 0
You need to be logged in to leave comments.
Login now