rust/rhg/src/commands/status.rs
changeset 50866 c112cc9effdc
parent 50763 f8412da86d05
child 51153 976403c95ba3
equal deleted inserted replaced
50865:f874342fa568 50866:c112cc9effdc
    16 use hg::config::Config;
    16 use hg::config::Config;
    17 use hg::dirstate::has_exec_bit;
    17 use hg::dirstate::has_exec_bit;
    18 use hg::dirstate::status::StatusPath;
    18 use hg::dirstate::status::StatusPath;
    19 use hg::dirstate::TruncatedTimestamp;
    19 use hg::dirstate::TruncatedTimestamp;
    20 use hg::errors::{HgError, IoResultExt};
    20 use hg::errors::{HgError, IoResultExt};
       
    21 use hg::filepatterns::parse_pattern_args;
    21 use hg::lock::LockError;
    22 use hg::lock::LockError;
    22 use hg::manifest::Manifest;
    23 use hg::manifest::Manifest;
    23 use hg::matchers::{AlwaysMatcher, IntersectionMatcher};
    24 use hg::matchers::{AlwaysMatcher, IntersectionMatcher};
    24 use hg::repo::Repo;
    25 use hg::repo::Repo;
    25 use hg::utils::debug::debug_wait_for_file;
    26 use hg::utils::debug::debug_wait_for_file;
    26 use hg::utils::files::get_bytes_from_os_string;
    27 use hg::utils::files::{
    27 use hg::utils::files::get_path_from_bytes;
    28     get_bytes_from_os_str, get_bytes_from_os_string, get_path_from_bytes,
       
    29 };
    28 use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
    30 use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
    29 use hg::DirstateStatus;
    31 use hg::DirstateStatus;
    30 use hg::PatternFileWarning;
    32 use hg::PatternFileWarning;
    31 use hg::StatusError;
    33 use hg::StatusError;
    32 use hg::StatusOptions;
    34 use hg::StatusOptions;
    46 
    48 
    47 pub fn args() -> clap::Command {
    49 pub fn args() -> clap::Command {
    48     clap::command!("status")
    50     clap::command!("status")
    49         .alias("st")
    51         .alias("st")
    50         .about(HELP_TEXT)
    52         .about(HELP_TEXT)
       
    53         .arg(
       
    54             Arg::new("file")
       
    55                 .value_parser(clap::value_parser!(std::ffi::OsString))
       
    56                 .help("show only these files")
       
    57                 .action(clap::ArgAction::Append),
       
    58         )
    51         .arg(
    59         .arg(
    52             Arg::new("all")
    60             Arg::new("all")
    53                 .help("show status of all files")
    61                 .help("show status of all files")
    54                 .short('A')
    62                 .short('A')
    55                 .action(clap::ArgAction::SetTrue)
    63                 .action(clap::ArgAction::SetTrue)
   365         let relative_status = config
   373         let relative_status = config
   366             .get_option(b"commands", b"status.relative")?
   374             .get_option(b"commands", b"status.relative")?
   367             .expect("commands.status.relative should have a default value");
   375             .expect("commands.status.relative should have a default value");
   368 
   376 
   369         let relativize_paths = relative_status || {
   377         let relativize_paths = relative_status || {
   370             // TODO should be dependent on whether patterns are passed once
       
   371             // we support those.
       
   372             // See in Python code with `getuipathfn` usage in `commands.py`.
   378             // See in Python code with `getuipathfn` usage in `commands.py`.
   373             let legacy_relative_behavior = false;
   379             let legacy_relative_behavior = args.contains_id("file");
   374             match relative_paths(invocation.config)? {
   380             match relative_paths(invocation.config)? {
   375                 RelativePaths::Legacy => legacy_relative_behavior,
   381                 RelativePaths::Legacy => legacy_relative_behavior,
   376                 RelativePaths::Bool(v) => v,
   382                 RelativePaths::Bool(v) => v,
   377             }
   383             }
   378         };
   384         };
   426             Box::new(IntersectionMatcher::new(narrow_matcher, sparse_matcher))
   432             Box::new(IntersectionMatcher::new(narrow_matcher, sparse_matcher))
   427         }
   433         }
   428         (true, false) => narrow_matcher,
   434         (true, false) => narrow_matcher,
   429         (false, true) => sparse_matcher,
   435         (false, true) => sparse_matcher,
   430         (false, false) => Box::new(AlwaysMatcher),
   436         (false, false) => Box::new(AlwaysMatcher),
       
   437     };
       
   438     let matcher = match args.get_many::<std::ffi::OsString>("file") {
       
   439         None => matcher,
       
   440         Some(files) => {
       
   441             let patterns: Vec<Vec<u8>> = files
       
   442                 .filter(|s| !s.is_empty())
       
   443                 .map(get_bytes_from_os_str)
       
   444                 .collect();
       
   445             for file in &patterns {
       
   446                 if file.starts_with(b"set:") {
       
   447                     return Err(CommandError::unsupported("fileset"));
       
   448                 }
       
   449             }
       
   450             let cwd = hg::utils::current_dir()?;
       
   451             let root = repo.working_directory_path();
       
   452             let ignore_patterns = parse_pattern_args(patterns, &cwd, root)?;
       
   453             let files_matcher =
       
   454                 hg::matchers::PatternMatcher::new(ignore_patterns)?;
       
   455             Box::new(IntersectionMatcher::new(
       
   456                 Box::new(files_matcher),
       
   457                 matcher,
       
   458             ))
       
   459         }
   431     };
   460     };
   432 
   461 
   433     print_narrow_sparse_warnings(
   462     print_narrow_sparse_warnings(
   434         &narrow_warnings,
   463         &narrow_warnings,
   435         &sparse_warnings,
   464         &sparse_warnings,