Show More
@@ -553,27 +553,6 b' class headerlessfixup(object):' | |||
|
553 | 553 | return d |
|
554 | 554 | return readexactly(self._fh, n) |
|
555 | 555 | |
|
556 | def _moddirs(files): | |
|
557 | """Given a set of modified files, find the list of modified directories. | |
|
558 | ||
|
559 | This returns a list of (path to changed dir, changed dir) tuples, | |
|
560 | as that's what the one client needs anyway. | |
|
561 | ||
|
562 | >>> _moddirs(['a/b/c.py', 'a/b/c.txt', 'a/d/e/f/g.txt', 'i.txt', ]) | |
|
563 | [('/', 'a/'), ('a/', 'b/'), ('a/', 'd/'), ('a/d/', 'e/'), ('a/d/e/', 'f/')] | |
|
564 | ||
|
565 | """ | |
|
566 | alldirs = set() | |
|
567 | for f in files: | |
|
568 | path = f.split('/')[:-1] | |
|
569 | for i in xrange(len(path) - 1, -1, -1): | |
|
570 | dn = '/'.join(path[:i]) | |
|
571 | current = dn + '/', path[i] + '/' | |
|
572 | if current in alldirs: | |
|
573 | break | |
|
574 | alldirs.add(current) | |
|
575 | return sorted(alldirs) | |
|
576 | ||
|
577 | 556 | class cg1packer(object): |
|
578 | 557 | deltaheader = _CHANGEGROUPV1_DELTA_HEADER |
|
579 | 558 | version = '01' |
@@ -755,7 +734,7 b' class cg1packer(object):' | |||
|
755 | 734 | def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs, |
|
756 | 735 | mfchangedfiles, fnodes): |
|
757 | 736 | repo = self._repo |
|
758 |
|
|
|
737 | dirlog = repo.manifest.dirlog | |
|
759 | 738 | tmfnodes = {'': mfs} |
|
760 | 739 | |
|
761 | 740 | # Callback for the manifest, used to collect linkrevs for filelog |
@@ -766,9 +745,6 b' class cg1packer(object):' | |||
|
766 | 745 | assert not dir |
|
767 | 746 | return mfs.__getitem__ |
|
768 | 747 | |
|
769 | if dir: | |
|
770 | return tmfnodes[dir].get | |
|
771 | ||
|
772 | 748 | def lookupmflinknode(x): |
|
773 | 749 | """Callback for looking up the linknode for manifests. |
|
774 | 750 | |
@@ -785,18 +761,23 b' class cg1packer(object):' | |||
|
785 | 761 | the client before you can trust the list of files and |
|
786 | 762 | treemanifests to send. |
|
787 | 763 | """ |
|
788 | clnode = mfs[x] | |
|
789 | # We no longer actually care about reading deltas of | |
|
790 | # the manifest here, because we already know the list | |
|
791 | # of changed files, so for treemanifests (which | |
|
792 | # lazily-load anyway to *generate* a readdelta) we can | |
|
793 | # just load them with read() and then we'll actually | |
|
794 | # be able to correctly load node IDs from the | |
|
795 | # submanifest entries. | |
|
764 | clnode = tmfnodes[dir][x] | |
|
765 | mdata = dirlog(dir).readshallowfast(x) | |
|
796 | 766 | if 'treemanifest' in repo.requirements: |
|
797 |
mdata |
|
|
767 | for p, n, fl in mdata.iterentries(): | |
|
768 | if fl == 't': # subdirectory manifest | |
|
769 | subdir = dir + p + '/' | |
|
770 | tmfclnodes = tmfnodes.setdefault(subdir, {}) | |
|
771 | tmfclnode = tmfclnodes.setdefault(n, clnode) | |
|
772 | if clrevorder[clnode] < clrevorder[tmfclnode]: | |
|
773 | tmfclnodes[n] = clnode | |
|
798 | 774 | else: |
|
799 | mdata = ml.readfast(x) | |
|
775 | f = dir + p | |
|
776 | fclnodes = fnodes.setdefault(f, {}) | |
|
777 | fclnode = fclnodes.setdefault(n, clnode) | |
|
778 | if clrevorder[clnode] < clrevorder[fclnode]: | |
|
779 | fclnodes[n] = clnode | |
|
780 | else: | |
|
800 | 781 | for f in mfchangedfiles[x]: |
|
801 | 782 | try: |
|
802 | 783 | n = mdata[f] |
@@ -808,20 +789,6 b' class cg1packer(object):' | |||
|
808 | 789 | fclnode = fclnodes.setdefault(n, clnode) |
|
809 | 790 | if clrevorder[clnode] < clrevorder[fclnode]: |
|
810 | 791 | fclnodes[n] = clnode |
|
811 | # gather list of changed treemanifest nodes | |
|
812 | if 'treemanifest' in repo.requirements: | |
|
813 | submfs = {'/': mdata} | |
|
814 | for dn, bn in _moddirs(mfchangedfiles[x]): | |
|
815 | try: | |
|
816 | submf = submfs[dn] | |
|
817 | submf = submf._dirs[bn] | |
|
818 | except KeyError: | |
|
819 | continue # deleted directory, so nothing to send | |
|
820 | submfs[submf.dir()] = submf | |
|
821 | tmfclnodes = tmfnodes.setdefault(submf.dir(), {}) | |
|
822 | tmfclnode = tmfclnodes.setdefault(submf._node, clnode) | |
|
823 | if clrevorder[clnode] < clrevorder[tmfclnode]: | |
|
824 | tmfclnodes[n] = clnode | |
|
825 | 792 | return clnode |
|
826 | 793 | return lookupmflinknode |
|
827 | 794 | |
@@ -829,7 +796,7 b' class cg1packer(object):' | |||
|
829 | 796 | while tmfnodes: |
|
830 | 797 | dir = min(tmfnodes) |
|
831 | 798 | nodes = tmfnodes[dir] |
|
832 |
prunednodes = self.prune( |
|
|
799 | prunednodes = self.prune(dirlog(dir), nodes, commonrevs) | |
|
833 | 800 | for x in self._packmanifests(dir, prunednodes, |
|
834 | 801 | makelookupmflinknode(dir)): |
|
835 | 802 | size += len(x) |
@@ -985,6 +985,15 b' class manifest(revlog.revlog):' | |||
|
985 | 985 | return self.readdelta(node) |
|
986 | 986 | return self.read(node) |
|
987 | 987 | |
|
988 | def readshallowfast(self, node): | |
|
989 | '''like readfast(), but calls readshallowdelta() instead of readdelta() | |
|
990 | ''' | |
|
991 | r = self.rev(node) | |
|
992 | deltaparent = self.deltaparent(r) | |
|
993 | if deltaparent != revlog.nullrev and deltaparent in self.parentrevs(r): | |
|
994 | return self.readshallowdelta(node) | |
|
995 | return self.readshallow(node) | |
|
996 | ||
|
988 | 997 | def read(self, node): |
|
989 | 998 | if node == revlog.nullid: |
|
990 | 999 | return self._newmanifest() # don't upset local cache |
@@ -1006,6 +1015,13 b' class manifest(revlog.revlog):' | |||
|
1006 | 1015 | self._mancache[node] = (m, arraytext) |
|
1007 | 1016 | return m |
|
1008 | 1017 | |
|
1018 | def readshallow(self, node): | |
|
1019 | '''Reads the manifest in this directory. When using flat manifests, | |
|
1020 | this manifest will generally have files in subdirectories in it. Does | |
|
1021 | not cache the manifest as the callers generally do not read the same | |
|
1022 | version twice.''' | |
|
1023 | return manifestdict(self.revision(node)) | |
|
1024 | ||
|
1009 | 1025 | def find(self, node, f): |
|
1010 | 1026 | '''look up entry for a single file efficiently. |
|
1011 | 1027 | return (node, flags) pair if found, (None, None) if not.''' |
@@ -363,6 +363,13 b' Pushing to an empty repo works' | |||
|
363 | 363 | added 11 changesets with 15 changes to 10 files (+3 heads) |
|
364 | 364 | $ grep treemanifest clone/.hg/requires |
|
365 | 365 | treemanifest |
|
366 | $ hg -R clone verify | |
|
367 | checking changesets | |
|
368 | checking manifests | |
|
369 | checking directory manifests | |
|
370 | crosschecking files in changesets and manifests | |
|
371 | checking files | |
|
372 | 10 files, 11 changesets, 15 total revisions | |
|
366 | 373 | |
|
367 | 374 | Create deeper repo with tree manifests. |
|
368 | 375 |
General Comments 0
You need to be logged in to leave comments.
Login now