From cad1f5fae2e4b48d8942add9dc4c950a170b5d2e Mon Sep 17 00:00:00 2001 From: Thilo Uttendorfer Date: Mon, 29 Aug 2022 22:32:29 +0200 Subject: [PATCH] ignore: fix filtering when searching subdirectories When searching subdirectories the path was not correctly built and included duplicate parts. This fix will remove the duplicate part if possible. Fixes #1757, Closes #2295 --- CHANGELOG.md | 2 ++ crates/ignore/src/dir.rs | 24 +++++++++++++++++++++++- tests/regression.rs | 13 +++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63c04ea60..05a2a781e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ Feature enhancements: Bug fixes: +* [BUG #1757](https://github.com/BurntSushi/ripgrep/issues/1757): + Fix bug when searching a sub-directory didn't have ignores applied correctly. * [BUG #1891](https://github.com/BurntSushi/ripgrep/issues/1891): Fix bug when using `-w` with a regex that can match the empty string. * [BUG #1911](https://github.com/BurntSushi/ripgrep/issues/1911): diff --git a/crates/ignore/src/dir.rs b/crates/ignore/src/dir.rs index 2577665d5..c813eb0d5 100644 --- a/crates/ignore/src/dir.rs +++ b/crates/ignore/src/dir.rs @@ -442,7 +442,29 @@ impl Ignore { } if self.0.opts.parents { if let Some(abs_parent_path) = self.absolute_base() { - let path = abs_parent_path.join(path); + // What we want to do here is take the absolute base path of + // this directory and join it with the path we're searching. + // The main issue we want to avoid is accidentally duplicating + // directory components, so we try to strip any common prefix + // off of `path`. Overall, this seems a little ham-fisted, but + // it does fix a nasty bug. It should do fine until we overhaul + // this crate. + let dirpath = self.0.dir.as_path(); + let path_prefix = match strip_prefix("./", dirpath) { + None => dirpath, + Some(stripped_dot_slash) => stripped_dot_slash, + }; + let path = match strip_prefix(path_prefix, path) { + None => abs_parent_path.join(path), + Some(p) => { + let p = match strip_prefix("/", p) { + None => p, + Some(p) => p, + }; + abs_parent_path.join(p) + } + }; + for ig in self.parents().skip_while(|ig| !ig.0.is_absolute_parent) { diff --git a/tests/regression.rs b/tests/regression.rs index 5ef741cf6..91c374497 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -952,6 +952,19 @@ rgtest!(r1739_replacement_lineterm_match, |dir: Dir, mut cmd: TestCommand| { eqnice!("af\n", cmd.stdout()); }); +// See: https://github.com/BurntSushi/ripgrep/issues/1757 +rgtest!(f1757, |dir: Dir, _: TestCommand| { + dir.create_dir("rust/target"); + dir.create(".ignore", "rust/target"); + dir.create("rust/source.rs", "needle"); + dir.create("rust/target/rustdoc-output.html", "needle"); + + let args = &["--files-with-matches", "needle", "rust"]; + eqnice!("rust/source.rs\n", dir.command().args(args).stdout()); + let args = &["--files-with-matches", "needle", "./rust"]; + eqnice!("./rust/source.rs\n", dir.command().args(args).stdout()); +}); + // See: https://github.com/BurntSushi/ripgrep/issues/1765 rgtest!(r1765, |dir: Dir, mut cmd: TestCommand| { dir.create("test", "\n");