dirstate-item: add dedicated "legacy" constructor for `addfile` case
This way the internal details of how a DirstateItem is encoded is encapsulated
within the DirstateItem. This will finally give use some latitude to change the
data we store in a DirstateItem.
The addfile logic will likely be rewritten eventually and these dedicated
constructor can be removed at that time.
In the mean-time this should help with hiding internal details of DirstateItem
and to migrate it to new internal storage and logic.
Differential Revision: https://phab.mercurial-scm.org/D11330
--- a/mercurial/cext/parsers.c Fri Jul 16 17:32:40 2021 +0200
+++ b/mercurial/cext/parsers.c Fri Jul 16 18:12:27 2021 +0200
@@ -277,6 +277,102 @@
return (PyObject *)t;
};
+/* constructor to help legacy API to build a new "added" item
+
+Should eventually be removed */
+static PyObject *dirstate_item_new_added(PyTypeObject *subtype)
+{
+ dirstateItemObject *t;
+ t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
+ if (!t) {
+ return NULL;
+ }
+ t->state = 'a';
+ t->mode = 0;
+ t->size = dirstate_v1_nonnormal;
+ t->mtime = ambiguous_time;
+ return (PyObject *)t;
+};
+
+/* constructor to help legacy API to build a new "merged" item
+
+Should eventually be removed */
+static PyObject *dirstate_item_new_merged(PyTypeObject *subtype)
+{
+ dirstateItemObject *t;
+ t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
+ if (!t) {
+ return NULL;
+ }
+ t->state = 'm';
+ t->mode = 0;
+ t->size = dirstate_v1_from_p2;
+ t->mtime = ambiguous_time;
+ return (PyObject *)t;
+};
+
+/* constructor to help legacy API to build a new "from_p2" item
+
+Should eventually be removed */
+static PyObject *dirstate_item_new_from_p2(PyTypeObject *subtype)
+{
+ /* We do all the initialization here and not a tp_init function because
+ * dirstate_item is immutable. */
+ dirstateItemObject *t;
+ t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
+ if (!t) {
+ return NULL;
+ }
+ t->state = 'n';
+ t->mode = 0;
+ t->size = dirstate_v1_from_p2;
+ t->mtime = ambiguous_time;
+ return (PyObject *)t;
+};
+
+/* constructor to help legacy API to build a new "possibly" item
+
+Should eventually be removed */
+static PyObject *dirstate_item_new_possibly_dirty(PyTypeObject *subtype)
+{
+ /* We do all the initialization here and not a tp_init function because
+ * dirstate_item is immutable. */
+ dirstateItemObject *t;
+ t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
+ if (!t) {
+ return NULL;
+ }
+ t->state = 'n';
+ t->mode = 0;
+ t->size = dirstate_v1_nonnormal;
+ t->mtime = ambiguous_time;
+ return (PyObject *)t;
+};
+
+/* constructor to help legacy API to build a new "normal" item
+
+Should eventually be removed */
+static PyObject *dirstate_item_new_normal(PyTypeObject *subtype, PyObject *args)
+{
+ /* We do all the initialization here and not a tp_init function because
+ * dirstate_item is immutable. */
+ dirstateItemObject *t;
+ int size, mode, mtime;
+ if (!PyArg_ParseTuple(args, "iii", &mode, &size, &mtime)) {
+ return NULL;
+ }
+
+ t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
+ if (!t) {
+ return NULL;
+ }
+ t->state = 'n';
+ t->mode = mode;
+ t->size = size;
+ t->mtime = mtime;
+ return (PyObject *)t;
+};
+
/* This means the next status call will have to actually check its content
to make sure it is correct. */
static PyObject *dirstate_item_set_possibly_dirty(dirstateItemObject *self)
@@ -313,6 +409,21 @@
"True if the stored mtime would be ambiguous with the current time"},
{"from_v1_data", (PyCFunction)dirstate_item_from_v1_meth,
METH_VARARGS | METH_CLASS, "build a new DirstateItem object from V1 data"},
+ {"new_added", (PyCFunction)dirstate_item_new_added,
+ METH_NOARGS | METH_CLASS,
+ "constructor to help legacy API to build a new \"added\" item"},
+ {"new_merged", (PyCFunction)dirstate_item_new_merged,
+ METH_NOARGS | METH_CLASS,
+ "constructor to help legacy API to build a new \"merged\" item"},
+ {"new_from_p2", (PyCFunction)dirstate_item_new_from_p2,
+ METH_NOARGS | METH_CLASS,
+ "constructor to help legacy API to build a new \"from_p2\" item"},
+ {"new_possibly_dirty", (PyCFunction)dirstate_item_new_possibly_dirty,
+ METH_NOARGS | METH_CLASS,
+ "constructor to help legacy API to build a new \"possibly_dirty\" item"},
+ {"new_normal", (PyCFunction)dirstate_item_new_normal,
+ METH_VARARGS | METH_CLASS,
+ "constructor to help legacy API to build a new \"normal\" item"},
{"set_possibly_dirty", (PyCFunction)dirstate_item_set_possibly_dirty,
METH_NOARGS, "mark a file as \"possibly dirty\""},
{"set_untracked", (PyCFunction)dirstate_item_set_untracked, METH_NOARGS,
--- a/mercurial/dirstatemap.py Fri Jul 16 17:32:40 2021 +0200
+++ b/mercurial/dirstatemap.py Fri Jul 16 18:12:27 2021 +0200
@@ -188,42 +188,28 @@
assert not merged
assert not possibly_dirty
assert not from_p2
- state = b'a'
- size = NONNORMAL
- mtime = AMBIGUOUS_TIME
+ new_entry = DirstateItem.new_added()
elif merged:
assert not possibly_dirty
assert not from_p2
- state = b'm'
- size = FROM_P2
- mtime = AMBIGUOUS_TIME
+ new_entry = DirstateItem.new_merged()
elif from_p2:
assert not possibly_dirty
- state = b'n'
- size = FROM_P2
- mtime = AMBIGUOUS_TIME
+ new_entry = DirstateItem.new_from_p2()
elif possibly_dirty:
- state = b'n'
- size = NONNORMAL
- mtime = AMBIGUOUS_TIME
+ new_entry = DirstateItem.new_possibly_dirty()
else:
- assert size != FROM_P2
- assert size != NONNORMAL
assert size is not None
assert mtime is not None
-
- state = b'n'
size = size & rangemask
mtime = mtime & rangemask
- assert state is not None
- assert size is not None
- assert mtime is not None
+ new_entry = DirstateItem.new_normal(mode, size, mtime)
old_entry = self.get(f)
self._dirs_incr(f, old_entry)
- e = self._map[f] = DirstateItem.from_v1_data(state, mode, size, mtime)
- if e.dm_nonnormal:
+ self._map[f] = new_entry
+ if new_entry.dm_nonnormal:
self.nonnormalset.add(f)
- if e.dm_otherparent:
+ if new_entry.dm_otherparent:
self.otherparentset.add(f)
def reset_state(
--- a/mercurial/pure/parsers.py Fri Jul 16 17:32:40 2021 +0200
+++ b/mercurial/pure/parsers.py Fri Jul 16 18:12:27 2021 +0200
@@ -119,6 +119,73 @@
assert False, 'unreachable'
@classmethod
+ def new_added(cls):
+ """constructor to help legacy API to build a new "added" item
+
+ Should eventually be removed
+ """
+ instance = cls()
+ instance._state = b'a'
+ instance._mode = 0
+ instance._size = NONNORMAL
+ instance._mtime = AMBIGUOUS_TIME
+ return instance
+
+ @classmethod
+ def new_merged(cls):
+ """constructor to help legacy API to build a new "merged" item
+
+ Should eventually be removed
+ """
+ instance = cls()
+ instance._state = b'm'
+ instance._mode = 0
+ instance._size = FROM_P2
+ instance._mtime = AMBIGUOUS_TIME
+ return instance
+
+ @classmethod
+ def new_from_p2(cls):
+ """constructor to help legacy API to build a new "from_p2" item
+
+ Should eventually be removed
+ """
+ instance = cls()
+ instance._state = b'n'
+ instance._mode = 0
+ instance._size = FROM_P2
+ instance._mtime = AMBIGUOUS_TIME
+ return instance
+
+ @classmethod
+ def new_possibly_dirty(cls):
+ """constructor to help legacy API to build a new "possibly_dirty" item
+
+ Should eventually be removed
+ """
+ instance = cls()
+ instance._state = b'n'
+ instance._mode = 0
+ instance._size = NONNORMAL
+ instance._mtime = AMBIGUOUS_TIME
+ return instance
+
+ @classmethod
+ def new_normal(cls, mode, size, mtime):
+ """constructor to help legacy API to build a new "normal" item
+
+ Should eventually be removed
+ """
+ assert size != FROM_P2
+ assert size != NONNORMAL
+ instance = cls()
+ instance._state = b'n'
+ instance._mode = mode
+ instance._size = size
+ instance._mtime = mtime
+ return instance
+
+ @classmethod
def from_v1_data(cls, state, mode, size, mtime):
"""Build a new DirstateItem object from V1 data