8 use crate::error::CommandError; |
8 use crate::error::CommandError; |
9 use crate::ui::Ui; |
9 use crate::ui::Ui; |
10 use crate::utils::path_utils::RelativizePaths; |
10 use crate::utils::path_utils::RelativizePaths; |
11 use clap::{Arg, SubCommand}; |
11 use clap::{Arg, SubCommand}; |
12 use format_bytes::format_bytes; |
12 use format_bytes::format_bytes; |
13 use hg; |
|
14 use hg::config::Config; |
13 use hg::config::Config; |
15 use hg::dirstate::has_exec_bit; |
14 use hg::dirstate::has_exec_bit; |
16 use hg::dirstate::status::StatusPath; |
15 use hg::dirstate::status::StatusPath; |
17 use hg::dirstate::TruncatedTimestamp; |
16 use hg::dirstate::TruncatedTimestamp; |
18 use hg::errors::{HgError, IoResultExt}; |
17 use hg::errors::{HgError, IoResultExt}; |
19 use hg::lock::LockError; |
18 use hg::lock::LockError; |
20 use hg::manifest::Manifest; |
19 use hg::manifest::Manifest; |
|
20 use hg::matchers::{AlwaysMatcher, IntersectionMatcher}; |
21 use hg::repo::Repo; |
21 use hg::repo::Repo; |
22 use hg::sparse::{matcher, SparseWarning}; |
|
23 use hg::utils::files::get_bytes_from_os_string; |
22 use hg::utils::files::get_bytes_from_os_string; |
24 use hg::utils::files::get_bytes_from_path; |
23 use hg::utils::files::get_bytes_from_path; |
25 use hg::utils::files::get_path_from_bytes; |
24 use hg::utils::files::get_path_from_bytes; |
26 use hg::utils::hg_path::{hg_path_to_path_buf, HgPath}; |
25 use hg::utils::hg_path::{hg_path_to_path_buf, HgPath}; |
27 use hg::DirstateStatus; |
26 use hg::DirstateStatus; |
28 use hg::PatternFileWarning; |
27 use hg::PatternFileWarning; |
29 use hg::StatusError; |
28 use hg::StatusError; |
30 use hg::StatusOptions; |
29 use hg::StatusOptions; |
|
30 use hg::{self, narrow, sparse}; |
31 use log::info; |
31 use log::info; |
32 use std::io; |
32 use std::io; |
33 use std::path::PathBuf; |
33 use std::path::PathBuf; |
34 |
34 |
35 pub const HELP_TEXT: &str = " |
35 pub const HELP_TEXT: &str = " |
249 "verbose status output is not supported by rhg (and is needed because we're in an unfinished operation)", |
249 "verbose status output is not supported by rhg (and is needed because we're in an unfinished operation)", |
250 )); |
250 )); |
251 }; |
251 }; |
252 } |
252 } |
253 |
253 |
254 if repo.has_narrow() { |
|
255 return Err(CommandError::unsupported( |
|
256 "rhg status is not supported for narrow clones yet", |
|
257 )); |
|
258 } |
|
259 |
|
260 let mut dmap = repo.dirstate_map_mut()?; |
254 let mut dmap = repo.dirstate_map_mut()?; |
261 |
255 |
262 let options = StatusOptions { |
256 let options = StatusOptions { |
263 // we're currently supporting file systems with exec flags only |
257 // we're currently supporting file systems with exec flags only |
264 // anyway |
258 // anyway |
364 fixup, |
358 fixup, |
365 dirstate_write_needed, |
359 dirstate_write_needed, |
366 filesystem_time_at_status_start, |
360 filesystem_time_at_status_start, |
367 )) |
361 )) |
368 }; |
362 }; |
369 let (matcher, sparse_warnings) = matcher(repo)?; |
363 let (narrow_matcher, narrow_warnings) = narrow::matcher(repo)?; |
370 |
364 let (sparse_matcher, sparse_warnings) = sparse::matcher(repo)?; |
371 for warning in sparse_warnings { |
365 let matcher = match (repo.has_narrow(), repo.has_sparse()) { |
|
366 (true, true) => { |
|
367 Box::new(IntersectionMatcher::new(narrow_matcher, sparse_matcher)) |
|
368 } |
|
369 (true, false) => narrow_matcher, |
|
370 (false, true) => sparse_matcher, |
|
371 (false, false) => Box::new(AlwaysMatcher), |
|
372 }; |
|
373 |
|
374 for warning in narrow_warnings.into_iter().chain(sparse_warnings) { |
372 match &warning { |
375 match &warning { |
373 SparseWarning::RootWarning { context, line } => { |
376 sparse::SparseWarning::RootWarning { context, line } => { |
374 let msg = format_bytes!( |
377 let msg = format_bytes!( |
375 b"warning: {} profile cannot use paths \" |
378 b"warning: {} profile cannot use paths \" |
376 starting with /, ignoring {}\n", |
379 starting with /, ignoring {}\n", |
377 context, |
380 context, |
378 line |
381 line |
379 ); |
382 ); |
380 ui.write_stderr(&msg)?; |
383 ui.write_stderr(&msg)?; |
381 } |
384 } |
382 SparseWarning::ProfileNotFound { profile, rev } => { |
385 sparse::SparseWarning::ProfileNotFound { profile, rev } => { |
383 let msg = format_bytes!( |
386 let msg = format_bytes!( |
384 b"warning: sparse profile '{}' not found \" |
387 b"warning: sparse profile '{}' not found \" |
385 in rev {} - ignoring it\n", |
388 in rev {} - ignoring it\n", |
386 profile, |
389 profile, |
387 rev |
390 rev |
388 ); |
391 ); |
389 ui.write_stderr(&msg)?; |
392 ui.write_stderr(&msg)?; |
390 } |
393 } |
391 SparseWarning::Pattern(e) => { |
394 sparse::SparseWarning::Pattern(e) => { |
392 ui.write_stderr(&print_pattern_file_warning(e, &repo))?; |
395 ui.write_stderr(&print_pattern_file_warning(e, &repo))?; |
393 } |
396 } |
394 } |
397 } |
395 } |
398 } |
396 let (fixup, mut dirstate_write_needed, filesystem_time_at_status_start) = |
399 let (fixup, mut dirstate_write_needed, filesystem_time_at_status_start) = |