##// END OF EJS Templates
rust-status: only involve ignore mechanism when needed...
Raphaël Gomès -
r45088:e62052d0 default
parent child Browse files
Show More
@@ -33,7 +33,7 b' use std::{'
33 33 fs::{read_dir, DirEntry},
34 34 io::ErrorKind,
35 35 ops::Deref,
36 path::Path,
36 path::{Path, PathBuf},
37 37 };
38 38
39 39 /// Wrong type of file from a `BadMatch`
@@ -94,6 +94,9 b' enum Dispatch {'
94 94 }
95 95
96 96 type IoResult<T> = std::io::Result<T>;
97 /// `Box<dyn Trait>` is syntactic sugar for `Box<dyn Trait, 'static>`, so add
98 /// an explicit lifetime here to not fight `'static` bounds "out of nowhere".
99 type IgnoreFnType<'a> = Box<dyn for<'r> Fn(&'r HgPath) -> bool + Sync + 'a>;
97 100
98 101 /// Dates and times that are outside the 31-bit signed range are compared
99 102 /// modulo 2^31. This should prevent hg from behaving badly with very large
@@ -312,8 +315,8 b" fn handle_traversed_entry<'a>("
312 315 root_dir: impl AsRef<Path> + Sync + Send + Copy + 'a,
313 316 dmap: &'a DirstateMap,
314 317 old_results: &'a FastHashMap<Cow<HgPath>, Dispatch>,
315 ignore_fn: &'a (impl for<'r> Fn(&'r HgPath) -> bool + Sync),
316 dir_ignore_fn: &'a (impl for<'r> Fn(&'r HgPath) -> bool + Sync),
318 ignore_fn: &'a IgnoreFnType,
319 dir_ignore_fn: &'a IgnoreFnType,
317 320 options: StatusOptions,
318 321 filename: HgPathBuf,
319 322 dir_entry: DirEntry,
@@ -393,8 +396,8 b" fn handle_traversed_dir<'a>("
393 396 root_dir: impl AsRef<Path> + Sync + Send + Copy + 'a,
394 397 dmap: &'a DirstateMap,
395 398 old_results: &'a FastHashMap<Cow<HgPath>, Dispatch>,
396 ignore_fn: &'a (impl for<'r> Fn(&'r HgPath) -> bool + Sync),
397 dir_ignore_fn: &'a (impl for<'r> Fn(&'r HgPath) -> bool + Sync),
399 ignore_fn: &'a IgnoreFnType,
400 dir_ignore_fn: &'a IgnoreFnType,
398 401 options: StatusOptions,
399 402 entry_option: Option<&'a DirstateEntry>,
400 403 directory: HgPathBuf,
@@ -439,8 +442,8 b" fn traverse_dir<'a>("
439 442 dmap: &'a DirstateMap,
440 443 directory: impl AsRef<HgPath>,
441 444 old_results: &FastHashMap<Cow<'a, HgPath>, Dispatch>,
442 ignore_fn: &(impl for<'r> Fn(&'r HgPath) -> bool + Sync),
443 dir_ignore_fn: &(impl for<'r> Fn(&'r HgPath) -> bool + Sync),
445 ignore_fn: &IgnoreFnType,
446 dir_ignore_fn: &IgnoreFnType,
444 447 options: StatusOptions,
445 448 ) -> IoResult<()> {
446 449 let directory = directory.as_ref();
@@ -522,8 +525,8 b" fn traverse<'a>("
522 525 dmap: &'a DirstateMap,
523 526 path: impl AsRef<HgPath>,
524 527 old_results: &FastHashMap<Cow<'a, HgPath>, Dispatch>,
525 ignore_fn: &(impl for<'r> Fn(&'r HgPath) -> bool + Sync),
526 dir_ignore_fn: &(impl for<'r> Fn(&'r HgPath) -> bool + Sync),
528 ignore_fn: &IgnoreFnType,
529 dir_ignore_fn: &IgnoreFnType,
527 530 options: StatusOptions,
528 531 results: &mut Vec<(Cow<'a, HgPath>, Dispatch)>,
529 532 ) -> IoResult<()> {
@@ -805,26 +808,39 b" pub fn status<'a: 'c, 'b: 'c, 'c>("
805 808 dmap: &'a DirstateMap,
806 809 matcher: &'b (impl Matcher + Sync),
807 810 root_dir: impl AsRef<Path> + Sync + Send + Copy + 'c,
808 ignore_files: &[impl AsRef<Path> + 'c],
811 ignore_files: Vec<PathBuf>,
809 812 options: StatusOptions,
810 813 ) -> StatusResult<(
811 814 (Vec<Cow<'c, HgPath>>, DirstateStatus<'c>),
812 815 Vec<PatternFileWarning>,
813 816 )> {
814 let (ignore_fn, warnings) = get_ignore_function(&ignore_files, root_dir)?;
817 // Needs to outlive `dir_ignore_fn` since it's captured.
818 let mut ignore_fn: IgnoreFnType;
819
820 // Only involve real ignore mechanism if we're listing unknowns or ignored.
821 let (dir_ignore_fn, warnings): (IgnoreFnType, _) = if options.list_ignored
822 || options.list_unknown
823 {
824 let (ignore, warnings) = get_ignore_function(ignore_files, root_dir)?;
815 825
816 // Is the path or one of its ancestors ignored?
817 let dir_ignore_fn = |dir: &_| {
818 if ignore_fn(dir) {
819 true
820 } else {
821 for p in find_dirs(dir) {
822 if ignore_fn(p) {
823 return true;
826 ignore_fn = ignore;
827 let dir_ignore_fn = Box::new(|dir: &_| {
828 // Is the path or one of its ancestors ignored?
829 if ignore_fn(dir) {
830 true
831 } else {
832 for p in find_dirs(dir) {
833 if ignore_fn(p) {
834 return true;
835 }
824 836 }
837 false
825 838 }
826 false
827 }
839 });
840 (dir_ignore_fn, warnings)
841 } else {
842 ignore_fn = Box::new(|&_| true);
843 (Box::new(|&_| true), vec![])
828 844 };
829 845
830 846 let files = matcher.file_set();
@@ -24,12 +24,12 b' use crate::{'
24 24 PatternSyntax,
25 25 };
26 26
27 use micro_timer::timed;
27 use std::borrow::ToOwned;
28 28 use std::collections::HashSet;
29 29 use std::fmt::{Display, Error, Formatter};
30 30 use std::iter::FromIterator;
31 31 use std::ops::Deref;
32 use std::path::Path;
32 use std::path::{Path, PathBuf};
33 33
34 34 #[derive(Debug, PartialEq)]
35 35 pub enum VisitChildrenSet<'a> {
@@ -507,7 +507,8 b" fn build_match<'a, 'b>("
507 507 let mut prefixes = vec![];
508 508
509 509 for SubInclude { prefix, root, path } in subincludes.into_iter() {
510 let (match_fn, warnings) = get_ignore_function(&[path], root)?;
510 let (match_fn, warnings) =
511 get_ignore_function(vec![path.to_path_buf()], root)?;
511 512 all_warnings.extend(warnings);
512 513 prefixes.push(prefix.to_owned());
513 514 submatchers.insert(prefix.to_owned(), match_fn);
@@ -578,12 +579,11 b" fn build_match<'a, 'b>("
578 579 /// Parses all "ignore" files with their recursive includes and returns a
579 580 /// function that checks whether a given file (in the general sense) should be
580 581 /// ignored.
581 #[timed]
582 582 pub fn get_ignore_function<'a>(
583 all_pattern_files: &[impl AsRef<Path>],
583 all_pattern_files: Vec<PathBuf>,
584 584 root_dir: impl AsRef<Path>,
585 585 ) -> PatternResult<(
586 impl for<'r> Fn(&'r HgPath) -> bool + Sync,
586 Box<dyn for<'r> Fn(&'r HgPath) -> bool + Sync + 'a>,
587 587 Vec<PatternFileWarning>,
588 588 )> {
589 589 let mut all_patterns = vec![];
@@ -593,12 +593,15 b" pub fn get_ignore_function<'a>("
593 593 let (patterns, warnings) =
594 594 get_patterns_from_file(pattern_file, &root_dir)?;
595 595
596 all_patterns.extend(patterns);
596 all_patterns.extend(patterns.to_owned());
597 597 all_warnings.extend(warnings);
598 598 }
599 599 let (matcher, warnings) = IncludeMatcher::new(all_patterns, root_dir)?;
600 600 all_warnings.extend(warnings);
601 Ok((move |path: &HgPath| matcher.matches(path), all_warnings))
601 Ok((
602 Box::new(move |path: &HgPath| matcher.matches(path)),
603 all_warnings,
604 ))
602 605 }
603 606
604 607 impl<'a> IncludeMatcher<'a> {
@@ -127,7 +127,7 b' pub fn status_wrapper('
127 127 &dmap,
128 128 &matcher,
129 129 &root_dir,
130 &ignore_files,
130 ignore_files,
131 131 StatusOptions {
132 132 check_exec,
133 133 last_normal_time,
@@ -163,7 +163,7 b' pub fn status_wrapper('
163 163 &dmap,
164 164 &matcher,
165 165 &root_dir,
166 &ignore_files,
166 ignore_files,
167 167 StatusOptions {
168 168 check_exec,
169 169 last_normal_time,
@@ -217,7 +217,7 b' pub fn status_wrapper('
217 217 &dmap,
218 218 &matcher,
219 219 &root_dir,
220 &ignore_files,
220 ignore_files,
221 221 StatusOptions {
222 222 check_exec,
223 223 last_normal_time,
General Comments 0
You need to be logged in to leave comments. Login now