diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -443,15 +443,16 @@ class dirstate(object): def _addpath( self, f, - state, - mode, + state=None, + mode=0, size=None, mtime=None, + added=False, from_p2=False, possibly_dirty=False, ): entry = self._map.get(f) - if state == b'a' or entry is not None and entry.removed: + if added or entry is not None and entry.removed: scmutil.checkfilename(f) if self._map.hastrackeddir(f): msg = _(b'directory %r already in dirstate') @@ -474,6 +475,7 @@ class dirstate(object): mode=mode, size=size, mtime=mtime, + added=added, from_p2=from_p2, possibly_dirty=possibly_dirty, ) @@ -544,7 +546,7 @@ class dirstate(object): def add(self, f): '''Mark a file added.''' - self._addpath(f, b'a', 0) + self._addpath(f, added=True) self._map.copymap.pop(f, None) def remove(self, f): diff --git a/mercurial/dirstatemap.py b/mercurial/dirstatemap.py --- a/mercurial/dirstatemap.py +++ b/mercurial/dirstatemap.py @@ -147,17 +147,19 @@ class dirstatemap(object): def addfile( self, f, - state, - mode, + state=None, + mode=0, size=None, mtime=None, + added=False, from_p2=False, possibly_dirty=False, ): """Add a tracked file to the dirstate.""" - if state == b'a': + if added: assert not possibly_dirty assert not from_p2 + state = b'a' size = NONNORMAL mtime = AMBIGUOUS_TIME elif from_p2: @@ -168,10 +170,12 @@ class dirstatemap(object): size = NONNORMAL mtime = AMBIGUOUS_TIME else: + assert state != b'a' assert size != FROM_P2 assert size != NONNORMAL size = size & rangemask mtime = mtime & rangemask + assert state is not None assert size is not None assert mtime is not None old_entry = self.get(f) @@ -461,10 +465,11 @@ if rustmod is not None: def addfile( self, f, - state, - mode, + state=None, + mode=0, size=None, mtime=None, + added=False, from_p2=False, possibly_dirty=False, ): @@ -474,6 +479,7 @@ if rustmod is not None: mode, size, mtime, + added, 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 @@ -70,13 +70,15 @@ impl DirstateMap { filename: &HgPath, entry: DirstateEntry, // XXX once the dust settle this should probably become an enum + added: bool, from_p2: bool, possibly_dirty: bool, ) -> Result<(), DirstateError> { let mut entry = entry; - if entry.state == EntryState::Added { + if added { assert!(!possibly_dirty); assert!(!from_p2); + entry.state = EntryState::Added; entry.size = SIZE_NON_NORMAL; entry.mtime = MTIME_UNSET; } else if from_p2 { @@ -407,6 +409,7 @@ mod tests { }, 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 @@ -722,13 +722,15 @@ impl<'on_disk> super::dispatch::Dirstate &mut self, filename: &HgPath, entry: DirstateEntry, + added: bool, from_p2: bool, possibly_dirty: bool, ) -> Result<(), DirstateError> { let mut entry = entry; - if entry.state == EntryState::Added { + if added { assert!(!possibly_dirty); assert!(!from_p2); + entry.state = EntryState::Added; entry.size = SIZE_NON_NORMAL; entry.mtime = MTIME_UNSET; } else if from_p2 { 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 @@ -48,6 +48,7 @@ pub trait DirstateMapMethods { &mut self, filename: &HgPath, entry: DirstateEntry, + added: bool, from_p2: bool, possibly_dirty: bool, ) -> Result<(), DirstateError>; @@ -287,10 +288,11 @@ impl DirstateMapMethods for DirstateMap &mut self, filename: &HgPath, entry: DirstateEntry, + added: bool, from_p2: bool, possibly_dirty: bool, ) -> Result<(), DirstateError> { - self.add_file(filename, entry, from_p2, possibly_dirty) + self.add_file(filename, entry, added, 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 @@ -112,17 +112,28 @@ py_class!(pub class DirstateMap |py| { mode: PyObject, size: PyObject, mtime: PyObject, + added: PyObject, from_p2: PyObject, possibly_dirty: PyObject, ) -> PyResult { let f = f.extract::(py)?; let filename = HgPath::new(f.data(py)); - let state = state.extract::(py)?.data(py)[0] + let state = if state.is_none(py) { + // Arbitrary default value + EntryState::Normal + } else { + state.extract::(py)?.data(py)[0] .try_into() .map_err(|e: HgError| { PyErr::new::(py, e.to_string()) - })?; - let mode = mode.extract(py)?; + })? + }; + let mode = if mode.is_none(py) { + // fallback default value + 0 + } else { + mode.extract(py)? + }; let size = if size.is_none(py) { // fallback default value SIZE_NON_NORMAL @@ -141,11 +152,13 @@ py_class!(pub class DirstateMap |py| { size: size, mtime: mtime, }; + let added = added.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, 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 @@ -25,11 +25,17 @@ impl DirstateMapMethods for OwningDirsta &mut self, filename: &HgPath, entry: DirstateEntry, + added: bool, from_p2: bool, possibly_dirty: bool, ) -> Result<(), DirstateError> { - self.get_mut() - .add_file(filename, entry, from_p2, possibly_dirty) + self.get_mut().add_file( + filename, + entry, + added, + from_p2, + possibly_dirty, + ) } fn remove_file(