[PATCH 1 of 3] dirstate: factor maybelookup() out of write()

Greg Ward greg-hg at gerg.ca
Tue Mar 15 20:39:39 CDT 2011


# HG changeset patch
# User Greg Ward <greg at gerg.ca>
# Date 1300239394 14400
# Node ID c5fa123f60a63af19057e873106c532ee2c553fa
# Parent  0652b2da832daada866a68f7a4359227570c2447
dirstate: factor maybelookup() out of write().

For the moment, this serves no obvious purpose.  But it will be needed
in localrepository.commit() to avoid a subtle dirstate race when there
are multiple commits in the same second from the same process.

diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -391,6 +391,26 @@
         self._pl = (parent, nullid)
         self._dirty = True
 
+    def maybelookup(self, f, now):
+        '''Examine f to determine if it needs more work to determine its
+        true status, or whether it can be considered normal.  If more
+        work needed, set the in-memory state to lookup; otherwise, leave
+        it alone. Thus, maybelookup() can affect the next call to
+        status(). now must be the current time to filesystem resolution.'''
+        e = self._map[f]
+        if e[0] == 'n' and e[3] == now:
+            # The file was last modified "simultaneously" to 'now'
+            # (i.e. within the same second for filesystems with a
+            # granularity of 1 sec). This commonly happens for at least
+            # a couple of files on 'update': the user could then change
+            # the file without changing its size within the same
+            # second. Invalidate the file's stat data in dirstate,
+            # forcing future 'status' calls to compare the contents of
+            # the file. This prevents mistakenly treating such files as
+            # clean.
+            self._map[f] = e = (e[0], 0, -1, -1)   # mark entry as 'unset'
+        return e
+
     def write(self):
         if not self._dirty:
             return
@@ -405,20 +425,8 @@
         pack = struct.pack
         write = cs.write
         write("".join(self._pl))
-        for f, e in self._map.iteritems():
-            if e[0] == 'n' and e[3] == now:
-                # The file was last modified "simultaneously" with the current
-                # write to dirstate (i.e. within the same second for file-
-                # systems with a granularity of 1 sec). This commonly happens
-                # for at least a couple of files on 'update'.
-                # The user could change the file without changing its size
-                # within the same second. Invalidate the file's stat data in
-                # dirstate, forcing future 'status' calls to compare the
-                # contents of the file. This prevents mistakenly treating such
-                # files as clean.
-                e = (e[0], 0, -1, -1)   # mark entry as 'unset'
-                self._map[f] = e
-
+        for f in self._map.iterkeys():
+            e = self.maybelookup(f, now)
             if f in copymap:
                 f = "%s\0%s" % (f, copymap[f])
             e = pack(_format, e[0], e[1], e[2], e[3], len(f))


More information about the Mercurial-devel mailing list