Mercurial > hg
comparison mercurial/manifest.py @ 40039:a0c18b271ea1
treemanifests: store whether a lazydirs entry needs copied after materializing
Due to the way that things like manifestlog.get caches its values, without
making a copy (if necessary) after calling readsubtree(), we might end up
adjusting the state of the same object on different contexts, breaking things
like dirty state tracking (and probably other things).
Differential Revision: https://phab.mercurial-scm.org/D4874
author | spectral <spectral@google.com> |
---|---|
date | Tue, 25 Sep 2018 19:25:41 -0700 |
parents | 906c95073ff7 |
children | 67b93cd847fb |
comparison
equal
deleted
inserted
replaced
40038:906c95073ff7 | 40039:a0c18b271ea1 |
---|---|
699 | 699 |
700 def _subpath(self, path): | 700 def _subpath(self, path): |
701 return self._dir + path | 701 return self._dir + path |
702 | 702 |
703 def _loadalllazy(self): | 703 def _loadalllazy(self): |
704 for k, (path, node, readsubtree) in self._lazydirs.iteritems(): | 704 selfdirs = self._dirs |
705 self._dirs[k] = readsubtree(path, node) | 705 for d, (path, node, readsubtree, docopy) in self._lazydirs.iteritems(): |
706 if docopy: | |
707 selfdirs[d] = readsubtree(path, node).copy() | |
708 else: | |
709 selfdirs[d] = readsubtree(path, node) | |
706 self._lazydirs = {} | 710 self._lazydirs = {} |
707 | 711 |
708 def _loadlazy(self, d): | 712 def _loadlazy(self, d): |
709 v = self._lazydirs.get(d) | 713 v = self._lazydirs.get(d) |
710 if v: | 714 if v: |
711 path, node, readsubtree = v | 715 path, node, readsubtree, docopy = v |
712 self._dirs[d] = readsubtree(path, node) | 716 if docopy: |
717 self._dirs[d] = readsubtree(path, node).copy() | |
718 else: | |
719 self._dirs[d] = readsubtree(path, node) | |
713 del self._lazydirs[d] | 720 del self._lazydirs[d] |
714 | 721 |
715 def _loadchildrensetlazy(self, visit): | 722 def _loadchildrensetlazy(self, visit): |
716 if not visit: | 723 if not visit: |
717 return None | 724 return None |
1168 selflazy = self._lazydirs | 1175 selflazy = self._lazydirs |
1169 subpath = self._subpath | 1176 subpath = self._subpath |
1170 for f, n, fl in _parse(text): | 1177 for f, n, fl in _parse(text): |
1171 if fl == 't': | 1178 if fl == 't': |
1172 f = f + '/' | 1179 f = f + '/' |
1173 selflazy[f] = (subpath(f), n, readsubtree) | 1180 # False below means "doesn't need to be copied" and can use the |
1181 # cached value from readsubtree directly. | |
1182 selflazy[f] = (subpath(f), n, readsubtree, False) | |
1174 elif '/' in f: | 1183 elif '/' in f: |
1175 # This is a flat manifest, so use __setitem__ and setflag rather | 1184 # This is a flat manifest, so use __setitem__ and setflag rather |
1176 # than assigning directly to _files and _flags, so we can | 1185 # than assigning directly to _files and _flags, so we can |
1177 # assign a path in a subdirectory, and to mark dirty (compared | 1186 # assign a path in a subdirectory, and to mark dirty (compared |
1178 # to nullid). | 1187 # to nullid). |
1195 """Get the full data of this directory as a bytestring. Make sure that | 1204 """Get the full data of this directory as a bytestring. Make sure that |
1196 any submanifests have been written first, so their nodeids are correct. | 1205 any submanifests have been written first, so their nodeids are correct. |
1197 """ | 1206 """ |
1198 self._load() | 1207 self._load() |
1199 flags = self.flags | 1208 flags = self.flags |
1200 lazydirs = [(d[:-1], node, 't') for | 1209 lazydirs = [(d[:-1], v[1], 't') for d, v in self._lazydirs.iteritems()] |
1201 d, (path, node, readsubtree) in self._lazydirs.iteritems()] | |
1202 dirs = [(d[:-1], self._dirs[d]._node, 't') for d in self._dirs] | 1210 dirs = [(d[:-1], self._dirs[d]._node, 't') for d in self._dirs] |
1203 files = [(f, self._files[f], flags(f)) for f in self._files] | 1211 files = [(f, self._files[f], flags(f)) for f in self._files] |
1204 return _text(sorted(dirs + files + lazydirs)) | 1212 return _text(sorted(dirs + files + lazydirs)) |
1205 | 1213 |
1206 def read(self, gettext, readsubtree): | 1214 def read(self, gettext, readsubtree): |