diff --git a/mercurial/cext/parsers.c b/mercurial/cext/parsers.c --- a/mercurial/cext/parsers.c +++ b/mercurial/cext/parsers.c @@ -515,6 +515,27 @@ Py_RETURN_NONE; } +static PyObject *dirstate_item_drop_merge_data(dirstateItemObject *self) +{ + if (dirstate_item_c_merged(self) || dirstate_item_c_from_p2(self)) { + if (dirstate_item_c_merged(self)) { + self->flags |= dirstate_flag_p1_tracked; + } else { + self->flags &= ~dirstate_flag_p1_tracked; + } + self->flags &= + ~(dirstate_flag_merged | dirstate_flag_clean_p1 | + dirstate_flag_clean_p2 | dirstate_flag_p2_tracked); + self->flags |= dirstate_flag_possibly_dirty; + self->mode = 0; + self->mtime = 0; + /* size = None on the python size turn into size = NON_NORMAL + * when accessed. So the next line is currently required, but a + * some future clean up would be welcome. */ + self->size = dirstate_v1_nonnormal; + } + Py_RETURN_NONE; +} static PyMethodDef dirstate_item_methods[] = { {"v1_state", (PyCFunction)dirstate_item_v1_state, METH_NOARGS, "return a \"state\" suitable for v1 serialization"}, @@ -551,6 +572,8 @@ "mark a file as \"tracked\""}, {"set_untracked", (PyCFunction)dirstate_item_set_untracked, METH_NOARGS, "mark a file as \"untracked\""}, + {"drop_merge_data", (PyCFunction)dirstate_item_drop_merge_data, METH_NOARGS, + "remove all \"merge-only\" from a DirstateItem"}, {NULL} /* Sentinel */ }; diff --git a/mercurial/dirstatemap.py b/mercurial/dirstatemap.py --- a/mercurial/dirstatemap.py +++ b/mercurial/dirstatemap.py @@ -441,26 +441,11 @@ continue # Discard "merged" markers when moving away from a merge state - if s.merged: - source = self.copymap.get(f) + if s.merged or s.from_p2: + source = self.copymap.pop(f, None) if source: copies[f] = source - self.reset_state( - f, - wc_tracked=True, - p1_tracked=True, - possibly_dirty=True, - ) - # Also fix up otherparent markers - elif s.from_p2: - source = self.copymap.get(f) - if source: - copies[f] = source - self.reset_state( - f, - p1_tracked=False, - wc_tracked=True, - ) + s.drop_merge_data() return copies def read(self): diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py --- a/mercurial/pure/parsers.py +++ b/mercurial/pure/parsers.py @@ -263,6 +263,24 @@ self._size = None self._mtime = None + def drop_merge_data(self): + """remove all "merge-only" from a DirstateItem + + This is to be call by the dirstatemap code when the second parent is dropped + """ + if not (self.merged or self.from_p2): + return + self._p1_tracked = self.merged # why is this not already properly set ? + + self._merged = False + self._clean_p1 = False + self._clean_p2 = False + self._p2_tracked = False + self._possibly_dirty = True + self._mode = None + self._size = None + self._mtime = None + @property def mode(self): return self.v1_mode()