diff --git a/mercurial/cext/parsers.c b/mercurial/cext/parsers.c --- a/mercurial/cext/parsers.c +++ b/mercurial/cext/parsers.c @@ -175,10 +175,20 @@ } }; +static PyObject *dirstatetuple_get_removed(dirstateTupleObject *self) +{ + if (self->state == 'r') { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +}; + static PyGetSetDef dirstatetuple_getset[] = { {"state", (getter)dirstatetuple_get_state, NULL, "state", NULL}, {"merged", (getter)dirstatetuple_get_merged, NULL, "merged", NULL}, {"from_p2", (getter)dirstatetuple_get_from_p2, NULL, "from_p2", NULL}, + {"removed", (getter)dirstatetuple_get_removed, NULL, "removed", NULL}, {NULL} /* Sentinel */ }; diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -472,7 +472,7 @@ if self._map.hastrackeddir(d): break entry = self._map.get(d) - if entry is not None and entry.state != b'r': + if entry is not None and not entry.removed: msg = _(b'file %r in dirstate clashes with %r') msg %= (pycompat.bytestr(d), pycompat.bytestr(f)) raise error.Abort(msg) @@ -531,9 +531,7 @@ # being removed, restore that state. entry = self._map.get(f) if entry is not None: - if entry.state == b'r' and ( - entry[2] == NONNORMAL or entry.from_p2 - ): + if entry.removed and (entry[2] == NONNORMAL or entry.from_p2): source = self._map.copymap.get(f) if entry[2] == NONNORMAL: self.merge(f) @@ -1364,7 +1362,7 @@ madd(fn) elif state == b'a': aadd(fn) - elif state == b'r': + elif t.removed: radd(fn) status = scmutil.status( modified, added, removed, deleted, unknown, ignored, clean diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py --- a/mercurial/pure/parsers.py +++ b/mercurial/pure/parsers.py @@ -99,6 +99,11 @@ """ return self._size == FROM_P2 + @property + def removed(self): + """True if the file has been removed""" + return self._state == b'r' + def v1_state(self): """return a "state" suitable for v1 serialization""" return self._state