From 71ad9bf393a3d89f8c6395d963d9329f1a271d81 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Sat, 24 Sep 2016 19:44:06 -0400 Subject: [PATCH] Fix trailing recursive globs in gitignore. A standard glob of `foo/**` will match `foo`, but gitignore semantics specify that `foo/**` should only match the contents of `foo` and not `foo` itself. We capture those semantics by translating `foo/**` to `foo/**/*`. Fixes #30. --- src/gitignore.rs | 7 +++++++ src/glob.rs | 11 +---------- tests/tests.rs | 11 +++++++++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/gitignore.rs b/src/gitignore.rs index d5aa9177..93d25a4d 100644 --- a/src/gitignore.rs +++ b/src/gitignore.rs @@ -339,6 +339,12 @@ impl GitignoreBuilder { pat.pat = format!("**/{}", pat.pat); } } + // If the pattern ends with `/**`, then we should only match everything + // inside a directory, but not the directory itself. Standard globs + // will match the directory. So we add `/*` to force the issue. + if pat.pat.ends_with("/**") { + pat.pat = format!("{}/*", pat.pat); + } try!(self.builder.add_with(&pat.pat, &opts)); self.patterns.push(pat); Ok(()) @@ -419,4 +425,5 @@ mod tests { not_ignored!(ignot10, ROOT, "**/foo/bar", "foo/src/bar"); not_ignored!(ignot11, ROOT, "#foo", "#foo"); not_ignored!(ignot12, ROOT, "\n\n\n", "foo"); + not_ignored!(ignot13, ROOT, "foo/**", "foo", true); } diff --git a/src/glob.rs b/src/glob.rs index bb033d69..770e9b0d 100644 --- a/src/glob.rs +++ b/src/glob.rs @@ -934,16 +934,6 @@ mod tests { baseliteral!(lit6, "[ab]", false); baseliteral!(lit7, "?", false); - /* - issuffix!(suf1, "", false); - issuffix!(suf2, "a", true); - issuffix!(suf3, "ab", true); - issuffix!(suf4, "*ab", true); - issuffix!(suf5, "*.ab", true); - issuffix!(suf6, "?.ab", true); - issuffix!(suf7, "ab*", false); - */ - matches!(match1, "a", "a"); matches!(match2, "a*b", "a_b"); matches!(match3, "a*b*c", "abc"); @@ -975,6 +965,7 @@ mod tests { matches!(matchrec20, "**/.*", "abc/.abc"); matches!(matchrec21, ".*/**", ".abc"); matches!(matchrec22, ".*/**", ".abc/abc"); + matches!(matchnot23, "foo/**", "foo"); matches!(matchrange1, "a[0-9]b", "a0b"); matches!(matchrange2, "a[0-9]b", "a9b"); diff --git a/tests/tests.rs b/tests/tests.rs index 4ffda0d6..5d4c41a9 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -625,6 +625,17 @@ clean!(regression_25, "test", ".", |wd: WorkDir, mut cmd: Command| { assert_eq!(lines, expected); }); +// See: https://github.com/BurntSushi/ripgrep/issues/30 +clean!(regression_30, "test", ".", |wd: WorkDir, mut cmd: Command| { + wd.create(".gitignore", "vendor/**\n!vendor/manifest"); + wd.create_dir("vendor"); + wd.create("vendor/manifest", "test"); + + let lines: String = wd.stdout(&mut cmd); + let expected = "vendor/manifest:test\n"; + assert_eq!(lines, expected); +}); + // See: https://github.com/BurntSushi/ripgrep/issues/49 clean!(regression_49, "xyz", ".", |wd: WorkDir, mut cmd: Command| { wd.create(".gitignore", "foo/bar");