rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
authorSimon Sapin <simon.sapin@octobus.net>
Tue, 06 Apr 2021 15:14:19 +0200
changeset 47124 9c6b458a08e1
parent 47123 33e5511b571a
child 47125 623c8e4ddc6d
rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct Instead of having `status()` returning a tuple of those paths and `DirstateStatus`. Differential Revision: https://phab.mercurial-scm.org/D10494
rust/hg-core/src/dirstate/status.rs
rust/hg-core/src/dirstate_tree/dirstate_map.rs
rust/hg-core/src/dirstate_tree/dispatch.rs
rust/hg-core/src/operations/dirstate_status.rs
rust/hg-cpython/src/dirstate/status.rs
rust/rhg/src/commands/status.rs
--- a/rust/hg-core/src/dirstate/status.rs	Tue Apr 13 17:02:58 2021 +0200
+++ b/rust/hg-core/src/dirstate/status.rs	Tue Apr 06 15:14:19 2021 +0200
@@ -264,6 +264,10 @@
     pub ignored: Vec<HgPathCow<'a>>,
     pub unknown: Vec<HgPathCow<'a>>,
     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<HgPathCow<'a>>,
     /// Only filled if `collect_traversed_dirs` is `true`
     pub traversed: Vec<HgPathBuf>,
 }
@@ -847,8 +851,8 @@
 pub fn build_response<'a>(
     results: impl IntoIterator<Item = DispatchedPath<'a>>,
     traversed: Vec<HgPathBuf>,
-) -> (Vec<HgPathCow<'a>>, 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<PathBuf>,
     options: StatusOptions,
-) -> StatusResult<(
-    (Vec<HgPathCow<'a>>, DirstateStatus<'a>),
-    Vec<PatternFileWarning>,
-)> {
+) -> StatusResult<(DirstateStatus<'a>, Vec<PatternFileWarning>)> {
     let (status, warnings) =
         Status::new(dmap, matcher, root_dir, ignore_files, options)?;
 
--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs	Tue Apr 13 17:02:58 2021 +0200
+++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs	Tue Apr 06 15:14:19 2021 +0200
@@ -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<PathBuf>,
         _options: StatusOptions,
-    ) -> Result<
-        (
-            (Vec<HgPathCow<'a>>, DirstateStatus<'a>),
-            Vec<PatternFileWarning>,
-        ),
-        StatusError,
-    > {
+    ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>
+    {
         todo!()
     }
 
--- a/rust/hg-core/src/dirstate_tree/dispatch.rs	Tue Apr 13 17:02:58 2021 +0200
+++ b/rust/hg-core/src/dirstate_tree/dispatch.rs	Tue Apr 06 15:14:19 2021 +0200
@@ -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<PathBuf>,
         options: StatusOptions,
-    ) -> Result<
-        (
-            (Vec<HgPathCow<'a>>, DirstateStatus<'a>),
-            Vec<PatternFileWarning>,
-        ),
-        StatusError,
-    >;
+    ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>;
 
     fn copy_map_len(&self) -> usize;
 
@@ -270,13 +263,8 @@
         root_dir: PathBuf,
         ignore_files: Vec<PathBuf>,
         options: StatusOptions,
-    ) -> Result<
-        (
-            (Vec<HgPathCow<'a>>, DirstateStatus<'a>),
-            Vec<PatternFileWarning>,
-        ),
-        StatusError,
-    > {
+    ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>
+    {
         crate::status(self, matcher, root_dir, ignore_files, options)
     }
 
--- a/rust/hg-core/src/operations/dirstate_status.rs	Tue Apr 13 17:02:58 2021 +0200
+++ b/rust/hg-core/src/operations/dirstate_status.rs	Tue Apr 06 15:14:19 2021 +0200
@@ -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<HgPathCow<'a>>, DirstateStatus<'a>);
-
 impl<'a, M: ?Sized + Matcher + Sync> Status<'a, M> {
-    pub(crate) fn run(&self) -> Result<LookupAndStatus<'a>, StatusError> {
+    pub(crate) fn run(&self) -> Result<DirstateStatus<'a>, StatusError> {
         let (traversed_sender, traversed_receiver) =
             crossbeam_channel::unbounded();
 
--- a/rust/hg-cpython/src/dirstate/status.rs	Tue Apr 13 17:02:58 2021 +0200
+++ b/rust/hg-cpython/src/dirstate/status.rs	Tue Apr 06 15:14:19 2021 +0200
@@ -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::<ValueError, _>(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::<ValueError, _>(
             py,
@@ -247,7 +247,6 @@
 
 fn build_response(
     py: Python,
-    lookup: Vec<Cow<HgPath>>,
     status_res: DirstateStatus,
     warnings: Vec<PatternFileWarning>,
 ) -> PyResult<PyTuple> {
@@ -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(),
--- a/rust/rhg/src/commands/status.rs	Tue Apr 13 17:02:58 2021 +0200
+++ b/rust/rhg/src/commands/status.rs	Tue Apr 06 15:14:19 2021 +0200
@@ -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<HgPathCow> = Vec::new();
         let mut rechecked_clean: Vec<HgPathCow> = 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 {