summaryrefslogtreecommitdiffstats
path: root/ignore
diff options
context:
space:
mode:
authorDavid Torosyan <davidtorosyan.git@gmail.com>2019-01-20 17:32:34 -0800
committerAndrew Gallant <jamslam@gmail.com>2019-01-22 20:03:59 -0500
commit718a00f6f2f88238546f7d33c1ea52217002495e (patch)
tree6dc4db1c1d1af1f5d87957754341b4f74ff41984 /ignore
parent7cbc535d70a53c81dfa3e58552c01f21c2e38d28 (diff)
ripgrep: add --ignore-file-case-insensitive
The --ignore-file-case-insensitive flag causes all .gitignore/.rgignore/.ignore files to have their globs matched without regard for case. Because this introduces a potentially significant performance regression, this is always disabled by default. Users that need case insensitive matching can enable it on a case by case basis. Closes #1164, Closes #1170
Diffstat (limited to 'ignore')
-rw-r--r--ignore/src/dir.rs49
-rw-r--r--ignore/src/gitignore.rs49
-rw-r--r--ignore/src/overrides.rs7
-rw-r--r--ignore/src/walk.rs8
4 files changed, 94 insertions, 19 deletions
diff --git a/ignore/src/dir.rs b/ignore/src/dir.rs
index 66b18635..30f4cb87 100644
--- a/ignore/src/dir.rs
+++ b/ignore/src/dir.rs
@@ -73,6 +73,8 @@ struct IgnoreOptions {
git_ignore: bool,
/// Whether to read .git/info/exclude files.
git_exclude: bool,
+ /// Whether to ignore files case insensitively
+ ignore_case_insensitive: bool,
}
/// Ignore is a matcher useful for recursively walking one or more directories.
@@ -225,7 +227,11 @@ impl Ignore {
Gitignore::empty()
} else {
let (m, err) =
- create_gitignore(&dir, &self.0.custom_ignore_filenames);
+ create_gitignore(
+ &dir,
+ &self.0.custom_ignore_filenames,
+ self.0.opts.ignore_case_insensitive,
+ );
errs.maybe_push(err);
m
};
@@ -233,7 +239,12 @@ impl Ignore {
if !self.0.opts.ignore {
Gitignore::empty()
} else {
- let (m, err) = create_gitignore(&dir, &[".ignore"]);
+ let (m, err) =
+ create_gitignore(
+ &dir,
+ &[".ignore"],
+ self.0.opts.ignore_case_insensitive,
+ );
errs.maybe_push(err);
m
};
@@ -241,7 +252,12 @@ impl Ignore {
if !self.0.opts.git_ignore {
Gitignore::empty()
} else {
- let (m, err) = create_gitignore(&dir, &[".gitignore"]);
+ let (m, err) =
+ create_gitignore(
+ &dir,
+ &[".gitignore"],
+ self.0.opts.ignore_case_insensitive,
+ );
errs.maybe_push(err);
m
};
@@ -249,7 +265,12 @@ impl Ignore {
if !self.0.opts.git_exclude {
Gitignore::empty()
} else {
- let (m, err) = create_gitignore(&dir, &[".git/info/exclude"]);
+ let (m, err) =
+ create_gitignore(
+ &dir,
+ &[".git/info/exclude"],
+ self.0.opts.ignore_case_insensitive,
+ );
errs.maybe_push(err);
m
};
@@ -483,6 +504,7 @@ impl IgnoreBuilder {
git_global: true,
git_ignore: true,
git_exclude: true,
+ ignore_case_insensitive: false,
},
}
}
@@ -496,7 +518,11 @@ impl IgnoreBuilder {
if !self.opts.git_global {
Gitignore::empty()
} else {
- let (gi, err) = Gitignore::global();
+ let mut builder = GitignoreBuilder::new("");
+ builder
+ .case_insensitive(self.opts.ignore_case_insensitive)
+ .unwrap();
+ let (gi, err) = builder.build_global();
if let Some(err) = err {
debug!("{}", err);
}
@@ -627,6 +653,17 @@ impl IgnoreBuilder {
self.opts.git_exclude = yes;
self
}
+
+ /// Process ignore files case insensitively
+ ///
+ /// This is disabled by default.
+ pub fn ignore_case_insensitive(
+ &mut self,
+ yes: bool,
+ ) -> &mut IgnoreBuilder {
+ self.opts.ignore_case_insensitive = yes;
+ self
+ }
}
/// Creates a new gitignore matcher for the directory given.
@@ -638,9 +675,11 @@ impl IgnoreBuilder {
pub fn create_gitignore<T: AsRef<OsStr>>(
dir: &Path,
names: &[T],
+ case_insensitive: bool,
) -> (Gitignore, Option<Error>) {
let mut builder = GitignoreBuilder::new(dir);
let mut errs = PartialErrorBuilder::default();
+ builder.case_insensitive(case_insensitive).unwrap();
for name in names {
let gipath = dir.join(name.as_ref());
errs.maybe_push_ignore_io(builder.add(gipath));
diff --git a/ignore/src/gitignore.rs b/ignore/src/gitignore.rs
index a151e2de..66f98dfe 100644
--- a/ignore/src/gitignore.rs
+++ b/ignore/src/gitignore.rs
@@ -127,16 +127,7 @@ impl Gitignore {
/// `$XDG_CONFIG_HOME/git/ignore` is read. If `$XDG_CONFIG_HOME` is not
/// set or is empty, then `$HOME/.config/git/ignore` is used instead.
pub fn global() -> (Gitignore, Option<Error>) {
- match gitconfig_excludes_path() {
- None => (Gitignore::empty(), None),
- Some(path) => {
- if !path.is_file() {
- (Gitignore::empty(), None)
- } else {
- Gitignore::new(path)
- }
- }
- }
+ GitignoreBuilder::new("").build_global()
}
/// Creates a new empty gitignore matcher that never matches anything.
@@ -359,6 +350,36 @@ impl GitignoreBuilder {
})
}
+ /// Build a global gitignore matcher using the configuration in this
+ /// builder.
+ ///
+ /// This consumes ownership of the builder unlike `build` because it
+ /// must mutate the builder to add the global gitignore globs.
+ ///
+ /// Note that this ignores the path given to this builder's constructor
+ /// and instead derives the path automatically from git's global
+ /// configuration.
+ pub fn build_global(mut self) -> (Gitignore, Option<Error>) {
+ match gitconfig_excludes_path() {
+ None => (Gitignore::empty(), None),
+ Some(path) => {
+ if !path.is_file() {
+ (Gitignore::empty(), None)
+ } else {
+ let mut errs = PartialErrorBuilder::default();
+ errs.maybe_push_ignore_io(self.add(path));
+ match self.build() {
+ Ok(gi) => (gi, errs.into_error_option()),
+ Err(err) => {
+ errs.push(err);
+ (Gitignore::empty(), errs.into_error_option())
+ }
+ }
+ }
+ }
+ }
+ }
+
/// Add each glob from the file path given.
///
/// The file given should be formatted as a `gitignore` file.
@@ -505,12 +526,16 @@ impl GitignoreBuilder {
/// Toggle whether the globs should be matched case insensitively or not.
///
- /// When this option is changed, only globs added after the change will be affected.
+ /// When this option is changed, only globs added after the change will be
+ /// affected.
///
/// This is disabled by default.
pub fn case_insensitive(
- &mut self, yes: bool
+ &mut self,
+ yes: bool,
) -> Result<&mut GitignoreBuilder, Error> {
+ // TODO: This should not return a `Result`. Fix this in the next semver
+ // release.
self.case_insensitive = yes;
Ok(self)
}
diff --git a/ignore/src/overrides.rs b/ignore/src/overrides.rs
index c63532af..08dbdac2 100644
--- a/ignore/src/overrides.rs
+++ b/ignore/src/overrides.rs
@@ -139,13 +139,16 @@ impl OverrideBuilder {
}
/// Toggle whether the globs should be matched case insensitively or not.
- ///
+ ///
/// When this option is changed, only globs added after the change will be affected.
///
/// This is disabled by default.
pub fn case_insensitive(
- &mut self, yes: bool
+ &mut self,
+ yes: bool,
) -> Result<&mut OverrideBuilder, Error> {
+ // TODO: This should not return a `Result`. Fix this in the next semver
+ // release.
self.builder.case_insensitive(yes)?;
Ok(self)
}
diff --git a/ignore/src/walk.rs b/ignore/src/walk.rs
index aee7a881..ae1f58ba 100644
--- a/ignore/src/walk.rs
+++ b/ignore/src/walk.rs
@@ -764,6 +764,14 @@ impl WalkBuilder {
self
}
+ /// Process ignore files case insensitively
+ ///
+ /// This is disabled by default.
+ pub fn ignore_case_insensitive(&mut self, yes: bool) -> &mut WalkBuilder {
+ self.ig_builder.ignore_case_insensitive(yes);
+ self
+ }
+
/// Set a function for sorting directory entries by their path.
///
/// If a compare function is set, the resulting iterator will return all