From patchwork Mon Dec 17 15:35:26 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [01, of, 12] localrepo: don't refresh filecache entries that aren't in __dict__ From: Idan Kamara X-Patchwork-Id: 155 Message-Id: Date: Mon, 17 Dec 2012 17:35:26 +0200 # HG changeset patch # User Idan Kamara # Date 1355692382 -7200 # Branch stable # Node ID de2d114accfcda2d867c65ef9bfc068d5614a8f7 # Parent 75544dacf843e2e7ba16de0cc48e7e8d52713494 localrepo: don't refresh filecache entries that aren't in __dict__ We call invalidate to remove properties from __dict__ because they're possibly outdated and we'd like to check for a new version. Next time the property is accessed the filecache mechanism checks the current stat info with the one recorded at the last time the property was read, if they're different it recreates the property. Previously we refreshed the stat info on all properties in the filecache when the lock is released, including properties that are missing from __dict__. This is a problem because: l = repo.lock() repo.P # stat info S for P is recorded in _filecache # P's new stat info = S' l.release() # filecache refreshes, records S' as P's stat info At this point our filecache contains P with stat info S', but P's version is from S, which is outdated. The above happens during _rollback and strip. Currently we're wiping the filecache and forcing everything to reload from scratch which works but isn't the right solution. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1114,7 +1114,7 @@ if '_phasecache' in vars(self): self._phasecache.write() for k, ce in self._filecache.items(): - if k == 'dirstate': + if k == 'dirstate' or k not in self.__dict__: continue ce.refresh()