dirstate: fix in memory dirstate entries for 1-second race
Adrian Buehlmann
adrian at cadifra.com
Mon Apr 5 17:59:26 CDT 2010
(cc-ing mercurial-devel)
tonfa committed e5aaa4543289 in crew stable:
> diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
> --- a/mercurial/dirstate.py
> +++ b/mercurial/dirstate.py
> @@ -391,16 +391,8 @@ class dirstate(object):
> # use the modification time of the newly created temporary file as the
> # filesystem's notion of 'now'
> now = int(util.fstat(st).st_mtime)
> -
> - cs = cStringIO.StringIO()
> - copymap = self._copymap
> - pack = struct.pack
> - write = cs.write
> - write("".join(self._pl))
> - for f, e in self._map.iteritems():
> - if f in copymap:
> - f = "%s\0%s" % (f, copymap[f])
> -
> + for f in self._map.keys():
> + e = self._map[f]
Is this really needed? We just need to update an existing entry, why do
another map lookup by f inside the loop for all f's?
See below for an alternative
> 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-
> @@ -411,8 +403,16 @@ class dirstate(object):
> # 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[0], 0, -1, -1) # mark entry as 'unset'
>
> + cs = cStringIO.StringIO()
> + copymap = self._copymap
> + pack = struct.pack
> + write = cs.write
> + write("".join(self._pl))
> + for f, e in self._map.iteritems():
> + if f in copymap:
> + f = "%s\0%s" % (f, copymap[f])
> e = pack(_format, e[0], e[1], e[2], e[3], len(f))
> write(e)
> write(f)
Alternative for discussion:
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -398,9 +398,6 @@ class dirstate(object):
write = cs.write
write("".join(self._pl))
for f, e in self._map.iteritems():
- if f in copymap:
- f = "%s\0%s" % (f, copymap[f])
-
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-
@@ -412,7 +409,9 @@ class dirstate(object):
# 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
+ if f in copymap:
+ f = "%s\0%s" % (f, copymap[f])
e = pack(_format, e[0], e[1], e[2], e[3], len(f))
write(e)
write(f)
See also http://stackoverflow.com/questions/2315520
More information about the Mercurial-devel
mailing list