revlog: specify checkambig at writing to avoid file stat ambiguity
This allows revlog-style files to be written out with checkambig=True
easily.
Because avoiding file stat ambiguity is needed only for filecache-ed
manifest and changelog, this patch does:
- use False for default value of checkambig
- focus only on writing changes of index file out
This patch also adds optional argument checkambig to _divert/_delay
for changelog, to safely accept checkambig specified in revlog
layer. But this argument can be fully ignored, because:
- changes are written into other than index file, if name != target
- changes are never written into index file, otherwise
(into pending file by _divert, or into in-memory buffer by _delay)
This is a part of ExactCacheValidationPlan.
https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan
--- a/mercurial/changelog.py Thu Sep 22 21:51:57 2016 +0900
+++ b/mercurial/changelog.py Thu Sep 22 21:51:58 2016 +0900
@@ -124,7 +124,7 @@
def _divertopener(opener, target):
"""build an opener that writes in 'target.a' instead of 'target'"""
- def _divert(name, mode='r'):
+ def _divert(name, mode='r', checkambig=False):
if name != target:
return opener(name, mode)
return opener(name + ".a", mode)
@@ -132,7 +132,7 @@
def _delayopener(opener, target, buf):
"""build an opener that stores chunks in 'buf' instead of 'target'"""
- def _delay(name, mode='r'):
+ def _delay(name, mode='r', checkambig=False):
if name != target:
return opener(name, mode)
return appender(opener, name, mode, buf)
--- a/mercurial/revlog.py Thu Sep 22 21:51:57 2016 +0900
+++ b/mercurial/revlog.py Thu Sep 22 21:51:58 2016 +0900
@@ -212,8 +212,11 @@
fashion, which means we never need to rewrite a file to insert or
remove data, and can use some simple techniques to avoid the need
for locking while reading.
+
+ If checkambig, indexfile is opened with checkambig=True at
+ writing, to avoid file stat ambiguity.
"""
- def __init__(self, opener, indexfile):
+ def __init__(self, opener, indexfile, checkambig=False):
"""
create a revlog object
@@ -223,6 +226,9 @@
self.indexfile = indexfile
self.datafile = indexfile[:-2] + ".d"
self.opener = opener
+ # When True, indexfile is opened with checkambig=True at writing, to
+ # avoid file stat ambiguity.
+ self._checkambig = checkambig
# 3-tuple of (node, rev, text) for a raw revision.
self._cache = None
# Maps rev to chain base rev.
@@ -1276,7 +1282,8 @@
finally:
df.close()
- fp = self.opener(self.indexfile, 'w', atomictemp=True)
+ fp = self.opener(self.indexfile, 'w', atomictemp=True,
+ checkambig=self._checkambig)
self.version &= ~(REVLOGNGINLINEDATA)
self._inline = False
for i in self:
@@ -1319,7 +1326,7 @@
dfh = None
if not self._inline:
dfh = self.opener(self.datafile, "a+")
- ifh = self.opener(self.indexfile, "a+")
+ ifh = self.opener(self.indexfile, "a+", checkambig=self._checkambig)
try:
return self._addrevision(node, text, transaction, link, p1, p2,
REVIDX_DEFAULT_FLAGS, cachedelta, ifh, dfh)
@@ -1567,7 +1574,7 @@
end = 0
if r:
end = self.end(r - 1)
- ifh = self.opener(self.indexfile, "a+")
+ ifh = self.opener(self.indexfile, "a+", checkambig=self._checkambig)
isize = r * self._io.size
if self._inline:
transaction.add(self.indexfile, end + isize, r)
@@ -1641,7 +1648,8 @@
# reopen the index
ifh.close()
dfh = self.opener(self.datafile, "a+")
- ifh = self.opener(self.indexfile, "a+")
+ ifh = self.opener(self.indexfile, "a+",
+ checkambig=self._checkambig)
finally:
if dfh:
dfh.close()