diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -448,6 +448,7 @@ size=None, mtime=None, added=False, + merged=False, from_p2=False, possibly_dirty=False, ): @@ -476,6 +477,7 @@ size=size, mtime=mtime, added=added, + merged=merged, from_p2=from_p2, possibly_dirty=possibly_dirty, ) @@ -538,7 +540,7 @@ raise error.Abort(msg) if f in self and self[f] == b'n': # merge-like - self._addpath(f, b'm', 0, from_p2=True) + self._addpath(f, merged=True) else: # add-like self._addpath(f, b'n', 0, from_p2=True) diff --git a/mercurial/dirstatemap.py b/mercurial/dirstatemap.py --- a/mercurial/dirstatemap.py +++ b/mercurial/dirstatemap.py @@ -152,16 +152,24 @@ size=None, mtime=None, added=False, + merged=False, from_p2=False, possibly_dirty=False, ): """Add a tracked file to the dirstate.""" if added: + assert not merged assert not possibly_dirty assert not from_p2 state = b'a' size = NONNORMAL mtime = AMBIGUOUS_TIME + elif merged: + assert not possibly_dirty + assert not from_p2 + state = b'm' + size = FROM_P2 + mtime = AMBIGUOUS_TIME elif from_p2: assert not possibly_dirty size = FROM_P2 @@ -470,6 +478,7 @@ size=None, mtime=None, added=False, + merged=False, from_p2=False, possibly_dirty=False, ): @@ -480,6 +489,7 @@ size, mtime, added, + merged, from_p2, possibly_dirty, ) diff --git a/rust/hg-core/src/dirstate/dirstate_map.rs b/rust/hg-core/src/dirstate/dirstate_map.rs --- a/rust/hg-core/src/dirstate/dirstate_map.rs +++ b/rust/hg-core/src/dirstate/dirstate_map.rs @@ -71,16 +71,24 @@ entry: DirstateEntry, // XXX once the dust settle this should probably become an enum added: bool, + merged: bool, from_p2: bool, possibly_dirty: bool, ) -> Result<(), DirstateError> { let mut entry = entry; if added { + assert!(!merged); assert!(!possibly_dirty); assert!(!from_p2); entry.state = EntryState::Added; entry.size = SIZE_NON_NORMAL; entry.mtime = MTIME_UNSET; + } else if merged { + assert!(!possibly_dirty); + assert!(!from_p2); + entry.state = EntryState::Merged; + entry.size = SIZE_FROM_OTHER_PARENT; + entry.mtime = MTIME_UNSET; } else if from_p2 { assert!(!possibly_dirty); entry.size = SIZE_FROM_OTHER_PARENT; @@ -410,6 +418,7 @@ false, false, false, + false, ) .unwrap(); diff --git a/rust/hg-core/src/dirstate_tree/dirstate_map.rs b/rust/hg-core/src/dirstate_tree/dirstate_map.rs --- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs +++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs @@ -723,6 +723,7 @@ filename: &HgPath, entry: DirstateEntry, added: bool, + merged: bool, from_p2: bool, possibly_dirty: bool, ) -> Result<(), DirstateError> { @@ -733,6 +734,12 @@ entry.state = EntryState::Added; entry.size = SIZE_NON_NORMAL; entry.mtime = MTIME_UNSET; + } else if merged { + assert!(!possibly_dirty); + assert!(!from_p2); + entry.state = EntryState::Merged; + entry.size = SIZE_FROM_OTHER_PARENT; + entry.mtime = MTIME_UNSET; } else if from_p2 { assert!(!possibly_dirty); entry.size = SIZE_FROM_OTHER_PARENT; diff --git a/rust/hg-core/src/dirstate_tree/dispatch.rs b/rust/hg-core/src/dirstate_tree/dispatch.rs --- a/rust/hg-core/src/dirstate_tree/dispatch.rs +++ b/rust/hg-core/src/dirstate_tree/dispatch.rs @@ -49,6 +49,7 @@ filename: &HgPath, entry: DirstateEntry, added: bool, + merged: bool, from_p2: bool, possibly_dirty: bool, ) -> Result<(), DirstateError>; @@ -289,10 +290,11 @@ filename: &HgPath, entry: DirstateEntry, added: bool, + merged: bool, from_p2: bool, possibly_dirty: bool, ) -> Result<(), DirstateError> { - self.add_file(filename, entry, added, from_p2, possibly_dirty) + self.add_file(filename, entry, added, merged, from_p2, possibly_dirty) } fn remove_file( diff --git a/rust/hg-cpython/src/dirstate/dirstate_map.rs b/rust/hg-cpython/src/dirstate/dirstate_map.rs --- a/rust/hg-cpython/src/dirstate/dirstate_map.rs +++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs @@ -113,6 +113,7 @@ size: PyObject, mtime: PyObject, added: PyObject, + merged: PyObject, from_p2: PyObject, possibly_dirty: PyObject, ) -> PyResult { @@ -153,12 +154,14 @@ mtime: mtime, }; let added = added.extract::(py)?.is_true(); + let merged = merged.extract::(py)?.is_true(); let from_p2 = from_p2.extract::(py)?.is_true(); let possibly_dirty = possibly_dirty.extract::(py)?.is_true(); self.inner(py).borrow_mut().add_file( filename, entry, added, + merged, from_p2, possibly_dirty ).and(Ok(py.None())).or_else(|e: DirstateError| { diff --git a/rust/hg-cpython/src/dirstate/dispatch.rs b/rust/hg-cpython/src/dirstate/dispatch.rs --- a/rust/hg-cpython/src/dirstate/dispatch.rs +++ b/rust/hg-cpython/src/dirstate/dispatch.rs @@ -26,6 +26,7 @@ filename: &HgPath, entry: DirstateEntry, added: bool, + merged: bool, from_p2: bool, possibly_dirty: bool, ) -> Result<(), DirstateError> { @@ -33,6 +34,7 @@ filename, entry, added, + merged, from_p2, possibly_dirty, )