dirstate: ignore stat data for files that were updated too recently

This should fix the race where

  hg commit foo
  <change foo without changing its size>

happens in the same second and status is fooled into thinking foo
is clean.

A configuration item is used to determine the timeout, since different
filesystems may have different requirements (I think VFAT needs 3s,
while most Unix filesystems are fine with 1s).
This commit is contained in:
Alexis S. L. Carvalho 2008-03-19 17:55:21 -03:00
parent 4794cecf39
commit d40b29d203
3 changed files with 19 additions and 7 deletions

View File

@ -10,7 +10,7 @@ of the GNU General Public License, incorporated herein by reference.
from node import nullid
from i18n import _
import struct, os, bisect, stat, strutil, util, errno, ignore
import cStringIO, osutil
import cStringIO, osutil, sys
_unknown = ('?', 0, 0, 0)
_format = ">cllll"
@ -66,6 +66,12 @@ class dirstate(object):
elif name == '_checkexec':
self._checkexec = util.checkexec(self._root)
return self._checkexec
elif name == '_limit':
try:
self._limit = int(self._ui.config('ui', 'limit', 1))
except ValueError:
self._limit = 1
return self._limit
else:
raise AttributeError, name
@ -335,6 +341,11 @@ class dirstate(object):
def write(self):
if not self._dirty:
return
st = self._opener("dirstate", "w", atomictemp=True)
if self._limit > 0:
limit = util.fstat(st).st_mtime - self._limit
else:
limit = sys.maxint
cs = cStringIO.StringIO()
copymap = self._copymap
pack = struct.pack
@ -343,10 +354,11 @@ class dirstate(object):
for f, e in self._map.iteritems():
if f in copymap:
f = "%s\0%s" % (f, copymap[f])
if e[3] > limit and e[0] == 'n':
e = (e[0], 0, -1, -1, 0)
e = pack(_format, e[0], e[1], e[2], e[3], len(f))
write(e)
write(f)
st = self._opener("dirstate", "w", atomictemp=True)
st.write(cs.getvalue())
st.rename()
self._dirty = self._dirtypl = False

View File

@ -3,10 +3,10 @@ creating base
creating branch a
creating branch b
we shouldn't have anything but n state here
n 644 2 bar
n 644 3 baz
n 644 3 foo
n 644 2 quux
n 0 -1 bar
n 0 -1 baz
n 0 -1 foo
n 0 -1 quux
merging
pulling from ../a
searching for changes

View File

@ -2,7 +2,7 @@ adding bar
adding foo
% state dump
a 0 -1 baz
n 644 0 foo
n 0 -1 foo
r 0 0 bar
% status
A baz