localrepo: make _refreshfilecachestats unfiltered method to refresh correctly
Before this patch, if transaction is started via "filtered repo"
object, _refreshfilecachestats() at closing transaction doesn't
refresh file stat of any @filecache properties correctly, because:
- _refreshfilecachestats() omits refreshing file stat of a
@filecache property, if it doesn't appear in self.__dict__
- if transaction is started via "filtered repo",
_refreshfilecachestats() is applied on "filtered repo"
because repo.transaction() adds "self._refreshfilecachestats" to
post close procedures. repo.transaction() isn't unfiltered method,
and "self" in it means "filtered repo" in this case.
Transactions started by explicit repo.transaction() easily causes
this situation.
- _refreshfilecachestats() applied on "filtered repo" omits whole
refreshing
because @filecache properties are stored into "unfiltered repo",
and appear only in self.__dict__ of "unfiltered repo".
This incorrect refreshing causes unnecessary reloading from files.
To refresh file stat of @filecache properties at closing transaction
correctly, this patch makes _refreshfilecachestats() unfiltered
method.
This patch chooses making _refreshfilecachestats() unfiltered method
instead of making transaction() unfiltered method, to reduce
unexpected side effect.
#!/usr/bin/env python
# Undump a dump from dumprevlog
# $ hg init
# $ undumprevlog < repo.dump
from __future__ import absolute_import
import sys
from mercurial import (
node,
revlog,
scmutil,
transaction,
util,
)
for fp in (sys.stdin, sys.stdout, sys.stderr):
util.setbinary(fp)
opener = scmutil.opener('.', False)
tr = transaction.transaction(sys.stderr.write, opener, {'store': opener},
"undump.journal")
while True:
l = sys.stdin.readline()
if not l:
break
if l.startswith("file:"):
f = l[6:-1]
r = revlog.revlog(opener, f)
print f
elif l.startswith("node:"):
n = node.bin(l[6:-1])
elif l.startswith("linkrev:"):
lr = int(l[9:-1])
elif l.startswith("parents:"):
p = l[9:-1].split()
p1 = node.bin(p[0])
p2 = node.bin(p[1])
elif l.startswith("length:"):
length = int(l[8:-1])
sys.stdin.readline() # start marker
d = sys.stdin.read(length)
sys.stdin.readline() # end marker
r.addrevision(d, tr, lr, p1, p2)
tr.close()