[PATCH 2 of 5 V5] dirstate: add code to populate the non-normal map on dirstate packing/parsing

Laurent Charignon lcharignon at fb.com
Thu Dec 17 17:44:43 CST 2015


# HG changeset patch
# User Laurent Charignon <lcharignon at fb.com>
# Date 1450395774 28800
#      Thu Dec 17 15:42:54 2015 -0800
# Node ID 2aab2915f57abb8331a2e53e946161bd32433207
# Parent  44eafafb98c9d24bdff7d6c46213ffe2cf8edc8d
dirstate: add code to populate the non-normal map on dirstate packing/parsing

Before this patch, the non-normal map was always empty. This patch adds the
logic to populate the non-normal map when we are packing and parsing the
dirstate.

diff --git a/mercurial/parsers.c b/mercurial/parsers.c
--- a/mercurial/parsers.c
+++ b/mercurial/parsers.c
@@ -463,10 +463,25 @@ PyTypeObject dirstateTupleType = {
 	dirstate_tuple_new,        /* tp_new */
 };
 
+static inline int add_to_nonnormalmap(PyObject *fname, PyObject *nonnmap,
+						      PyObject * statestring, char state, int mtime)
 {
+	if (fname && nonnmap) {
+		if (state != 'n' &&
+		    PyDict_SetItem(nonnmap, fname, statestring) == -1)
+			return -1;
+		if (state == 'n' && mtime == -1 &&
+		    PyDict_SetItem(nonnmap, fname, statestring) == -1)
+			return -1;
+	}
+	return 0;
+}
+
 static PyObject *parse_dirstate_v2(PyObject *self, PyObject *args)
+{
 	PyObject *dmap, *cmap, *nonnmap, *parents = NULL, *ret = NULL;
 	PyObject *fname = NULL, *cname = NULL, *entry = NULL;
+
 	char state, *cur, *str, *cpos;
 	int mode, size, mtime;
 	unsigned int flen, len, pos = 40;
@@ -514,6 +529,7 @@ static PyObject *parse_dirstate_v2(PyObj
 
 		entry = (PyObject *)make_dirstate_tuple(state, mode, size,
 							mtime);
+
 		cpos = memchr(cur, 0, flen);
 		if (cpos) {
 			fname = PyBytes_FromStringAndSize(cur, cpos - cur);
@@ -521,13 +537,15 @@ static PyObject *parse_dirstate_v2(PyObj
 							   flen - (cpos - cur) - 1);
 			if (!fname || !cname ||
 			    PyDict_SetItem(cmap, fname, cname) == -1 ||
-			    PyDict_SetItem(dmap, fname, entry) == -1)
+			    PyDict_SetItem(dmap, fname, entry) == -1 ||
+			    add_to_nonnormalmap(fname, nonnmap, entry, state, mtime) == -1)
 				goto quit;
 			Py_DECREF(cname);
 		} else {
 			fname = PyBytes_FromStringAndSize(cur, flen);
 			if (!fname ||
-			    PyDict_SetItem(dmap, fname, entry) == -1)
+			    PyDict_SetItem(dmap, fname, entry) == -1 ||
+			    add_to_nonnormalmap(fname, nonnmap, entry, state, mtime) == -1)
 				goto quit;
 		}
 		Py_DECREF(fname);
@@ -637,6 +655,8 @@ static PyObject *pack_dirstate_v2(PyObje
 				goto bail;
 			if (PyDict_SetItem(map, k, mtime_unset) == -1)
 				goto bail;
+			if (PyDict_SetItem(nonnmap, k, mtime_unset) == -1)
+				goto bail;
 			Py_DECREF(mtime_unset);
 			mtime_unset = NULL;
 		}
diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -86,6 +86,9 @@ def parse_dirstate_v2(dmap, copymap, st,
             f, c = f.split('\0')
             copymap[f] = c
         dmap[f] = e[:4]
+        if nonnormalmap is not None and (e[0] != 'n' or e[3] == -1):
+            nonnormalmap[f] = e[:4]
+
     return parents
 
 def pack_dirstate_v2(dmap, copymap, pl, now, nonnormalmap=None):
@@ -106,6 +109,8 @@ def pack_dirstate_v2(dmap, copymap, pl, 
             # mistakenly treating such files as clean.
             e = dirstatetuple(e[0], e[1], e[2], -1)
             dmap[f] = e
+            if nonnormalmap is not None:
+                nonnormalmap[f] = e
 
         if f in copymap:
             f = "%s\0%s" % (f, copymap[f])


More information about the Mercurial-devel mailing list