Mercurial > public > mercurial-scm > hg-stable
comparison rust/hg-core/src/filepatterns.rs @ 52385:e2e49069eeb6
rust-ignore: make `debugignorerhg` command show a full regex, with exact files
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Tue, 03 Dec 2024 13:51:51 +0000 |
parents | 2ff004fb491c |
children | 1866119cbad7 |
comparison
equal
deleted
inserted
replaced
52384:2ff004fb491c | 52385:e2e49069eeb6 |
---|---|
366 } else { | 366 } else { |
367 new_bytes | 367 new_bytes |
368 } | 368 } |
369 } | 369 } |
370 | 370 |
371 /// Controls whether we want the emitted regex to cover all cases | |
372 /// or just the cases that are not covered by optimized code paths. | |
373 #[derive(Debug, Clone, Copy)] | |
374 pub enum RegexCompleteness { | |
375 /// `Complete` emits a regex that handles all files, including the ones | |
376 /// that are typically handled by a different code path. | |
377 /// This is used in `hg debugignorerhg -a` to avoid missing some rules. | |
378 Complete, | |
379 /// `ExcludeExactFiles` excludes the patterns that correspond to exact | |
380 /// file matches. This is the normal behavior, and gives a potentially | |
381 /// much smaller regex. | |
382 ExcludeExactFiles, | |
383 } | |
384 | |
385 impl RegexCompleteness { | |
386 fn may_exclude_exact_files(self) -> bool { | |
387 match self { | |
388 Self::Complete => false, | |
389 Self::ExcludeExactFiles => true, | |
390 } | |
391 } | |
392 } | |
393 | |
371 /// Wrapper function to `_build_single_regex` that short-circuits 'exact' globs | 394 /// Wrapper function to `_build_single_regex` that short-circuits 'exact' globs |
372 /// that don't need to be transformed into a regex. | 395 /// that don't need to be transformed into a regex. |
373 pub fn build_single_regex( | 396 pub fn build_single_regex( |
374 entry: &IgnorePattern, | 397 entry: &IgnorePattern, |
375 glob_suffix: GlobSuffix, | 398 glob_suffix: GlobSuffix, |
399 regex_config: RegexCompleteness, | |
376 ) -> Result<Option<Vec<u8>>, PatternError> { | 400 ) -> Result<Option<Vec<u8>>, PatternError> { |
377 let IgnorePattern { | 401 let IgnorePattern { |
378 pattern, syntax, .. | 402 pattern, syntax, .. |
379 } = entry; | 403 } = entry; |
380 let pattern = match syntax { | 404 let pattern = match syntax { |
388 } | 412 } |
389 _ => pattern.to_owned(), | 413 _ => pattern.to_owned(), |
390 }; | 414 }; |
391 let is_simple_rootglob = *syntax == PatternSyntax::RootGlob | 415 let is_simple_rootglob = *syntax == PatternSyntax::RootGlob |
392 && !pattern.iter().any(|b| GLOB_SPECIAL_CHARACTERS.contains(b)); | 416 && !pattern.iter().any(|b| GLOB_SPECIAL_CHARACTERS.contains(b)); |
393 if is_simple_rootglob || syntax == &PatternSyntax::FilePath { | 417 if regex_config.may_exclude_exact_files() |
418 && (is_simple_rootglob || syntax == &PatternSyntax::FilePath) | |
419 { | |
394 Ok(None) | 420 Ok(None) |
395 } else { | 421 } else { |
396 let mut entry = entry.clone(); | 422 let mut entry = entry.clone(); |
397 entry.pattern = pattern; | 423 entry.pattern = pattern; |
398 Ok(Some(_build_single_regex(&entry, glob_suffix))) | 424 Ok(Some(_build_single_regex(&entry, glob_suffix))) |
816 Path::new("file_path") | 842 Path::new("file_path") |
817 )] | 843 )] |
818 ); | 844 ); |
819 } | 845 } |
820 | 846 |
847 pub fn build_single_regex( | |
848 entry: &IgnorePattern, | |
849 glob_suffix: GlobSuffix, | |
850 ) -> Result<Option<Vec<u8>>, PatternError> { | |
851 super::build_single_regex( | |
852 entry, | |
853 glob_suffix, | |
854 RegexCompleteness::ExcludeExactFiles, | |
855 ) | |
856 } | |
857 | |
821 #[test] | 858 #[test] |
822 fn test_build_single_regex() { | 859 fn test_build_single_regex() { |
823 assert_eq!( | 860 assert_eq!( |
824 build_single_regex( | 861 build_single_regex( |
825 &IgnorePattern::new( | 862 &IgnorePattern::new( |