Show More
@@ -553,27 +553,6 b' class headerlessfixup(object):' | |||||
553 | return d |
|
553 | return d | |
554 | return readexactly(self._fh, n) |
|
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 | class cg1packer(object): |
|
556 | class cg1packer(object): | |
578 | deltaheader = _CHANGEGROUPV1_DELTA_HEADER |
|
557 | deltaheader = _CHANGEGROUPV1_DELTA_HEADER | |
579 | version = '01' |
|
558 | version = '01' | |
@@ -755,7 +734,7 b' class cg1packer(object):' | |||||
755 | def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs, |
|
734 | def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs, | |
756 | mfchangedfiles, fnodes): |
|
735 | mfchangedfiles, fnodes): | |
757 | repo = self._repo |
|
736 | repo = self._repo | |
758 |
|
|
737 | dirlog = repo.manifest.dirlog | |
759 | tmfnodes = {'': mfs} |
|
738 | tmfnodes = {'': mfs} | |
760 |
|
739 | |||
761 | # Callback for the manifest, used to collect linkrevs for filelog |
|
740 | # Callback for the manifest, used to collect linkrevs for filelog | |
@@ -766,9 +745,6 b' class cg1packer(object):' | |||||
766 | assert not dir |
|
745 | assert not dir | |
767 | return mfs.__getitem__ |
|
746 | return mfs.__getitem__ | |
768 |
|
747 | |||
769 | if dir: |
|
|||
770 | return tmfnodes[dir].get |
|
|||
771 |
|
||||
772 | def lookupmflinknode(x): |
|
748 | def lookupmflinknode(x): | |
773 | """Callback for looking up the linknode for manifests. |
|
749 | """Callback for looking up the linknode for manifests. | |
774 |
|
750 | |||
@@ -785,43 +761,34 b' class cg1packer(object):' | |||||
785 | the client before you can trust the list of files and |
|
761 | the client before you can trust the list of files and | |
786 | treemanifests to send. |
|
762 | treemanifests to send. | |
787 | """ |
|
763 | """ | |
788 | clnode = mfs[x] |
|
764 | clnode = tmfnodes[dir][x] | |
789 | # We no longer actually care about reading deltas of |
|
765 | mdata = dirlog(dir).readshallowfast(x) | |
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. |
|
|||
796 | if 'treemanifest' in repo.requirements: |
|
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 | |||
|
774 | else: | |||
|
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 | |||
798 | else: |
|
780 | else: | |
799 |
|
|
781 | for f in mfchangedfiles[x]: | |
800 | for f in mfchangedfiles[x]: |
|
|||
801 | try: |
|
|||
802 | n = mdata[f] |
|
|||
803 | except KeyError: |
|
|||
804 | continue |
|
|||
805 | # record the first changeset introducing this filelog |
|
|||
806 | # version |
|
|||
807 | fclnodes = fnodes.setdefault(f, {}) |
|
|||
808 | fclnode = fclnodes.setdefault(n, clnode) |
|
|||
809 | if clrevorder[clnode] < clrevorder[fclnode]: |
|
|||
810 | 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: |
|
782 | try: | |
816 |
|
|
783 | n = mdata[f] | |
817 | submf = submf._dirs[bn] |
|
|||
818 | except KeyError: |
|
784 | except KeyError: | |
819 |
continue |
|
785 | continue | |
820 | submfs[submf.dir()] = submf |
|
786 | # record the first changeset introducing this filelog | |
821 | tmfclnodes = tmfnodes.setdefault(submf.dir(), {}) |
|
787 | # version | |
822 |
|
|
788 | fclnodes = fnodes.setdefault(f, {}) | |
823 | if clrevorder[clnode] < clrevorder[tmfclnode]: |
|
789 | fclnode = fclnodes.setdefault(n, clnode) | |
824 | tmfclnodes[n] = clnode |
|
790 | if clrevorder[clnode] < clrevorder[fclnode]: | |
|
791 | fclnodes[n] = clnode | |||
825 | return clnode |
|
792 | return clnode | |
826 | return lookupmflinknode |
|
793 | return lookupmflinknode | |
827 |
|
794 | |||
@@ -829,7 +796,7 b' class cg1packer(object):' | |||||
829 | while tmfnodes: |
|
796 | while tmfnodes: | |
830 | dir = min(tmfnodes) |
|
797 | dir = min(tmfnodes) | |
831 | nodes = tmfnodes[dir] |
|
798 | nodes = tmfnodes[dir] | |
832 |
prunednodes = self.prune( |
|
799 | prunednodes = self.prune(dirlog(dir), nodes, commonrevs) | |
833 | for x in self._packmanifests(dir, prunednodes, |
|
800 | for x in self._packmanifests(dir, prunednodes, | |
834 | makelookupmflinknode(dir)): |
|
801 | makelookupmflinknode(dir)): | |
835 | size += len(x) |
|
802 | size += len(x) |
@@ -985,6 +985,15 b' class manifest(revlog.revlog):' | |||||
985 | return self.readdelta(node) |
|
985 | return self.readdelta(node) | |
986 | return self.read(node) |
|
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 | def read(self, node): |
|
997 | def read(self, node): | |
989 | if node == revlog.nullid: |
|
998 | if node == revlog.nullid: | |
990 | return self._newmanifest() # don't upset local cache |
|
999 | return self._newmanifest() # don't upset local cache | |
@@ -1006,6 +1015,13 b' class manifest(revlog.revlog):' | |||||
1006 | self._mancache[node] = (m, arraytext) |
|
1015 | self._mancache[node] = (m, arraytext) | |
1007 | return m |
|
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 | def find(self, node, f): |
|
1025 | def find(self, node, f): | |
1010 | '''look up entry for a single file efficiently. |
|
1026 | '''look up entry for a single file efficiently. | |
1011 | return (node, flags) pair if found, (None, None) if not.''' |
|
1027 | return (node, flags) pair if found, (None, None) if not.''' |
@@ -363,6 +363,13 b' Pushing to an empty repo works' | |||||
363 | added 11 changesets with 15 changes to 10 files (+3 heads) |
|
363 | added 11 changesets with 15 changes to 10 files (+3 heads) | |
364 | $ grep treemanifest clone/.hg/requires |
|
364 | $ grep treemanifest clone/.hg/requires | |
365 | treemanifest |
|
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 | Create deeper repo with tree manifests. |
|
374 | Create deeper repo with tree manifests. | |
368 |
|
375 |
General Comments 0
You need to be logged in to leave comments.
Login now