diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeTest.java index ec2370e67..f0d3c3690 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeTest.java @@ -166,6 +166,25 @@ public class AttributesNodeTest { assertAttribute("file.type3", node, asSet(A_UNSET_ATTR, B_SET_ATTR)); } + @Test + public void testDoubleAsteriskAtEnd() throws IOException { + String attributeFileContent = "dir/** \tA -B\tC=value"; + + is = new ByteArrayInputStream(attributeFileContent.getBytes()); + AttributesNode node = new AttributesNode(); + node.parse(is); + assertAttribute("dir", node, + asSet(new Attribute[]{})); + assertAttribute("dir/", node, + asSet(new Attribute[]{})); + assertAttribute("dir/file.type1", node, + asSet(A_SET_ATTR, B_UNSET_ATTR, C_VALUE_ATTR)); + assertAttribute("dir/sub/", node, + asSet(A_SET_ATTR, B_UNSET_ATTR, C_VALUE_ATTR)); + assertAttribute("dir/sub/file.type1", node, + asSet(A_SET_ATTR, B_UNSET_ATTR, C_VALUE_ATTR)); + } + private void assertAttribute(String path, AttributesNode node, Attributes attrs) throws IOException { Attributes attributes = new Attributes(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/FastIgnoreRuleTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/FastIgnoreRuleTest.java index 1863b8032..bcc8f7e47 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/FastIgnoreRuleTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/FastIgnoreRuleTest.java @@ -391,7 +391,6 @@ public class FastIgnoreRuleTest { assertMatched("/**/a/b", "c/d/a/b"); assertMatched("/**/**/a/b", "c/d/a/b"); - assertMatched("a/b/**", "a/b"); assertMatched("a/b/**", "a/b/c"); assertMatched("a/b/**", "a/b/c/d/"); assertMatched("a/b/**/**", "a/b/c/d"); @@ -415,6 +414,12 @@ public class FastIgnoreRuleTest { @Test public void testWildmatchDoNotMatch() { + assertNotMatched("a/**", "a/"); + assertNotMatched("a/b/**", "a/b/"); + assertNotMatched("a/**", "a"); + assertNotMatched("a/b/**", "a/b"); + assertNotMatched("a/b/**/", "a/b"); + assertNotMatched("a/b/**/**", "a/b"); assertNotMatched("**/a/b", "a/c/b"); assertNotMatched("!/**/*.zip", "c/a/b.zip"); assertNotMatched("!**/*.zip", "c/a/b.zip"); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java index 65224eab9..ce9ad80fb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java @@ -227,29 +227,30 @@ public class PathMatcher extends AbstractMatcher { int left = right; right = path.indexOf(slash, right); if (right == -1) { - if (left < endExcl) + if (left < endExcl) { match = matches(matcher, path, left, endExcl, assumeDirectory); + } else { + // a/** should not match a/ or a + match = match && matchers.get(matcher) != WILD; + } if (match) { - if (matcher == matchers.size() - 2 - && matchers.get(matcher + 1) == WILD) - // ** can match *nothing*: a/b/** match also a/b - return true; if (matcher < matchers.size() - 1 && matchers.get(matcher) == WILD) { // ** can match *nothing*: a/**/b match also a/b matcher++; match = matches(matcher, path, left, endExcl, assumeDirectory); - } else if (dirOnly && !assumeDirectory) + } else if (dirOnly && !assumeDirectory) { // Directory expectations not met return false; + } } return match && matcher + 1 == matchers.size(); } - if (right - left > 0) + if (right - left > 0) { match = matches(matcher, path, left, right, assumeDirectory); - else { + } else { // path starts with slash??? right++; continue; @@ -261,12 +262,14 @@ public class PathMatcher extends AbstractMatcher { right = left - 1; } matcher++; - if (matcher == matchers.size()) + if (matcher == matchers.size()) { return true; - } else if (lastWildmatch != -1) + } + } else if (lastWildmatch != -1) { matcher = lastWildmatch + 1; - else + } else { return false; + } right++; } }