From b941c10b9005edbb520cdd38fdb94ace2969fb57 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Sat, 24 Sep 2016 20:10:26 -0400 Subject: [PATCH] Fix directory whitelisting. There was a bug in the translation from a gitignore pattern to a standard glob where `!/dir` wasn't being interpreted as an absolute path. Fixes #67. --- src/gitignore.rs | 23 ++++++----------------- tests/tests.rs | 12 ++++++++++++ 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/gitignore.rs b/src/gitignore.rs index 93d25a4d..3341e6db 100644 --- a/src/gitignore.rs +++ b/src/gitignore.rs @@ -276,7 +276,7 @@ impl GitignoreBuilder { from: P, mut line: &str, ) -> Result<(), Error> { - if line.is_empty() { + if line.is_empty() || line.starts_with("#") { return Ok(()); } let mut pat = Pattern { @@ -289,24 +289,14 @@ impl GitignoreBuilder { let mut opts = glob::MatchOptions::default(); let has_slash = line.chars().any(|c| c == '/'); let is_absolute = line.chars().nth(0).unwrap() == '/'; - // If the line starts with an escaped '!', then remove the escape. - // Otherwise, if it starts with an unescaped '!', then this is a - // whitelist pattern. - match line.chars().nth(0) { - Some('#') => return Ok(()), - Some('\\') => { - match line.chars().nth(1) { - Some('!') | Some('#') => { - line = &line[1..]; - } - _ => {} - } - } - Some('!') => { + if line.starts_with("\\!") || line.starts_with("\\#") { + line = &line[1..]; + } else { + if line.starts_with("!") { pat.whitelist = true; line = &line[1..]; } - Some('/') => { + if line.starts_with("/") { // `man gitignore` says that if a glob starts with a slash, // then the glob can only match the beginning of a path // (relative to the location of gitignore). We achieve this by @@ -314,7 +304,6 @@ impl GitignoreBuilder { opts.require_literal_separator = true; line = &line[1..]; } - _ => {} } // If it ends with a slash, then this should only match directories, // but the slash should otherwise not be used while globbing. diff --git a/tests/tests.rs b/tests/tests.rs index 5d4c41a9..3f8c3aa8 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -663,6 +663,18 @@ clean!(regression_65, "xyz", ".", |wd: WorkDir, mut cmd: Command| { wd.assert_err(&mut cmd); }); +// See: https://github.com/BurntSushi/ripgrep/issues/67 +clean!(regression_67, "test", ".", |wd: WorkDir, mut cmd: Command| { + wd.create(".gitignore", "/*\n!/dir"); + wd.create_dir("dir"); + wd.create_dir("foo"); + wd.create("foo/bar", "test"); + wd.create("dir/bar", "test"); + + let lines: String = wd.stdout(&mut cmd); + assert_eq!(lines, "dir/bar:test\n"); +}); + // See: https://github.com/BurntSushi/ripgrep/issues/20 sherlock!(feature_20, "Sherlock", ".", |wd: WorkDir, mut cmd: Command| { cmd.arg("--no-filename");