summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2018-02-14 18:15:17 -0500
committerAndrew Gallant <jamslam@gmail.com>2018-02-14 18:16:38 -0500
commit361698b90a6b31feac78ac2f16082342f750a1e1 (patch)
tree7320fd387f2f1d8fb3e3a342e54770e820199229
parentb71a110ccf1c9cfe5f4c447cc3878a2e45ed7b8f (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.rs19
-rw-r--r--tests/tests.rs13
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 =