[Updated] D11320: dirstate-item: feed more information to `__init__`

marmoute (Pierre-Yves David) phabricator at mercurial-scm.org
Fri Aug 27 12:38:28 UTC 2021


Closed by commit rHG22c39f8acf78: dirstate-item: feed more information to `__init__` (authored by marmoute).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D11320?vs=30046&id=30088

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D11320/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D11320

AFFECTED FILES
  mercurial/cext/parsers.c
  mercurial/pure/parsers.py

CHANGE DETAILS

diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -61,11 +61,62 @@
     _size = attr.ib()
     _mtime = attr.ib()
 
-    def __init__(self, state, mode, size, mtime):
-        self._state = state
-        self._mode = mode
-        self._size = size
-        self._mtime = mtime
+    def __init__(
+        self,
+        wc_tracked=False,
+        p1_tracked=False,
+        p2_tracked=False,
+        merged=False,
+        clean_p1=False,
+        clean_p2=False,
+        possibly_dirty=False,
+        parentfiledata=None,
+    ):
+        if merged and (clean_p1 or clean_p2):
+            msg = b'`merged` argument incompatible with `clean_p1`/`clean_p2`'
+            raise error.ProgrammingError(msg)
+
+        self._state = None
+        self._mode = 0
+        self._size = NONNORMAL
+        self._mtime = AMBIGUOUS_TIME
+        if not (p1_tracked or p2_tracked or wc_tracked):
+            pass  # the object has no state to record
+        elif merged:
+            self._state = b'm'
+            self._size = FROM_P2
+            self._mtime = AMBIGUOUS_TIME
+        elif not (p1_tracked or p2_tracked) and wc_tracked:
+            self._state = b'a'
+            self._size = NONNORMAL
+            self._mtime = AMBIGUOUS_TIME
+        elif (p1_tracked or p2_tracked) and not wc_tracked:
+            self._state = b'r'
+            self._size = 0
+            self._mtime = 0
+        elif clean_p2 and wc_tracked:
+            self._state = b'n'
+            self._size = FROM_P2
+            self._mtime = AMBIGUOUS_TIME
+        elif not p1_tracked and p2_tracked and wc_tracked:
+            self._state = b'n'
+            self._size = FROM_P2
+            self._mtime = AMBIGUOUS_TIME
+        elif possibly_dirty:
+            self._state = b'n'
+            self._size = NONNORMAL
+            self._mtime = AMBIGUOUS_TIME
+        elif wc_tracked:
+            # this is a "normal" file
+            if parentfiledata is None:
+                msg = b'failed to pass parentfiledata for a normal file'
+                raise error.ProgrammingError(msg)
+            self._state = b'n'
+            self._mode = parentfiledata[0]
+            self._size = parentfiledata[1]
+            self._mtime = parentfiledata[2]
+        else:
+            assert False, 'unreachable'
 
     @classmethod
     def from_v1_data(cls, state, mode, size, mtime):
@@ -74,12 +125,12 @@
         Since the dirstate-v1 format is frozen, the signature of this function
         is not expected to change, unlike the __init__ one.
         """
-        return cls(
-            state=state,
-            mode=mode,
-            size=size,
-            mtime=mtime,
-        )
+        instance = cls()
+        instance._state = state
+        instance._mode = mode
+        instance._size = size
+        instance._mtime = mtime
+        return instance
 
     def set_possibly_dirty(self):
         """Mark a file as "possibly dirty"
diff --git a/mercurial/cext/parsers.c b/mercurial/cext/parsers.c
--- a/mercurial/cext/parsers.c
+++ b/mercurial/cext/parsers.c
@@ -65,21 +65,100 @@
 	/* We do all the initialization here and not a tp_init function because
 	 * dirstate_item is immutable. */
 	dirstateItemObject *t;
