##// END OF EJS Templates
rhg: support "status FILE"...
Spencer Baugh -
r51759:c112cc9e default
parent child Browse files
Show More
@@ -366,6 +366,7 b' pub fn parse_one_pattern('
366 pattern: &[u8],
366 pattern: &[u8],
367 source: &Path,
367 source: &Path,
368 default: PatternSyntax,
368 default: PatternSyntax,
369 normalize: bool,
369 ) -> IgnorePattern {
370 ) -> IgnorePattern {
370 let mut pattern_bytes: &[u8] = pattern;
371 let mut pattern_bytes: &[u8] = pattern;
371 let mut syntax = default;
372 let mut syntax = default;
@@ -378,7 +379,19 b' pub fn parse_one_pattern('
378 }
379 }
379 }
380 }
380
381
381 let pattern = pattern_bytes.to_vec();
382 let pattern = match syntax {
383 PatternSyntax::RootGlob
384 | PatternSyntax::Path
385 | PatternSyntax::Glob
386 | PatternSyntax::RelGlob
387 | PatternSyntax::RelPath
388 | PatternSyntax::RootFiles
389 if normalize =>
390 {
391 normalize_path_bytes(pattern_bytes)
392 }
393 _ => pattern_bytes.to_vec(),
394 };
382
395
383 IgnorePattern {
396 IgnorePattern {
384 syntax,
397 syntax,
@@ -438,6 +451,7 b' pub fn parse_pattern_file_contents('
438 line,
451 line,
439 file_path,
452 file_path,
440 current_syntax.clone(),
453 current_syntax.clone(),
454 false,
441 );
455 );
442 inputs.push(if relativize {
456 inputs.push(if relativize {
443 pattern.to_relative()
457 pattern.to_relative()
@@ -449,6 +463,35 b' pub fn parse_pattern_file_contents('
449 Ok((inputs, warnings))
463 Ok((inputs, warnings))
450 }
464 }
451
465
466 pub fn parse_pattern_args(
467 patterns: Vec<Vec<u8>>,
468 cwd: &Path,
469 root: &Path,
470 ) -> Result<Vec<IgnorePattern>, HgPathError> {
471 let mut ignore_patterns: Vec<IgnorePattern> = Vec::new();
472 for pattern in patterns {
473 let pattern = parse_one_pattern(
474 &pattern,
475 Path::new("<args>"),
476 PatternSyntax::RelPath,
477 true,
478 );
479 match pattern.syntax {
480 PatternSyntax::RelGlob | PatternSyntax::RelPath => {
481 let name = get_path_from_bytes(&pattern.pattern);
482 let canon = canonical_path(root, cwd, name)?;
483 ignore_patterns.push(IgnorePattern {
484 syntax: pattern.syntax,
485 pattern: get_bytes_from_path(canon),
486 source: pattern.source,
487 })
488 }
489 _ => ignore_patterns.push(pattern.to_owned()),
490 };
491 }
492 Ok(ignore_patterns)
493 }
494
452 pub fn read_pattern_file(
495 pub fn read_pattern_file(
453 file_path: &Path,
496 file_path: &Path,
454 warn: bool,
497 warn: bool,
@@ -25,7 +25,7 b' pub use dirstate::{'
25 DirstateEntry, DirstateParents, EntryState,
25 DirstateEntry, DirstateParents, EntryState,
26 };
26 };
27 pub mod copy_tracing;
27 pub mod copy_tracing;
28 mod filepatterns;
28 pub mod filepatterns;
29 pub mod matchers;
29 pub mod matchers;
30 pub mod repo;
30 pub mod repo;
31 pub mod revlog;
31 pub mod revlog;
@@ -18,13 +18,15 b' 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;
@@ -49,6 +51,12 b' pub fn args() -> clap::Command {'
49 .alias("st")
51 .alias("st")
50 .about(HELP_TEXT)
52 .about(HELP_TEXT)
51 .arg(
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 )
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')
@@ -367,10 +375,8 b' pub fn run(invocation: &crate::CliInvoca'
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,
@@ -429,6 +435,29 b' pub fn run(invocation: &crate::CliInvoca'
429 (false, true) => sparse_matcher,
435 (false, true) => sparse_matcher,
430 (false, false) => Box::new(AlwaysMatcher),
436 (false, false) => Box::new(AlwaysMatcher),
431 };
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 }
460 };
432
461
433 print_narrow_sparse_warnings(
462 print_narrow_sparse_warnings(
434 &narrow_warnings,
463 &narrow_warnings,
@@ -10,7 +10,8 b' use hg::repo::RepoError;'
10 use hg::revlog::RevlogError;
10 use hg::revlog::RevlogError;
11 use hg::sparse::SparseConfigError;
11 use hg::sparse::SparseConfigError;
12 use hg::utils::files::get_bytes_from_path;
12 use hg::utils::files::get_bytes_from_path;
13 use hg::{DirstateError, DirstateMapError, StatusError};
13 use hg::utils::hg_path::HgPathError;
14 use hg::{DirstateError, DirstateMapError, PatternError, StatusError};
14 use std::convert::From;
15 use std::convert::From;
15
16
16 /// The kind of command error
17 /// The kind of command error
@@ -230,6 +231,18 b' impl From<StatusError> for CommandError '
230 }
231 }
231 }
232 }
232
233
234 impl From<HgPathError> for CommandError {
235 fn from(error: HgPathError) -> Self {
236 CommandError::unsupported(format!("{}", error))
237 }
238 }
239
240 impl From<PatternError> for CommandError {
241 fn from(error: PatternError) -> Self {
242 CommandError::unsupported(format!("{}", error))
243 }
244 }
245
233 impl From<DirstateMapError> for CommandError {
246 impl From<DirstateMapError> for CommandError {
234 fn from(error: DirstateMapError) -> Self {
247 fn from(error: DirstateMapError) -> Self {
235 CommandError::abort(format!("{}", error))
248 CommandError::abort(format!("{}", error))
General Comments 0
You need to be logged in to leave comments. Login now