##// END OF EJS Templates
changegroup: fix treemanifests on merges...
Martin von Zweigbergk -
r28240:1ac8ce13 default
parent child Browse files
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 ml = repo.manifest
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,43 +761,34 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 = ml.read(x)
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 780 else:
799 mdata = ml.readfast(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]):
781 for f in mfchangedfiles[x]:
815 782 try:
816 submf = submfs[dn]
817 submf = submf._dirs[bn]
783 n = mdata[f]
818 784 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
785 continue
786 # record the first changeset introducing this filelog
787 # version
788 fclnodes = fnodes.setdefault(f, {})
789 fclnode = fclnodes.setdefault(n, clnode)
790 if clrevorder[clnode] < clrevorder[fclnode]:
791 fclnodes[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(ml.dirlog(dir), nodes, commonrevs)
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