diff rust/rhg/src/commands/status.rs @ 50866:c112cc9effdc

rhg: support "status FILE" This change adds a new [file] argument to rhg status, parses them as patterns, canonicalizes the paths, and constructs a new PatternMatcher to intersect with the existing matcher being passed to the status implementation. We also make filepatterns a public module so we can access the pattern-parsing functionality we need from commands/status.rs.
author Spencer Baugh <sbaugh@janestreet.com>
date Wed, 02 Aug 2023 10:46:47 -0400
parents f8412da86d05
children 976403c95ba3
line wrap: on
line diff
--- a/rust/rhg/src/commands/status.rs	Wed Aug 02 10:16:33 2023 -0400
+++ b/rust/rhg/src/commands/status.rs	Wed Aug 02 10:46:47 2023 -0400
@@ -18,13 +18,15 @@
 use hg::dirstate::status::StatusPath;
 use hg::dirstate::TruncatedTimestamp;
 use hg::errors::{HgError, IoResultExt};
+use hg::filepatterns::parse_pattern_args;
 use hg::lock::LockError;
 use hg::manifest::Manifest;
 use hg::matchers::{AlwaysMatcher, IntersectionMatcher};
 use hg::repo::Repo;
 use hg::utils::debug::debug_wait_for_file;
-use hg::utils::files::get_bytes_from_os_string;
-use hg::utils::files::get_path_from_bytes;
+use hg::utils::files::{
+    get_bytes_from_os_str, get_bytes_from_os_string, get_path_from_bytes,
+};
 use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
 use hg::DirstateStatus;
 use hg::PatternFileWarning;
@@ -49,6 +51,12 @@
         .alias("st")
         .about(HELP_TEXT)
         .arg(
+            Arg::new("file")
+                .value_parser(clap::value_parser!(std::ffi::OsString))
+                .help("show only these files")
+                .action(clap::ArgAction::Append),
+        )
+        .arg(
             Arg::new("all")
                 .help("show status of all files")
                 .short('A')
@@ -367,10 +375,8 @@
             .expect("commands.status.relative should have a default value");
 
         let relativize_paths = relative_status || {
-            // TODO should be dependent on whether patterns are passed once
-            // we support those.
             // See in Python code with `getuipathfn` usage in `commands.py`.
-            let legacy_relative_behavior = false;
+            let legacy_relative_behavior = args.contains_id("file");
             match relative_paths(invocation.config)? {
                 RelativePaths::Legacy => legacy_relative_behavior,
                 RelativePaths::Bool(v) => v,
@@ -429,6 +435,29 @@
         (false, true) => sparse_matcher,
         (false, false) => Box::new(AlwaysMatcher),
     };
+    let matcher = match args.get_many::<std::ffi::OsString>("file") {
+        None => matcher,
+        Some(files) => {
+            let patterns: Vec<Vec<u8>> = files
+                .filter(|s| !s.is_empty())
+                .map(get_bytes_from_os_str)
+                .collect();
+            for file in &patterns {
+                if file.starts_with(b"set:") {
+                    return Err(CommandError::unsupported("fileset"));
+                }
+            }
+            let cwd = hg::utils::current_dir()?;
+            let root = repo.working_directory_path();
+            let ignore_patterns = parse_pattern_args(patterns, &cwd, root)?;
+            let files_matcher =
+                hg::matchers::PatternMatcher::new(ignore_patterns)?;
+            Box::new(IntersectionMatcher::new(
+                Box::new(files_matcher),
+                matcher,
+            ))
+        }
+    };
 
     print_narrow_sparse_warnings(
         &narrow_warnings,