diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1957,6 +1957,7 @@ for f in self.removed(): self._repo.dirstate.drop(f) self._repo.dirstate.setparents(node) + self._repo._quick_access_changeid_invalidate() # write changes out explicitly, because nesting wlock at # runtime may prevent 'wlock.release()' in 'repo.commit()' diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1514,18 +1514,51 @@ narrowspec.save(self, newincludes, newexcludes) self.invalidate(clearfilecache=True) - @util.propertycache + @unfilteredpropertycache + def _quick_access_changeid_null(self): + return { + b'null': (nullrev, nullid), + nullrev: (nullrev, nullid), + nullid: (nullrev, nullid), + } + + @unfilteredpropertycache + def _quick_access_changeid_wc(self): + # also fast path access to the working copy parents + # however, only do it for filter that ensure wc is visible. + quick = {} + cl = self.unfiltered().changelog + for node in self.dirstate.parents(): + if node == nullid: + continue + rev = cl.index.get_rev(node) + if rev is None: + # unknown working copy parent case: + # + # skip the fast path and let higher code deal with it + continue + pair = (rev, node) + quick[rev] = pair + quick[node] = pair + return quick + + @unfilteredmethod + def _quick_access_changeid_invalidate(self): + if '_quick_access_changeid_wc' in vars(self): + del self.__dict__['_quick_access_changeid_wc'] + + @property def _quick_access_changeid(self): """an helper dictionnary for __getitem__ calls This contains a list of symbol we can recognise right away without further processing. """ - return { - b'null': (nullrev, nullid), - nullrev: (nullrev, nullid), - nullid: (nullrev, nullid), - } + mapping = self._quick_access_changeid_null + if self.filtername in repoview.filter_has_wc: + mapping = mapping.copy() + mapping.update(self._quick_access_changeid_wc) + return mapping def __getitem__(self, changeid): # dealing with special cases @@ -1897,6 +1930,7 @@ for f, s in sorted(self.dirstate.copies().items()): if f not in pctx and s not in pctx: self.dirstate.copy(None, f) + self._quick_access_changeid_invalidate() def filectx(self, path, changeid=None, fileid=None, changectx=None): """changeid must be a changeset revision, if specified. @@ -2494,6 +2528,7 @@ def invalidatevolatilesets(self): self.filteredrevcache.clear() obsolete.clearobscaches(self) + self._quick_access_changeid_invalidate() def invalidatedirstate(self): '''Invalidates the dirstate, causing the next call to dirstate diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -1463,6 +1463,7 @@ if src not in newctx or dst in newctx or ds[dst] != b'a': src = None ds.copy(src, dst) + repo._quick_access_changeid_invalidate() def writerequires(opener, requirements): diff --git a/tests/test-repo-filters-tiptoe.t b/tests/test-repo-filters-tiptoe.t --- a/tests/test-repo-filters-tiptoe.t +++ b/tests/test-repo-filters-tiptoe.t @@ -62,7 +62,6 @@ Getting status of working copy $ hg status - debug.filters: computing revision filter for "visible" M c A d R a @@ -78,7 +77,6 @@ Getting working copy diff $ hg diff - debug.filters: computing revision filter for "visible" diff -r c2932ca7786be30b67154d541a8764fae5532261 a --- a/a Thu Jan 01 00:00:00 1970 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000