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