# HG changeset patch # User Spencer Baugh # Date 1692302012 14400 # Node ID 788113f056d4f9b4881fd35f3f2dda8e8254a325 # Parent c112cc9effdc8200f60fd209365e56ef32176eda rhg: support rhg files [FILE] This comes mostly for free after the rhg status [FILE] implementation. diff -r c112cc9effdc -r 788113f056d4 rust/rhg/src/commands/files.rs --- a/rust/rhg/src/commands/files.rs Wed Aug 02 10:46:47 2023 -0400 +++ b/rust/rhg/src/commands/files.rs Thu Aug 17 15:53:32 2023 -0400 @@ -4,9 +4,12 @@ }; use crate::utils::path_utils::RelativizePaths; use clap::Arg; +use hg::filepatterns::parse_pattern_args; +use hg::matchers::IntersectionMatcher; use hg::narrow; use hg::operations::list_rev_tracked_files; use hg::repo::Repo; +use hg::utils::files::get_bytes_from_os_str; use hg::utils::filter_map_results; use hg::utils::hg_path::HgPath; use rayon::prelude::*; @@ -26,6 +29,12 @@ .long("revision") .value_name("REV"), ) + .arg( + Arg::new("file") + .value_parser(clap::value_parser!(std::ffi::OsString)) + .help("show only these files") + .action(clap::ArgAction::Append), + ) .about(HELP_TEXT) } @@ -35,7 +44,8 @@ RelativePaths::Bool(v) => v, }; - let rev = invocation.subcommand_args.get_one::("rev"); + let args = invocation.subcommand_args; + let rev = args.get_one::("rev"); let repo = invocation.repo?; @@ -51,11 +61,34 @@ )); } - let (narrow_matcher, narrow_warnings) = narrow::matcher(repo)?; + let (matcher, narrow_warnings) = narrow::matcher(repo)?; print_narrow_sparse_warnings(&narrow_warnings, &[], invocation.ui, repo)?; + let matcher = match args.get_many::("file") { + None => matcher, + Some(files) => { + let patterns: Vec> = 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, + )) + } + }; if let Some(rev) = rev { - let files = list_rev_tracked_files(repo, rev, narrow_matcher) + let files = list_rev_tracked_files(repo, rev, matcher) .map_err(|e| (e, rev.as_ref()))?; display_files(invocation.ui, repo, relative_paths, files.iter()) } else { @@ -63,7 +96,7 @@ let dirstate = repo.dirstate_map()?; let files_res: Result, _> = filter_map_results(dirstate.iter(), |(path, entry)| { - Ok(if entry.tracked() && narrow_matcher.matches(path) { + Ok(if entry.tracked() && matcher.matches(path) { Some(path) } else { None