Bug: 500967 Change-Id: I7fabc2654af97011c62f46d5c30ee992341e45e2 Signed-off-by: Andrey Loskutov <loskutov@gmx.de>tags/v4.5.0.201609210915-r
@@ -47,6 +47,7 @@ import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertNotEquals; | |||
import static org.junit.Assert.assertTrue; | |||
import org.eclipse.jgit.ignore.internal.Strings; | |||
import org.junit.Test; | |||
public class BasicRuleTest { | |||
@@ -73,4 +74,31 @@ public class BasicRuleTest { | |||
assertNotEquals(rule1.toString(), rule3.toString()); | |||
} | |||
@Test | |||
public void testDirectoryPattern() { | |||
assertTrue(Strings.isDirectoryPattern("/")); | |||
assertTrue(Strings.isDirectoryPattern("/ ")); | |||
assertTrue(Strings.isDirectoryPattern("/ ")); | |||
assertFalse(Strings.isDirectoryPattern(" ")); | |||
assertFalse(Strings.isDirectoryPattern("")); | |||
} | |||
@Test | |||
public void testStripTrailingChar() { | |||
assertEquals("", Strings.stripTrailing("/", '/')); | |||
assertEquals("", Strings.stripTrailing("///", '/')); | |||
assertEquals("a", Strings.stripTrailing("a/", '/')); | |||
assertEquals("a", Strings.stripTrailing("a///", '/')); | |||
assertEquals("a/ ", Strings.stripTrailing("a/ ", '/')); | |||
} | |||
@Test | |||
public void testStripTrailingWhitespace() { | |||
assertEquals("", Strings.stripTrailingWhitespace("")); | |||
assertEquals("", Strings.stripTrailingWhitespace(" ")); | |||
assertEquals("a", Strings.stripTrailingWhitespace("a")); | |||
assertEquals("a", Strings.stripTrailingWhitespace("a ")); | |||
assertEquals("a", Strings.stripTrailingWhitespace("a ")); | |||
assertEquals("a", Strings.stripTrailingWhitespace("a \t")); | |||
} | |||
} |
@@ -122,6 +122,17 @@ public class FastIgnoreRuleTest { | |||
assertMatched("/[v-z]/", "/x/b"); | |||
} | |||
@Test | |||
public void testTrailingSpaces() { | |||
assertMatched("a ", "a"); | |||
assertMatched("a/ ", "a/"); | |||
assertMatched("a/ ", "a/b"); | |||
assertMatched("a/\\ ", "a/ "); | |||
assertNotMatched("a/\\ ", "a/"); | |||
assertNotMatched("a/\\ ", "a/b"); | |||
assertNotMatched("/ ", "a"); | |||
} | |||
@Test | |||
public void testAsteriskDot() { | |||
assertMatched("*.a", ".a"); |
@@ -480,8 +480,9 @@ public class IgnoreNodeTest extends RepositoryTestCase { | |||
writeTrashFile("a/a", ""); | |||
writeTrashFile("a/a ", ""); | |||
writeTrashFile("a/a ", ""); | |||
writeTrashFile("b/c", ""); | |||
writeIgnoreFile(".gitignore", "a\\ ", "a \\ "); | |||
writeIgnoreFile(".gitignore", "a\\ ", "a \\ ", "b/ "); | |||
beginWalk(); | |||
assertEntry(F, tracked, ".gitignore"); | |||
@@ -497,6 +498,8 @@ public class IgnoreNodeTest extends RepositoryTestCase { | |||
assertEntry(F, tracked, "a/a"); | |||
assertEntry(F, ignored, "a/a "); | |||
assertEntry(F, ignored, "a/a "); | |||
assertEntry(D, ignored, "b"); | |||
assertEntry(F, ignored, "b/c"); | |||
endWalk(); | |||
} | |||
@@ -43,6 +43,8 @@ | |||
package org.eclipse.jgit.ignore; | |||
import static org.eclipse.jgit.ignore.internal.Strings.stripTrailing; | |||
import static org.eclipse.jgit.ignore.internal.Strings.stripTrailingWhitespace; | |||
import static org.eclipse.jgit.ignore.internal.Strings.isDirectoryPattern; | |||
import static org.eclipse.jgit.ignore.internal.IMatcher.NO_MATCH; | |||
import org.eclipse.jgit.errors.InvalidPatternException; | |||
import org.eclipse.jgit.ignore.internal.IMatcher; | |||
@@ -111,8 +113,9 @@ public class FastIgnoreRule { | |||
pattern = pattern.substring(1); | |||
} | |||
} | |||
dirOnly = pattern.charAt(pattern.length() - 1) == PATH_SEPARATOR; | |||
dirOnly = isDirectoryPattern(pattern); | |||
if (dirOnly) { | |||
pattern = stripTrailingWhitespace(pattern); | |||
pattern = stripTrailing(pattern, PATH_SEPARATOR); | |||
if (pattern.length() == 0) { | |||
this.matcher = NO_MATCH; |
@@ -76,10 +76,50 @@ public class Strings { | |||
* @return new string with all trailing characters removed | |||
*/ | |||
public static String stripTrailing(String pattern, char c) { | |||
while (pattern.length() > 0 | |||
&& pattern.charAt(pattern.length() - 1) == c) | |||
pattern = pattern.substring(0, pattern.length() - 1); | |||
return pattern; | |||
for (int i = pattern.length() - 1; i >= 0; i--) { | |||
char charAt = pattern.charAt(i); | |||
if (charAt != c) { | |||
if (i == pattern.length() - 1) { | |||
return pattern; | |||
} | |||
return pattern.substring(0, i + 1); | |||
} | |||
} | |||
return ""; //$NON-NLS-1$ | |||
} | |||
/** | |||
* @param pattern | |||
* non null | |||
* @return new string with all trailing whitespace removed | |||
*/ | |||
public static String stripTrailingWhitespace(String pattern) { | |||
for (int i = pattern.length() - 1; i >= 0; i--) { | |||
char charAt = pattern.charAt(i); | |||
if (!Character.isWhitespace(charAt)) { | |||
if (i == pattern.length() - 1) { | |||
return pattern; | |||
} | |||
return pattern.substring(0, i + 1); | |||
} | |||
} | |||
return ""; //$NON-NLS-1$ | |||
} | |||
/** | |||
* @param pattern | |||
* non null | |||
* @return true if the last character, which is not whitespace, is a path | |||
* separator | |||
*/ | |||
public static boolean isDirectoryPattern(String pattern) { | |||
for (int i = pattern.length() - 1; i >= 0; i--) { | |||
char charAt = pattern.charAt(i); | |||
if (!Character.isWhitespace(charAt)) { | |||
return charAt == FastIgnoreRule.PATH_SEPARATOR; | |||
} | |||
} | |||
return false; | |||
} | |||
static int count(String s, char c, boolean ignoreFirstLast) { |