dirstate: delay writing out to ensure timestamp of each entries explicitly stable
authorFUJIWARA Katsunori <foozy@lares.dti.ne.jp>
Tue, 22 Jul 2014 23:59:30 +0900
branchstable
changeset 21931 89b809fa6cef
parent 21930 a5168eb9b2bc
child 21932 21a2f31f054d
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.
mercurial/dirstate.py
--- 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'