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,26 +808,39 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: |
|
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; | |||
|
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? |
|
826 | ignore_fn = ignore; | |
817 | let dir_ignore_fn = |dir: &_| { |
|
827 | let dir_ignore_fn = Box::new(|dir: &_| { | |
818 | if ignore_fn(dir) { |
|
828 | // Is the path or one of its ancestors ignored? | |
819 | true |
|
829 | if ignore_fn(dir) { | |
820 | } else { |
|
830 | true | |
821 | for p in find_dirs(dir) { |
|
831 | } else { | |
822 |
|
|
832 | for p in find_dirs(dir) { | |
823 |
|
|
833 | if ignore_fn(p) { | |
|
834 | return true; | |||
|
835 | } | |||
824 | } |
|
836 | } | |
|
837 | false | |||
825 | } |
|
838 | } | |
826 | false |
|
839 | }); | |
827 | } |
|
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) = |
|
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: |
|
583 | all_pattern_files: Vec<PathBuf>, | |
584 | root_dir: impl AsRef<Path>, |
|
584 | root_dir: impl AsRef<Path>, | |
585 | ) -> PatternResult<( |
|
585 | ) -> PatternResult<( | |
586 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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