# HG changeset patch # User Pierre-Yves David # Date 1677024505 -3600 # Node ID 2f60cd6442fd4de5dabc76263243776dc74b58ea # Parent ec769cbc1fa21f1f6193ee257dae157c7c3a9be1 dirstate: only reload the dirstate when it may have changed This reinstall the equivalent of what the `filecache` was doing. However it does it at the dirstate level. There is a double motivation for this: - This avoid duplicating logic with the dirstate "identity" logic. - This increase the lifetime of the `dirstate` object, helping to implement change scoping. diff -r ec769cbc1fa2 -r 2f60cd6442fd mercurial/dirstate.py --- a/mercurial/dirstate.py Wed Feb 22 01:04:55 2023 +0100 +++ b/mercurial/dirstate.py Wed Feb 22 01:08:25 2023 +0100 @@ -190,6 +190,12 @@ # raises an exception). self._cwd + def refresh(self): + if '_branch' in vars(self): + del self._branch + if '_map' in vars(self) and self._map.may_need_refresh(): + self.invalidate() + def prefetch_parents(self): """make sure the parents are loaded diff -r ec769cbc1fa2 -r 2f60cd6442fd mercurial/dirstatemap.py --- a/mercurial/dirstatemap.py Wed Feb 22 01:04:55 2023 +0100 +++ b/mercurial/dirstatemap.py Wed Feb 22 01:08:25 2023 +0100 @@ -67,6 +67,25 @@ except FileNotFoundError: return None + def may_need_refresh(self): + if 'identity' not in vars(self): + # no existing identity, we need a refresh + return True + if self.identity is None: + return True + if not self.identity.cacheable(): + # We cannot trust the entry + # XXX this is a problem on windows, NFS, or other inode less system + return True + current_identity = self._get_current_identity() + if current_identity is None: + return True + if not current_identity.cacheable(): + # We cannot trust the entry + # XXX this is a problem on windows, NFS, or other inode less system + return True + return current_identity != self.identity + def preload(self): """Loads the underlying data, if it's not already loaded""" self._map diff -r ec769cbc1fa2 -r 2f60cd6442fd mercurial/localrepo.py --- a/mercurial/localrepo.py Wed Feb 22 01:04:55 2023 +0100 +++ b/mercurial/localrepo.py Wed Feb 22 01:08:25 2023 +0100 @@ -1465,6 +1465,7 @@ # - bookmark changes self.filteredrevcache = {} + self._dirstate = None # post-dirstate-status hooks self._postdsstatus = [] @@ -1752,9 +1753,11 @@ @unfilteredpropertycache def dirstate(self): - # XXX This is known to be missing smarter caching. Check the next - # changesets - return self._makedirstate() + if self._dirstate is None: + self._dirstate = self._makedirstate() + else: + self._dirstate.refresh() + return self._dirstate def _makedirstate(self): """Extension point for wrapping the dirstate per-repo.""" diff -r ec769cbc1fa2 -r 2f60cd6442fd mercurial/statichttprepo.py --- a/mercurial/statichttprepo.py Wed Feb 22 01:04:55 2023 +0100 +++ b/mercurial/statichttprepo.py Wed Feb 22 01:08:25 2023 +0100 @@ -225,6 +225,7 @@ self.encodepats = None self.decodepats = None self._transref = None + self._dirstate = None def _restrictcapabilities(self, caps): caps = super(statichttprepository, self)._restrictcapabilities(caps)