diff --git a/rust/hg-core/src/dirstate/status.rs b/rust/hg-core/src/dirstate/status.rs --- a/rust/hg-core/src/dirstate/status.rs +++ b/rust/hg-core/src/dirstate/status.rs @@ -264,6 +264,10 @@ pub ignored: Vec>, pub unknown: Vec>, pub bad: Vec<(HgPathCow<'a>, BadMatch)>, + /// Either clean or modified, but we can’t tell from filesystem metadata + /// alone. The file contents need to be read and compared with that in + /// the parent. + pub unsure: Vec>, /// Only filled if `collect_traversed_dirs` is `true` pub traversed: Vec, } @@ -847,8 +851,8 @@ pub fn build_response<'a>( results: impl IntoIterator>, traversed: Vec, -) -> (Vec>, DirstateStatus<'a>) { - let mut lookup = vec![]; +) -> DirstateStatus<'a> { + let mut unsure = vec![]; let mut modified = vec![]; let mut added = vec![]; let mut removed = vec![]; @@ -861,7 +865,7 @@ for (filename, dispatch) in results.into_iter() { match dispatch { Dispatch::Unknown => unknown.push(filename), - Dispatch::Unsure => lookup.push(filename), + Dispatch::Unsure => unsure.push(filename), Dispatch::Modified => modified.push(filename), Dispatch::Added => added.push(filename), Dispatch::Removed => removed.push(filename), @@ -874,20 +878,18 @@ } } - ( - lookup, - DirstateStatus { - modified, - added, - removed, - deleted, - clean, - ignored, - unknown, - bad, - traversed, - }, - ) + DirstateStatus { + modified, + added, + removed, + deleted, + clean, + ignored, + unknown, + bad, + unsure, + traversed, + } } /// Get the status of files in the working directory. @@ -902,10 +904,7 @@ root_dir: PathBuf, ignore_files: Vec, options: StatusOptions, -) -> StatusResult<( - (Vec>, DirstateStatus<'a>), - Vec, -)> { +) -> StatusResult<(DirstateStatus<'a>, Vec)> { let (status, warnings) = Status::new(dmap, matcher, root_dir, ignore_files, options)?; 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 @@ -19,7 +19,6 @@ use crate::DirstateParents; use crate::DirstateStatus; use crate::EntryState; -use crate::HgPathCow; use crate::PatternFileWarning; use crate::StateMapIter; use crate::StatusError; @@ -582,13 +581,8 @@ _root_dir: PathBuf, _ignore_files: Vec, _options: StatusOptions, - ) -> Result< - ( - (Vec>, DirstateStatus<'a>), - Vec, - ), - StatusError, - > { + ) -> Result<(DirstateStatus<'a>, Vec), StatusError> + { todo!() } 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 @@ -11,7 +11,6 @@ use crate::DirstateParents; use crate::DirstateStatus; use crate::EntryState; -use crate::HgPathCow; use crate::PatternFileWarning; use crate::StateMapIter; use crate::StatusError; @@ -102,13 +101,7 @@ root_dir: PathBuf, ignore_files: Vec, options: StatusOptions, - ) -> Result< - ( - (Vec>, DirstateStatus<'a>), - Vec, - ), - StatusError, - >; + ) -> Result<(DirstateStatus<'a>, Vec), StatusError>; fn copy_map_len(&self) -> usize; @@ -270,13 +263,8 @@ root_dir: PathBuf, ignore_files: Vec, options: StatusOptions, - ) -> Result< - ( - (Vec>, DirstateStatus<'a>), - Vec, - ), - StatusError, - > { + ) -> Result<(DirstateStatus<'a>, Vec), StatusError> + { crate::status(self, matcher, root_dir, ignore_files, options) } diff --git a/rust/hg-core/src/operations/dirstate_status.rs b/rust/hg-core/src/operations/dirstate_status.rs --- a/rust/hg-core/src/operations/dirstate_status.rs +++ b/rust/hg-core/src/operations/dirstate_status.rs @@ -5,17 +5,12 @@ // This software may be used and distributed according to the terms of the // GNU General Public License version 2 or any later version. -use crate::dirstate::status::{build_response, Dispatch, HgPathCow, Status}; +use crate::dirstate::status::{build_response, Dispatch, Status}; use crate::matchers::Matcher; use crate::{DirstateStatus, StatusError}; -/// A tuple of the paths that need to be checked in the filelog because it's -/// ambiguous whether they've changed, and the rest of the already dispatched -/// files. -pub type LookupAndStatus<'a> = (Vec>, DirstateStatus<'a>); - impl<'a, M: ?Sized + Matcher + Sync> Status<'a, M> { - pub(crate) fn run(&self) -> Result, StatusError> { + pub(crate) fn run(&self) -> Result, StatusError> { let (traversed_sender, traversed_receiver) = crossbeam_channel::unbounded(); diff --git a/rust/hg-cpython/src/dirstate/status.rs b/rust/hg-cpython/src/dirstate/status.rs --- a/rust/hg-cpython/src/dirstate/status.rs +++ b/rust/hg-cpython/src/dirstate/status.rs @@ -25,7 +25,7 @@ BadMatch, DirstateStatus, IgnorePattern, PatternFileWarning, StatusError, StatusOptions, }; -use std::borrow::{Borrow, Cow}; +use std::borrow::Borrow; /// This will be useless once trait impls for collection are added to `PyBytes` /// upstream. @@ -126,7 +126,7 @@ match matcher.get_type(py).name(py).borrow() { "alwaysmatcher" => { let matcher = AlwaysMatcher; - let ((lookup, status_res), warnings) = dmap + let (status_res, warnings) = dmap .status( &matcher, root_dir.to_path_buf(), @@ -141,7 +141,7 @@ }, ) .map_err(|e| handle_fallback(py, e))?; - build_response(py, lookup, status_res, warnings) + build_response(py, status_res, warnings) } "exactmatcher" => { let files = matcher.call_method( @@ -163,7 +163,7 @@ let files = files?; let matcher = FileMatcher::new(files.as_ref()) .map_err(|e| PyErr::new::(py, e.to_string()))?; - let ((lookup, status_res), warnings) = dmap + let (status_res, warnings) = dmap .status( &matcher, root_dir.to_path_buf(), @@ -178,7 +178,7 @@ }, ) .map_err(|e| handle_fallback(py, e))?; - build_response(py, lookup, status_res, warnings) + build_response(py, status_res, warnings) } "includematcher" => { // Get the patterns from Python even though most of them are @@ -218,7 +218,7 @@ .map_err(|e| handle_fallback(py, e.into()))?; all_warnings.extend(warnings); - let ((lookup, status_res), warnings) = dmap + let (status_res, warnings) = dmap .status( &matcher, root_dir.to_path_buf(), @@ -236,7 +236,7 @@ all_warnings.extend(warnings); - build_response(py, lookup, status_res, all_warnings) + build_response(py, status_res, all_warnings) } e => Err(PyErr::new::( py, @@ -247,7 +247,6 @@ fn build_response( py: Python, - lookup: Vec>, status_res: DirstateStatus, warnings: Vec, ) -> PyResult { @@ -258,7 +257,7 @@ let clean = collect_pybytes_list(py, status_res.clean.as_ref()); let ignored = collect_pybytes_list(py, status_res.ignored.as_ref()); let unknown = collect_pybytes_list(py, status_res.unknown.as_ref()); - let lookup = collect_pybytes_list(py, lookup.as_ref()); + let unsure = collect_pybytes_list(py, status_res.unsure.as_ref()); let bad = collect_bad_matches(py, status_res.bad.as_ref())?; let traversed = collect_pybytes_list(py, status_res.traversed.as_ref()); let py_warnings = PyList::new(py, &[]); @@ -287,7 +286,7 @@ Ok(PyTuple::new( py, &[ - lookup.into_object(), + unsure.into_object(), modified.into_object(), added.into_object(), removed.into_object(), diff --git a/rust/rhg/src/commands/status.rs b/rust/rhg/src/commands/status.rs --- a/rust/rhg/src/commands/status.rs +++ b/rust/rhg/src/commands/status.rs @@ -181,7 +181,7 @@ collect_traversed_dirs: false, }; let ignore_file = repo.working_directory_vfs().join(".hgignore"); // TODO hardcoded - let ((lookup, ds_status), pattern_warnings) = hg::status( + let (ds_status, pattern_warnings) = hg::status( &dmap, &AlwaysMatcher, repo.working_directory_path().to_owned(), @@ -195,10 +195,10 @@ if !ds_status.bad.is_empty() { warn!("Bad matches {:?}", &(ds_status.bad)) } - if !lookup.is_empty() { + if !ds_status.unsure.is_empty() { info!( "Files to be rechecked by retrieval from filelog: {:?}", - &lookup + &ds_status.unsure ); } // TODO check ordering to match `hg status` output. @@ -206,7 +206,7 @@ if display_states.modified { display_status_paths(ui, &(ds_status.modified), b"M")?; } - if !lookup.is_empty() { + if !ds_status.unsure.is_empty() { let p1: Node = parents .expect( "Dirstate with no parents should not list any file to @@ -217,7 +217,7 @@ let p1_hex = format!("{:x}", p1); let mut rechecked_modified: Vec = Vec::new(); let mut rechecked_clean: Vec = Vec::new(); - for to_check in lookup { + for to_check in ds_status.unsure { if cat_file_is_modified(repo, &to_check, &p1_hex)? { rechecked_modified.push(to_check); } else {