# HG changeset patch # User Durham Goode # Date 1506423380 25200 # Node ID ec769bba34d377503f42308dea5ddcb8ce4c0ade # Parent 0c3e3810cdb60b70db3e301225c7af584fc478b0 dirstate: move parents source of truth to dirstatemap As part of moving dirstate storage to its own class, let's move the source of truth for the dirstate parents to dirstatemap. This requires that dirstate._pl no longer be a cache, and that all sets go through dirstatemap.setparents. Differential Revision: https://phab.mercurial-scm.org/D759 diff -r 0c3e3810cdb6 -r ec769bba34d3 mercurial/dirstate.py --- a/mercurial/dirstate.py Tue Sep 26 03:56:20 2017 -0700 +++ b/mercurial/dirstate.py Tue Sep 26 03:56:20 2017 -0700 @@ -71,7 +71,6 @@ # UNC path pointing to root share (issue4557) self._rootdir = pathutil.normasprefix(root) self._dirty = False - self._dirtypl = False self._lastnormaltime = 0 self._ui = ui self._filecache = {} @@ -184,7 +183,7 @@ raise return "default" - @propertycache + @property def _pl(self): return self._map.parents() @@ -343,11 +342,11 @@ raise ValueError("cannot set dirstate parent without " "calling dirstate.beginparentchange") - self._dirty = self._dirtypl = True + self._dirty = True oldp2 = self._pl[1] if self._origpl is None: self._origpl = self._pl - self._pl = p1, p2 + self._map.setparents(p1, p2) copies = {} if oldp2 != nullid and p2 == nullid: candidatefiles = self._nonnormalset.union(self._otherparentset) @@ -432,8 +431,8 @@ # (we cannot decorate the function directly since it is in a C module) parse_dirstate = util.nogc(parsers.parse_dirstate) p = parse_dirstate(self._map._map, self._map.copymap, st) - if not self._dirtypl: - self._pl = p + if not self._map._dirtyparents: + self._map.setparents(*p) def invalidate(self): '''Causes the next access to reread the dirstate. @@ -444,7 +443,7 @@ for a in ("_map", "_identity", "_filefoldmap", "_dirfoldmap", "_branch", - "_pl", "_dirs", "_ignore", "_nonnormalset", + "_dirs", "_ignore", "_nonnormalset", "_otherparentset"): if a in self.__dict__: delattr(self, a) @@ -679,7 +678,7 @@ self._otherparentset = set() if "_dirs" in self.__dict__: delattr(self, "_dirs") - self._pl = [nullid, nullid] + self._map.setparents(nullid, nullid) self._lastnormaltime = 0 self._updatedfiles.clear() self._dirty = True @@ -694,7 +693,7 @@ if self._origpl is None: self._origpl = self._pl - self._pl = (parent, nullid) + self._map.setparents(parent, nullid) for f in changedfiles: if f in allfiles: self.normallookup(f) @@ -787,7 +786,7 @@ self._nonnormalset, self._otherparentset = self._map.nonnormalentries() st.close() self._lastnormaltime = 0 - self._dirty = self._dirtypl = False + self._dirty = self._map._dirtyparents = False def _dirignore(self, f): if f == '.': @@ -1292,6 +1291,8 @@ self._map = {} self.copymap = {} + self._parents = None + self._dirtyparents = False # for consistent view between _pl() and _read() invocations self._pendingmode = None @@ -1370,16 +1371,28 @@ return fp def parents(self): - try: - fp = self._opendirstatefile() - st = fp.read(40) - fp.close() + if not self._parents: + try: + fp = self._opendirstatefile() + st = fp.read(40) + fp.close() + except IOError as err: + if err.errno != errno.ENOENT: + raise + # File doesn't exist, so the current state is empty + st = '' + l = len(st) if l == 40: - return st[:20], st[20:40] - elif l > 0 and l < 40: - raise error.Abort(_('working directory state appears damaged!')) - except IOError as err: - if err.errno != errno.ENOENT: - raise - return [nullid, nullid] + self._parents = st[:20], st[20:40] + elif l == 0: + self._parents = [nullid, nullid] + else: + raise error.Abort(_('working directory state appears ' + 'damaged!')) + + return self._parents + + def setparents(self, p1, p2): + self._parents = (p1, p2) + self._dirtyparents = True