[PATCH 05 of 10 v2] destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara
idankk86 at gmail.com
Thu Jan 10 16:10:52 CST 2013
# HG changeset patch
# User Idan Kamara <idankk86 at gmail.com>
# Date 1357756664 -7200
# Node ID 1f3fe4ea7561adb4fd43b39bc01dd5533e0e2f6e
# Parent d995557a854b835d65b3cde1d4ca5eaa2666471e
destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
We need to make sure that if X is in the filecache then it's also in the
filecache owner's __dict__, otherwise it will go out of sync:
repo.X # first access to X, records stat info in filecache and updates __dict__
repo._filecache.clear() # removes X from _filecache but it's still in __dict__
repo.invalidate() # iterates over _filecache and removes entries from __dict__
# but X isn't in _filecache, so it's kept in __dict__
repo.X # X is fetched from __dict__, bypassing the filecache
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1446,10 +1446,7 @@
# head, refresh the tag cache, then immediately add a new head.
# But I think doing it this way is necessary for the "instant
# tag cache retrieval" case to work.
- self.invalidatecaches()
-
- # Discard all cache entries to force reloading everything.
- self._filecache.clear()
+ self.invalidate()
def walk(self, match, node=None):
'''
diff --git a/tests/test-filecache.py b/tests/test-filecache.py
--- a/tests/test-filecache.py
+++ b/tests/test-filecache.py
@@ -4,7 +4,7 @@
'cacheable']):
sys.exit(80)
-from mercurial import util, scmutil, extensions
+from mercurial import util, scmutil, extensions, hg, ui
filecache = scmutil.filecache
@@ -86,6 +86,21 @@
util.cachestat.cacheable = origcacheable
util.cachestat.__init__ = originit
+def test_filecache_synced():
+ # test old behaviour that caused filecached properties to go out of sync
+ os.system('hg init && echo a >> a && hg ci -qAm.')
+ repo = hg.repository(ui.ui())
+ # first rollback clears the filecache, but changelog to stays in __dict__
+ repo.rollback()
+ repo.commit('.')
+ # second rollback comes along and touches the changelog externally
+ # (file is moved)
+ repo.rollback()
+ # but since changelog isn't under the filecache control anymore, we don't
+ # see that it changed, and return the old changelog without reconstructing
+ # it
+ repo.commit('.')
+
print 'basic:'
print
basic(fakerepo())
@@ -93,3 +108,4 @@
print 'fakeuncacheable:'
print
fakeuncacheable()
+test_filecache_synced()
diff --git a/tests/test-filecache.py.out b/tests/test-filecache.py.out
--- a/tests/test-filecache.py.out
+++ b/tests/test-filecache.py.out
@@ -13,3 +13,7 @@
creating
creating
creating
+repository tip rolled back to revision -1 (undo commit)
+working directory now based on revision -1
+repository tip rolled back to revision -1 (undo commit)
+working directory now based on revision -1
More information about the Mercurial-devel
mailing list