Skip to content

Commit 76df916

Browse files
ignore: fix filtering searching subdir or .ignore in parent dir
The previous code deleted too many parts of the path when constructing the absolute path, resulting in a shortened final path. This patch creates the correct absolute path by only removing the necessary parts. Fixes #2836
1 parent 79cbe89 commit 76df916

File tree

2 files changed

+44
-15
lines changed

2 files changed

+44
-15
lines changed

crates/ignore/src/dir.rs

+25-15
Original file line numberDiff line numberDiff line change
@@ -461,21 +461,31 @@ impl Ignore {
461461
// off of `path`. Overall, this seems a little ham-fisted, but
462462
// it does fix a nasty bug. It should do fine until we overhaul
463463
// this crate.
464-
let dirpath = self.0.dir.as_path();
465-
let path_prefix = match strip_prefix("./", dirpath) {
466-
None => dirpath,
467-
Some(stripped_dot_slash) => stripped_dot_slash,
468-
};
469-
let path = match strip_prefix(path_prefix, path) {
470-
None => abs_parent_path.join(path),
471-
Some(p) => {
472-
let p = match strip_prefix("/", p) {
473-
None => p,
474-
Some(p) => p,
475-
};
476-
abs_parent_path.join(p)
477-
}
478-
};
464+
465+
fn strip_if_is_prefix<'a, P: AsRef<Path> + ?Sized>(
466+
prefix: &'a P,
467+
path: &'a Path,
468+
) -> &'a Path {
469+
strip_prefix(prefix, path).map_or(path, |p| p)
470+
}
471+
472+
let path = abs_parent_path.join(
473+
self.parents()
474+
.take_while(|ig| !ig.0.is_absolute_parent)
475+
.last()
476+
.map_or(path, |ig| {
477+
strip_if_is_prefix(
478+
"/",
479+
strip_if_is_prefix(
480+
strip_if_is_prefix(
481+
"./",
482+
ig.0.dir.as_path(),
483+
),
484+
path,
485+
),
486+
)
487+
}),
488+
);
479489

480490
for ig in
481491
self.parents().skip_while(|ig| !ig.0.is_absolute_parent)

tests/regression.rs

+19
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,15 @@ rgtest!(f1757, |dir: Dir, _: TestCommand| {
965965
eqnice!("rust/source.rs\n", dir.command().args(args).stdout());
966966
let args = &["--files-with-matches", "needle", "./rust"];
967967
eqnice!("./rust/source.rs\n", dir.command().args(args).stdout());
968+
969+
dir.create_dir("rust1/target/onemore");
970+
dir.create(".ignore", "rust1/target/onemore");
971+
dir.create("rust1/source.rs", "needle");
972+
dir.create("rust1/target/onemore/rustdoc-output.html", "needle");
973+
let args = &["--files-with-matches", "needle", "rust1"];
974+
eqnice!("rust1/source.rs\n", dir.command().args(args).stdout());
975+
let args = &["--files-with-matches", "needle", "./rust1"];
976+
eqnice!("./rust1/source.rs\n", dir.command().args(args).stdout());
968977
});
969978

970979
// See: https://github.com/BurntSushi/ripgrep/issues/1765
@@ -1217,3 +1226,13 @@ rgtest!(r2658_null_data_line_regexp, |dir: Dir, mut cmd: TestCommand| {
12171226
let got = cmd.args(&["--null-data", "--line-regexp", r"bar"]).stdout();
12181227
eqnice!("haystack:bar\0", got);
12191228
});
1229+
1230+
rgtest!(f2836, |dir: Dir, mut cmd: TestCommand| {
1231+
dir.create_dir("testdir/sub/sub2");
1232+
dir.create(".ignore", "/testdir/sub/sub2/");
1233+
dir.create("testdir/sub/sub2/testfile", "needle");
1234+
1235+
let args = &["--files-with-matches", "needle"];
1236+
cmd.current_dir(dir.path().join("testdir"));
1237+
cmd.args(args).assert_err();
1238+
});

0 commit comments

Comments
 (0)