Skip to content

Commit

Permalink
Make handling of patterns containing a / match actual git behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
okdana committed Jan 27, 2018
1 parent 35f8021 commit ff30708
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 19 deletions.
21 changes: 11 additions & 10 deletions ignore/src/gitignore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,6 @@ impl GitignoreBuilder {
is_only_dir: false,
};
let mut literal_separator = false;
let has_slash = line.chars().any(|c| c == '/');
let mut is_absolute = false;
if line.starts_with("\\!") || line.starts_with("\\#") {
line = &line[1..];
Expand Down Expand Up @@ -447,13 +446,13 @@ impl GitignoreBuilder {
// If there is a literal slash, then we note that so that globbing
// doesn't let wildcards match slashes.
glob.actual = line.to_string();
if has_slash {
if is_absolute || line.chars().any(|c| c == '/') {
literal_separator = true;
}
// If there was a leading slash, then this is a glob that must
// match the entire path name. Otherwise, we should let it match
// anywhere, so use a **/ prefix.
if !is_absolute {
// If there was a slash, then this is a glob that must match the entire
// path name. Otherwise, we should let it match anywhere, so use a **/
// 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)) {
glob.actual = format!("**/{}", glob.actual);
Expand Down Expand Up @@ -617,10 +616,10 @@ mod tests {
ignored!(ig25, ROOT, "Cargo.lock", "./tabwriter-bin/Cargo.lock");
ignored!(ig26, ROOT, "/foo/bar/baz", "./foo/bar/baz");
ignored!(ig27, ROOT, "foo/", "xyz/foo", true);
ignored!(ig28, ROOT, "src/*.rs", "src/grep/src/main.rs");
ignored!(ig29, "./src", "/llvm/", "./src/llvm", true);
ignored!(ig30, ROOT, "node_modules/ ", "node_modules", true);
ignored!(ig31, ROOT, "**/", "foo/bar", true);
ignored!(ig28, "./src", "/llvm/", "./src/llvm", true);
ignored!(ig29, ROOT, "node_modules/ ", "node_modules", true);
ignored!(ig30, ROOT, "**/", "foo/bar", true);
ignored!(ig31, ROOT, "path1/*", "path1/foo");

not_ignored!(ignot1, ROOT, "amonths", "months");
not_ignored!(ignot2, ROOT, "monthsa", "months");
Expand All @@ -640,6 +639,8 @@ mod tests {
"./third_party/protobuf/csharp/src/packages/repositories.config");
not_ignored!(ignot15, ROOT, "!/bar", "foo/bar");
not_ignored!(ignot16, ROOT, "*\n!**/", "foo", true);
not_ignored!(ignot17, ROOT, "src/*.rs", "src/grep/src/main.rs");
not_ignored!(ignot18, ROOT, "path1/*", "path2/path1/foo");

fn bytes(s: &str) -> Vec<u8> {
s.to_string().into_bytes()
Expand Down
3 changes: 2 additions & 1 deletion ignore/src/overrides.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,9 @@ mod tests {
#[test]
fn gitignore() {
let ov = ov(&["/foo", "bar/*.rs", "baz/**"]);
assert!(ov.matched("bar/lib.rs", false).is_whitelist());
assert!(ov.matched("bar/wat/lib.rs", false).is_ignore());
assert!(ov.matched("wat/bar/lib.rs", false).is_whitelist());
assert!(ov.matched("wat/bar/lib.rs", false).is_ignore());
assert!(ov.matched("foo", false).is_whitelist());
assert!(ov.matched("wat/foo", false).is_ignore());
assert!(ov.matched("baz", false).is_ignore());
Expand Down
16 changes: 8 additions & 8 deletions ignore/tests/gitignore_matched_path_or_any_parents_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,16 +212,16 @@ fn test_dirs_in_deep() {
assert!(m("ROOT/parent_dir/dir_deep_01/child_dir/file", false).is_ignore());

// 02
assert!(m("ROOT/parent_dir/dir_deep_02", true).is_none()); // dir itself doesn't match
assert!(m("ROOT/parent_dir/dir_deep_02/file", false).is_ignore());
assert!(m("ROOT/parent_dir/dir_deep_02/child_dir", true).is_ignore());
assert!(m("ROOT/parent_dir/dir_deep_02/child_dir/file", false).is_ignore());
assert!(m("ROOT/parent_dir/dir_deep_02", true).is_none());
assert!(m("ROOT/parent_dir/dir_deep_02/file", false).is_none());
assert!(m("ROOT/parent_dir/dir_deep_02/child_dir", true).is_none());
assert!(m("ROOT/parent_dir/dir_deep_02/child_dir/file", false).is_none());

// 03
assert!(m("ROOT/parent_dir/dir_deep_03", true).is_none()); // dir itself doesn't match
assert!(m("ROOT/parent_dir/dir_deep_03/file", false).is_ignore());
assert!(m("ROOT/parent_dir/dir_deep_03/child_dir", true).is_ignore());
assert!(m("ROOT/parent_dir/dir_deep_03/child_dir/file", false).is_ignore());
assert!(m("ROOT/parent_dir/dir_deep_03", true).is_none());
assert!(m("ROOT/parent_dir/dir_deep_03/file", false).is_none());
assert!(m("ROOT/parent_dir/dir_deep_03/child_dir", true).is_none());
assert!(m("ROOT/parent_dir/dir_deep_03/child_dir/file", false).is_none());

// 10
assert!(m("ROOT/parent_dir/dir_deep_10", true).is_none());
Expand Down

0 comments on commit ff30708

Please sign in to comment.