Missed Change on commit

Robin Farine robin.farine at terminus.org
Thu Feb 15 14:20:47 CST 2007


On Thursday February 15 2007 20:08, Matt Mackall wrote:
> On Thu, Feb 15, 2007 at 10:47:37AM -0700, Russell Suter wrote:
> > Hi All,
> >
> > I have an example where a commit is missing a change.  I've
> > attached a script and the output that (for me) always breaks. 
> > Specifically, in the output the commit didn't pickup the branch
> > 2 version 1 change:
>
> Mercurial can miss a change if the change happens so quickly that
> it doesn't change the timestamp or the size that we recorded for
> the file.

> Possible fixes:
>
> a) wait until the next second after recording dirstate
>    this will catch any changes made after update but will
> penalize everyone by a half second per add/merge/update...

Tried this, it becomes extremely painful to run the tests.

How about verifying each file with an mtime equal to the mtime of 
the dirstate file itself? This would catch files changed in the 
same second as the dirstate has been updated. Something like this:

diff -r 5b1f663ef86d mercurial/dirstate.py
--- a/mercurial/dirstate.py	Tue Feb 06 16:12:22 2007 -0600
+++ b/mercurial/dirstate.py	Thu Feb 15 21:05:52 2007 +0100
@@ -24,6 +24,7 @@ class dirstate(object):
         self.dirs = None
         self.copymap = {}
         self.ignorefunc = None
+        self.mtime = 0
 
     def wjoin(self, f):
         return os.path.join(self.root, f)
@@ -184,9 +185,11 @@ class dirstate(object):
         self.map = {}
         self.pl = [nullid, nullid]
         try:
-            st = self.opener("dirstate").read()
+            fp = self.opener("dirstate")
+            st = fp.read()
             if st:
                 self.parse(st)
+                self.mtime = util.fstat(fp).st_mtime
         except IOError, err:
             if err.errno != errno.ENOENT: raise
 
@@ -305,6 +308,7 @@ class dirstate(object):
             e = struct.pack(self.format, e[0], e[1], e[2], e[3], 
len(f))
             st.write(e + f)
         self.dirty = 0
+        self.mtime = util.fstat(st).st_mtime
 
     def filterfiles(self, files):
         ret = {}
@@ -516,6 +520,8 @@ class dirstate(object):
                     modified.append(fn)
                 elif time != int(st.st_mtime):
                     lookup.append(fn)
+                elif self.mtime == int(st.st_mtime):
+                    lookup.append(fn)
                 elif list_clean:
                     clean.append(fn)
             elif type_ == 'm':


More information about the Mercurial-devel mailing list