# HG changeset patch # User Siddharth Agarwal # Date 1358495168 28800 # Node ID 194e63c1ccb92b3a3afe7ab90b395a0887c87100 # Parent 341868ef0cf6bb3fc9fc4f5b4f34047ba57b5a77 dirstate: move pure python dirstate packing to pure/parsers.py diff -r 341868ef0cf6 -r 194e63c1ccb9 mercurial/dirstate.py --- a/mercurial/dirstate.py Tue Feb 05 16:22:53 2013 -0800 +++ b/mercurial/dirstate.py Thu Jan 17 23:46:08 2013 -0800 @@ -9,10 +9,8 @@ from node import nullid from i18n import _ import scmutil, util, ignore, osutil, parsers, encoding -import struct, os, stat, errno -import cStringIO +import os, stat, errno -_format = ">cllll" propertycache = util.propertycache filecache = scmutil.filecache _rangemask = 0x7fffffff @@ -508,38 +506,7 @@ # use the modification time of the newly created temporary file as the # filesystem's notion of 'now' now = util.fstat(st).st_mtime - copymap = self._copymap - try: - finish(parsers.pack_dirstate(self._map, copymap, self._pl, now)) - return - except AttributeError: - pass - - now = int(now) - cs = cStringIO.StringIO() - pack = struct.pack - write = cs.write - write("".join(self._pl)) - for f, e in self._map.iteritems(): - 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- - # systems with a granularity of 1 sec). This commonly happens - # for at least a couple of files on 'update'. - # The user could change the file without changing its size - # within the same second. Invalidate the file's stat data in - # 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 - - 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) - finish(cs.getvalue()) + finish(parsers.pack_dirstate(self._map, self._copymap, self._pl, now)) def _dirignore(self, f): if f == '.': diff -r 341868ef0cf6 -r 194e63c1ccb9 mercurial/parsers.c --- a/mercurial/parsers.c Tue Feb 05 16:22:53 2013 -0800 +++ b/mercurial/parsers.c Thu Jan 17 23:46:08 2013 -0800 @@ -326,7 +326,8 @@ if (getintat(v, 3, &mtime) == -1) goto bail; if (*s == 'n' && mtime == (uint32_t)now) { - /* See dirstate.py:write for why we do this. */ + /* See pure/parsers.py:pack_dirstate for why we do + * this. */ if (PyDict_SetItem(map, k, dirstate_unset) == -1) goto bail; mode = 0, size = -1, mtime = -1; diff -r 341868ef0cf6 -r 194e63c1ccb9 mercurial/pure/parsers.py --- a/mercurial/pure/parsers.py Tue Feb 05 16:22:53 2013 -0800 +++ b/mercurial/pure/parsers.py Thu Jan 17 23:46:08 2013 -0800 @@ -7,7 +7,7 @@ from mercurial.node import bin, nullid from mercurial import util -import struct, zlib +import struct, zlib, cStringIO _pack = struct.pack _unpack = struct.unpack @@ -87,3 +87,29 @@ copymap[f] = c dmap[f] = e[:4] return parents + +def pack_dirstate(dmap, copymap, pl, now): + now = int(now) + cs = cStringIO.StringIO() + write = cs.write + write("".join(pl)) + for f, e in dmap.iteritems(): + 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- + # systems with a granularity of 1 sec). This commonly happens + # for at least a couple of files on 'update'. + # The user could change the file without changing its size + # within the same second. Invalidate the file's stat data in + # 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' + dmap[f] = e + + if f in copymap: + f = "%s\0%s" % (f, copymap[f]) + e = _pack(">cllll", e[0], e[1], e[2], e[3], len(f)) + write(e) + write(f) + return cs.getvalue()