[PATCH V6] dirstate: avoid a race with multiple commits in the same process

Adrian Buehlmann adrian at cadifra.com
Mon Mar 21 09:08:35 CDT 2011


On 2011-03-21 12:53, Adrian Buehlmann wrote:
> local.status does a full compare for files that need to be looked into,
> which IIUC now includes the files in self._lastnormal (see
> dirstate.status() ).
> 
> localrepo.status calls self.dirstate.normal(f) for the files that
> content-compare equal (list "fixup").
> 
> Maybe there should be a way to say "this file is *really* normal, we've
> even compared file contents". I think such files shouldn't be added to
> _lastnormal, so they are not content-compared again and again on every
> localrepo.status() call.
> 
> ?

Perhaps something like:

diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -277,7 +277,7 @@ class dirstate(object):
         if oldstate in "?r" and "_dirs" in self.__dict__:
             _incdirs(self._dirs, f)

-    def normal(self, f):
+    def normal(self, f, fixup=False):
         '''Mark a file normal and clean.'''
         self._dirty = True
         self._addpath(f)
@@ -286,11 +286,14 @@ class dirstate(object):
         if f in self._copymap:
             del self._copymap[f]

-        # Right now, this file is clean: but if some code in this
-        # process modifies it without changing its size before the clock
-        # ticks over to the next second, then it won't be clean anymore.
-        # So make sure that status() will look harder at it.
-        self._lastnormal.add(f)
+        if fixup:
+            self._lastnormal.discard(f)
+        else:
+            # Right now, this file is clean: but if some code in this
+            # process modifies it without changing its size before the clock
+            # ticks over to the next second, then it won't be clean anymore.
+            # So make sure that status() will look harder at it.
+            self._lastnormal.add(f)

     def normallookup(self, f):
         '''Mark a file normal, but possibly dirty.'''
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1195,7 +1195,7 @@ class localrepository(repo.repository):
                         wlock = self.wlock(False)
                         try:
                             for f in fixup:
-                                self.dirstate.normal(f)
+                                self.dirstate.normal(f, fixup=True)
                         finally:
                             wlock.release()
                     except error.LockError:


More information about the Mercurial-devel mailing list