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