mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-08-04 21:52:54 +02:00
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 #829, Fixes #2731, Fixes #2747, Fixes #2778, Fixes #2836, Fixes #2933 Closes #2933
This commit is contained in:
committed by
Andrew Gallant
parent
78803979c5
commit
c2f1653ddd
10
CHANGELOG.md
10
CHANGELOG.md
@ -2,6 +2,16 @@ TBD
|
|||||||
===
|
===
|
||||||
Unreleased changes. Release notes have not yet been written.
|
Unreleased changes. Release notes have not yet been written.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* [BUG #829](https://github.com/BurntSushi/ripgrep/issues/829),
|
||||||
|
[BUG #2731](https://github.com/BurntSushi/ripgrep/issues/2731),
|
||||||
|
[BUG #2747](https://github.com/BurntSushi/ripgrep/issues/2747),
|
||||||
|
[BUG #2778](https://github.com/BurntSushi/ripgrep/issues/2778),
|
||||||
|
[BUG #2836](https://github.com/BurntSushi/ripgrep/issues/2836),
|
||||||
|
[BUG #2933](https://github.com/BurntSushi/ripgrep/pull/2933):
|
||||||
|
Fix bug related to gitignores from parent directories.
|
||||||
|
|
||||||
Feature enhancements:
|
Feature enhancements:
|
||||||
|
|
||||||
* [FEATURE #2708](https://github.com/BurntSushi/ripgrep/pull/2708):
|
* [FEATURE #2708](https://github.com/BurntSushi/ripgrep/pull/2708):
|
||||||
|
@ -461,21 +461,23 @@ impl Ignore {
|
|||||||
// off of `path`. Overall, this seems a little ham-fisted, but
|
// off of `path`. Overall, this seems a little ham-fisted, but
|
||||||
// it does fix a nasty bug. It should do fine until we overhaul
|
// it does fix a nasty bug. It should do fine until we overhaul
|
||||||
// this crate.
|
// this crate.
|
||||||
let dirpath = self.0.dir.as_path();
|
let path = abs_parent_path.join(
|
||||||
let path_prefix = match strip_prefix("./", dirpath) {
|
self.parents()
|
||||||
None => dirpath,
|
.take_while(|ig| !ig.0.is_absolute_parent)
|
||||||
Some(stripped_dot_slash) => stripped_dot_slash,
|
.last()
|
||||||
};
|
.map_or(path, |ig| {
|
||||||
let path = match strip_prefix(path_prefix, path) {
|
strip_if_is_prefix(
|
||||||
None => abs_parent_path.join(path),
|
"/",
|
||||||
Some(p) => {
|
strip_if_is_prefix(
|
||||||
let p = match strip_prefix("/", p) {
|
strip_if_is_prefix(
|
||||||
None => p,
|
"./",
|
||||||
Some(p) => p,
|
ig.0.dir.as_path(),
|
||||||
};
|
),
|
||||||
abs_parent_path.join(p)
|
path,
|
||||||
}
|
),
|
||||||
};
|
)
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
for ig in
|
for ig in
|
||||||
self.parents().skip_while(|ig| !ig.0.is_absolute_parent)
|
self.parents().skip_while(|ig| !ig.0.is_absolute_parent)
|
||||||
@ -874,6 +876,15 @@ fn resolve_git_commondir(
|
|||||||
Ok(commondir_abs)
|
Ok(commondir_abs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Strips `prefix` from `path` if it's a prefix, otherwise returns `path`
|
||||||
|
/// unchanged.
|
||||||
|
fn strip_if_is_prefix<'a, P: AsRef<Path> + ?Sized>(
|
||||||
|
prefix: &'a P,
|
||||||
|
path: &'a Path,
|
||||||
|
) -> &'a Path {
|
||||||
|
strip_prefix(prefix, path).map_or(path, |p| p)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::{io::Write, path::Path};
|
use std::{io::Write, path::Path};
|
||||||
|
@ -569,6 +569,139 @@ rgtest!(r807, |dir: Dir, mut cmd: TestCommand| {
|
|||||||
eqnice!(".a/c/file:test\n", cmd.arg("--hidden").arg("test").stdout());
|
eqnice!(".a/c/file:test\n", cmd.arg("--hidden").arg("test").stdout());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/829
|
||||||
|
rgtest!(r829_original, |dir: Dir, _cmd: TestCommand| {
|
||||||
|
dir.create_dir("a/b");
|
||||||
|
dir.create(".ignore", "/a/b");
|
||||||
|
dir.create("a/b/test.txt", "Sample text");
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
cmd.args(&["Sample"]).assert_err();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
cmd.args(&["Sample", "a"]).assert_err();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
cmd.current_dir(dir.path().join("a"));
|
||||||
|
cmd.args(&["Sample"]).assert_err();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/2731
|
||||||
|
rgtest!(r829_2731, |dir: Dir, _cmd: TestCommand| {
|
||||||
|
dir.create_dir("some_dir/build");
|
||||||
|
dir.create("some_dir/build/foo", "string");
|
||||||
|
dir.create(".ignore", "build/\n!/some_dir/build/");
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
eqnice!("some_dir/build/foo\n", cmd.arg("-l").arg("string").stdout());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
eqnice!(
|
||||||
|
"some_dir/build/foo\n",
|
||||||
|
cmd.arg("-l").arg("string").arg("some_dir").stdout()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
eqnice!(
|
||||||
|
"./some_dir/build/foo\n",
|
||||||
|
cmd.arg("-l").arg("string").arg("./some_dir").stdout()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
eqnice!(
|
||||||
|
"some_dir/build/foo\n",
|
||||||
|
cmd.arg("-l").arg("string").arg("some_dir/build").stdout()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
eqnice!(
|
||||||
|
"./some_dir/build/foo\n",
|
||||||
|
cmd.arg("-l").arg("string").arg("./some_dir/build").stdout()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/2747
|
||||||
|
rgtest!(r829_2747, |dir: Dir, _cmd: TestCommand| {
|
||||||
|
dir.create_dir("a/c/b");
|
||||||
|
dir.create_dir("a/src/f/b");
|
||||||
|
dir.create("a/c/b/foo", "");
|
||||||
|
dir.create("a/src/f/b/foo", "");
|
||||||
|
dir.create(".ignore", "/a/*/b");
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
eqnice!("a/src/f/b/foo\n", cmd.arg("--files").stdout());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
eqnice!("a/src/f/b/foo\n", cmd.arg("--files").arg("a/src").stdout());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
cmd.current_dir(dir.path().join("a/src"));
|
||||||
|
eqnice!("f/b/foo\n", cmd.arg("--files").stdout());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/2778
|
||||||
|
rgtest!(r829_2778, |dir: Dir, _cmd: TestCommand| {
|
||||||
|
dir.create_dir("parent/subdir");
|
||||||
|
dir.create(".ignore", "/parent/*.txt");
|
||||||
|
dir.create("parent/ignore-me.txt", "");
|
||||||
|
dir.create("parent/subdir/dont-ignore-me.txt", "");
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
eqnice!(
|
||||||
|
"parent/subdir/dont-ignore-me.txt\n",
|
||||||
|
cmd.arg("--files").stdout()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
cmd.current_dir(dir.path().join("parent"));
|
||||||
|
eqnice!("subdir/dont-ignore-me.txt\n", cmd.arg("--files").stdout());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/2836
|
||||||
|
rgtest!(r829_2836, |dir: Dir, _cmd: TestCommand| {
|
||||||
|
dir.create_dir("testdir/sub/sub2");
|
||||||
|
dir.create(".ignore", "/testdir/sub/sub2/\n");
|
||||||
|
dir.create("testdir/sub/sub2/foo", "");
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
cmd.arg("--files").assert_err();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut cmd = dir.command();
|
||||||
|
cmd.current_dir(dir.path().join("testdir"));
|
||||||
|
cmd.arg("--files").assert_err();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/pull/2933
|
||||||
|
rgtest!(r829_2933, |dir: Dir, mut cmd: TestCommand| {
|
||||||
|
dir.create_dir("testdir/sub/sub2");
|
||||||
|
dir.create(".ignore", "/testdir/sub/sub2/");
|
||||||
|
dir.create("testdir/sub/sub2/testfile", "needle");
|
||||||
|
|
||||||
|
let args = &["--files-with-matches", "needle"];
|
||||||
|
cmd.current_dir(dir.path().join("testdir"));
|
||||||
|
cmd.args(args).assert_err();
|
||||||
|
});
|
||||||
|
|
||||||
// See: https://github.com/BurntSushi/ripgrep/issues/900
|
// See: https://github.com/BurntSushi/ripgrep/issues/900
|
||||||
rgtest!(r900, |dir: Dir, mut cmd: TestCommand| {
|
rgtest!(r900, |dir: Dir, mut cmd: TestCommand| {
|
||||||
dir.create("sherlock", SHERLOCK);
|
dir.create("sherlock", SHERLOCK);
|
||||||
@ -965,6 +1098,15 @@ rgtest!(f1757, |dir: Dir, _: TestCommand| {
|
|||||||
eqnice!("rust/source.rs\n", dir.command().args(args).stdout());
|
eqnice!("rust/source.rs\n", dir.command().args(args).stdout());
|
||||||
let args = &["--files-with-matches", "needle", "./rust"];
|
let args = &["--files-with-matches", "needle", "./rust"];
|
||||||
eqnice!("./rust/source.rs\n", dir.command().args(args).stdout());
|
eqnice!("./rust/source.rs\n", dir.command().args(args).stdout());
|
||||||
|
|
||||||
|
dir.create_dir("rust1/target/onemore");
|
||||||
|
dir.create(".ignore", "rust1/target/onemore");
|
||||||
|
dir.create("rust1/source.rs", "needle");
|
||||||
|
dir.create("rust1/target/onemore/rustdoc-output.html", "needle");
|
||||||
|
let args = &["--files-with-matches", "needle", "rust1"];
|
||||||
|
eqnice!("rust1/source.rs\n", dir.command().args(args).stdout());
|
||||||
|
let args = &["--files-with-matches", "needle", "./rust1"];
|
||||||
|
eqnice!("./rust1/source.rs\n", dir.command().args(args).stdout());
|
||||||
});
|
});
|
||||||
|
|
||||||
// See: https://github.com/BurntSushi/ripgrep/issues/1765
|
// See: https://github.com/BurntSushi/ripgrep/issues/1765
|
||||||
|
Reference in New Issue
Block a user