diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java index 92a4837b2..f9c239431 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java @@ -307,7 +307,11 @@ public class FileNameMatcher { return new WildCardHead(star); } - private void extendStringToMatchByOneCharacter(final char c) { + /** + * @param c new character to append + * @return true to continue, false if the matcher can stop appending + */ + private boolean extendStringToMatchByOneCharacter(final char c) { final List newHeads = listForLocalUseage; newHeads.clear(); List lastAddedHeads = null; @@ -320,12 +324,14 @@ public class FileNameMatcher { // This is the case with the heads "a" and "*" of "a*b" which // both can return the list ["*","b"] if (headsToAdd != lastAddedHeads) { - newHeads.addAll(headsToAdd); + if (!headsToAdd.isEmpty()) + newHeads.addAll(headsToAdd); lastAddedHeads = headsToAdd; } } listForLocalUseage = heads; heads = newHeads; + return !newHeads.isEmpty(); } private static int indexOfUnescaped(final String searchString, @@ -349,7 +355,8 @@ public class FileNameMatcher { public void append(final String stringToMatch) { for (int i = 0; i < stringToMatch.length(); i++) { final char c = stringToMatch.charAt(i); - extendStringToMatchByOneCharacter(c); + if (!extendStringToMatchByOneCharacter(c)) + break; } } @@ -378,6 +385,9 @@ public class FileNameMatcher { * @return true, if the string currently being matched does match. */ public boolean isMatch() { + if (heads.isEmpty()) + return false; + final ListIterator headIterator = heads .listIterator(heads.size()); while (headIterator.hasPrevious()) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java index fd095d76d..42bbd9e9b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java @@ -191,6 +191,9 @@ public class IgnoreRule { final String[] segments = target.split("/"); //$NON-NLS-1$ for (int idx = 0; idx < segments.length; idx++) { final String segmentName = segments[idx]; + // String.split("/") creates empty segment for leading slash + if (segmentName.length() == 0) + continue; if (segmentName.equals(pattern) && doesMatchDirectoryExpectations(isDirectory, idx, segments.length)) return true; @@ -207,6 +210,9 @@ public class IgnoreRule { if (nameOnly) { for (int idx = 0; idx < segments.length; idx++) { final String segmentName = segments[idx]; + // String.split("/") creates empty segment for leading slash + if (segmentName.length() == 0) + continue; //Iterate through each sub-directory matcher.reset(); matcher.append(segmentName); @@ -218,14 +224,18 @@ public class IgnoreRule { //TODO: This is the slowest operation //This matches e.g. "/src/ne?" to "/src/new/file.c" matcher.reset(); + for (int idx = 0; idx < segments.length; idx++) { final String segmentName = segments[idx]; - if (segmentName.length() > 0) { - matcher.append("/" + segmentName); //$NON-NLS-1$ - } + // String.split("/") creates empty segment for leading slash + if (segmentName.length() == 0) + continue; - if (matcher.isMatch() && - doesMatchDirectoryExpectations(isDirectory, idx, segments.length)) + matcher.append("/" + segmentName); //$NON-NLS-1$ + + if (matcher.isMatch() + && doesMatchDirectoryExpectations(isDirectory, idx, + segments.length)) return true; } }