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: |
|
|
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 |
|
|
|
823 |
|
|
|
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) = |
|
|
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: |
|
|
583 | all_pattern_files: Vec<PathBuf>, | |
|
584 | 584 | root_dir: impl AsRef<Path>, |
|
585 | 585 | ) -> PatternResult<( |
|
586 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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