-	char state;
-	int size, mode, mtime;
-	if (!PyArg_ParseTuple(args, "ciii", &state, &mode, &size, &mtime)) {
+	int wc_tracked;
+	int p1_tracked;
+	int p2_tracked;
+	int merged;
+	int clean_p1;
+	int clean_p2;
+	int possibly_dirty;
+	PyObject *parentfiledata;
+	static char *keywords_name[] = {
+	    "wc_tracked",     "p1_tracked",     "p2_tracked",
+	    "merged",         "clean_p1",       "clean_p2",
+	    "possibly_dirty", "parentfiledata", NULL,
+	};
+	wc_tracked = 0;
+	p1_tracked = 0;
+	p2_tracked = 0;
+	merged = 0;
+	clean_p1 = 0;
+	clean_p2 = 0;
+	possibly_dirty = 0;
+	parentfiledata = Py_None;
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiiiiiiO", keywords_name,
+	                                 &wc_tracked, &p1_tracked, &p2_tracked,
+	                                 &merged, &clean_p1, &clean_p2,
+	                                 &possibly_dirty, &parentfiledata
+
+	                                 )) {
 		return NULL;
 	}
-
+	if (merged && (clean_p1 || clean_p2)) {
+		PyErr_SetString(PyExc_RuntimeError,
+		                "`merged` argument incompatible with "
+		                "`clean_p1`/`clean_p2`");
+		return NULL;
+	}
 	t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
 	if (!t) {
 		return NULL;
 	}
-	t->state = state;
-	t->mode = mode;
-	t->size = size;
-	t->mtime = mtime;
-
+	t->state = 'r';
+	t->mode = 0;
+	t->size = dirstate_v1_nonnormal;
+	t->mtime = ambiguous_time;
+	if (!(p1_tracked || p2_tracked || wc_tracked)) {
+		/* Nothing special to do, file is untracked */
+	} else if (merged) {
+		t->state = 'm';
+		t->size = dirstate_v1_from_p2;
+		t->mtime = ambiguous_time;
+	} else if (!(p1_tracked || p2_tracked) && wc_tracked) {
+		t->state = 'a';
+		t->size = dirstate_v1_nonnormal;
+		t->mtime = ambiguous_time;
+	} else if ((p1_tracked || p2_tracked) && !wc_tracked) {
+		t->state = 'r';
+		t->size = 0;
+		t->mtime = 0;
+	} else if (clean_p2 && wc_tracked) {
+		t->state = 'n';
+		t->size = dirstate_v1_from_p2;
+		t->mtime = ambiguous_time;
+	} else if (!p1_tracked && p2_tracked && wc_tracked) {
+		t->state = 'n';
+		t->size = dirstate_v1_from_p2;
+		t->mtime = ambiguous_time;
+	} else if (possibly_dirty) {
+		t->state = 'n';
+		t->size = dirstate_v1_nonnormal;
+		t->mtime = ambiguous_time;
+	} else if (wc_tracked) {
+		/* this is a "normal" file */
+		if (parentfiledata == Py_None) {
+			PyErr_SetString(
+			    PyExc_RuntimeError,
+			    "failed to pass parentfiledata for a normal file");
+			return NULL;
+		}
+		if (!PyTuple_CheckExact(parentfiledata)) {
+			PyErr_SetString(
+			    PyExc_TypeError,
+			    "parentfiledata should be a Tuple or None");
+			return NULL;
+		}
+		t->state = 'n';
+		t->mode =
+		    (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 0));
+		t->size =
+		    (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 1));
+		t->mtime =
+		    (int)PyLong_AsLong(PyTuple_GetItem(parentfiledata, 2));
+	} else {
+		PyErr_SetString(PyExc_RuntimeError, "unreachable");
+		return NULL;
+	}
 	return (PyObject *)t;
 }
 



To: marmoute, #hg-reviewers, Alphare
Cc: Alphare, mercurial-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurial-scm.org/pipermail/mercurial-patches/attachments/20210827/9d7c87fc/attachment-0002.html>


More information about the Mercurial-patches mailing list