diff options
author | Andrew Gallant <jamslam@gmail.com> | 2018-02-14 18:15:17 -0500 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2018-02-14 18:16:38 -0500 |
commit | 361698b90a6b31feac78ac2f16082342f750a1e1 (patch) | |
tree | 7320fd387f2f1d8fb3e3a342e54770e820199229 | |
parent | b71a110ccf1c9cfe5f4c447cc3878a2e45ed7b8f (diff) |
ignore: fix improper hidden filtering
This commit fixes a bug where `rg --hidden .` would behave differently
with respect to ignore filtering than `rg --hidden ./`. In particular,
this was due to a bug where the directory name `.` caused the leading
`.` in a hidden directory to get stripped, which in turn caused the
ignore rules to fail.
Fixes #807
-rw-r--r-- | ignore/src/gitignore.rs | 19 | ||||
-rw-r--r-- | tests/tests.rs | 13 |
2 files changed, 30 insertions, 2 deletions
diff --git a/ignore/src/gitignore.rs b/ignore/src/gitignore.rs index a21afa55..7e7233d6 100644 --- a/ignore/src/gitignore.rs +++ b/ignore/src/gitignore.rs @@ -66,6 +66,12 @@ impl Glob { pub fn is_only_dir(&self) -> bool { self.is_only_dir } + + /// Returns true if and only if this glob has a `**/` prefix. + fn has_doublestar_prefix(&self) -> bool { + self.actual.starts_with("**/") + || (self.actual == "**" && self.is_only_dir) + } } /// Gitignore is a matcher for the globs in one or more gitignore files @@ -278,7 +284,10 @@ impl Gitignore { // BUT, a file name might not have any directory components to it, // in which case, we don't want to accidentally strip any part of the // file name. - if !is_file_name(path) { + // + // As an additional special case, if the root is just `.`, then we + // shouldn't try to strip anything, e.g., when path begins with a `.`. + if self.root != Path::new(".") && !is_file_name(path) { if let Some(p) = strip_prefix(&self.root, path) { path = p; // If we're left with a leading slash, get rid of it. @@ -454,7 +463,7 @@ impl GitignoreBuilder { // prefix. if !literal_separator { // ... but only if we don't already have a **/ prefix. - if !(glob.actual.starts_with("**/") || (glob.actual == "**" && glob.is_only_dir)) { + if !glob.has_doublestar_prefix() { glob.actual = format!("**/{}", glob.actual); } } @@ -620,6 +629,12 @@ mod tests { ignored!(ig29, ROOT, "node_modules/ ", "node_modules", true); ignored!(ig30, ROOT, "**/", "foo/bar", true); ignored!(ig31, ROOT, "path1/*", "path1/foo"); + ignored!(ig32, ROOT, ".a/b", ".a/b"); + ignored!(ig33, "./", ".a/b", ".a/b"); + ignored!(ig34, ".", ".a/b", ".a/b"); + ignored!(ig35, "./.", ".a/b", ".a/b"); + ignored!(ig36, "././", ".a/b", ".a/b"); + ignored!(ig37, "././.", ".a/b", ".a/b"); not_ignored!(ignot1, ROOT, "amonths", "months"); not_ignored!(ignot2, ROOT, "monthsa", "months"); diff --git a/tests/tests.rs b/tests/tests.rs index e88756dc..0e144d19 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1232,6 +1232,19 @@ clean!(regression_599, "^$", "input.txt", |wd: WorkDir, mut cmd: Command| { assert_eq!(expected, lines); }); +// See: https://github.com/BurntSushi/ripgrep/issues/807 +clean!(regression_807, "test", ".", |wd: WorkDir, mut cmd: Command| { + wd.create(".gitignore", ".a/b"); + wd.create_dir(".a/b"); + wd.create_dir(".a/c"); + wd.create(".a/b/file", "test"); + wd.create(".a/c/file", "test"); + + cmd.arg("--hidden"); + let lines: String = wd.stdout(&mut cmd); + assert_eq!(lines, format!("{}:test\n", path(".a/c/file"))); +}); + // See: https://github.com/BurntSushi/ripgrep/issues/1 clean!(feature_1_sjis, "Шерлок Холмс", ".", |wd: WorkDir, mut cmd: Command| { let sherlock = |