dirstate: delay writing out to ensure timestamp of each entries explicitly
Even though "dirstate.write()" is invoked explicitly after "normal"
invocations, timestamp field of entries may be still "unset" in the
"dirstate" file itself , because "pack_dirstate" drops it when it is
equal to the timestamp of "dirstate" file itself.
This can avoid overlooking modification of files, which are updated at
same time in the second. But on the other hand, this may hide timing
critical problems.
For example, incorrect "normal"-ing (or lack of "normallookup"-ing on
the already "normal"-ed entry) is visible only when:
- the target file is modified in the working directory at T1, and
- "dirstate" file is written out at T2 (!= T1)
Otherwise, T1 is dropped by "pack_dirstate" in "dirstate.write()"
invocation, and "unset" is stored into "dirstate" file.
It often fails to reproduce problems from incorrect "normal"-ing by
Mercurial testset, because automated actions in the small repository
almost always causes that T1 and T2 are same.
This patch adds the debug feature to delay writing out to ensure
timestamp of each entries explicitly.
This feature is used to make timing critical "dirstate" problems
reproducable in subsequent patches.
--- a/mercurial/dirstate.py Mon Jul 21 11:27:24 2014 -0700
+++ b/mercurial/dirstate.py Tue Jul 22 23:59:30 2014 +0900
@@ -504,6 +504,14 @@
def write(self):
if not self._dirty:
return
+
+ # enough 'delaywrite' prevents 'pack_dirstate' from dropping
+ # timestamp of each entries in dirstate, because of 'now > mtime'
+ delaywrite = self._ui.configint('debug', 'dirstate.delaywrite', 0)
+ if delaywrite:
+ import time # to avoid useless import
+ time.sleep(delaywrite)
+
st = self._opener("dirstate", "w", atomictemp=True)
# use the modification time of the newly created temporary file as the
# filesystem's notion of 'now'