From c87ae94c70158ba2bcb310aa242102853d221f11 Mon Sep 17 00:00:00 2001 From: Marc Strapetz Date: Fri, 7 Jan 2011 12:52:42 +0100 Subject: Fix IgnoreRule for directory-only patterns Patterns containing only a trailing slash have to be treated as "global" patterns. For example: "classes/" matches "classes" as well as "dir/classes" directory. --- .../org/eclipse/jgit/ignore/IgnoreMatcherTest.java | 10 ++++++ .../src/org/eclipse/jgit/ignore/IgnoreRule.java | 39 ++++++++++++++++------ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreMatcherTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreMatcherTest.java index ce2508a3e5..7e771dc993 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreMatcherTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreMatcherTest.java @@ -242,11 +242,21 @@ public class IgnoreMatcherTest { //Test matches for name-only, applies to file name or folder name pattern = "src"; + assertMatched(pattern, "/src"); + assertMatched(pattern, "/src/"); assertMatched(pattern, "/src/a.c"); assertMatched(pattern, "/src/new/a.c"); assertMatched(pattern, "/new/src/a.c"); assertMatched(pattern, "/file/src"); + + //Test matches for name-only, applies only to folder names + pattern = "src/"; assertMatched(pattern, "/src/"); + assertMatched(pattern, "/src/a.c"); + assertMatched(pattern, "/src/new/a.c"); + assertMatched(pattern, "/new/src/a.c"); + assertNotMatched(pattern, "/src"); + assertNotMatched(pattern, "/file/src"); //Test matches for name-only, applies to file name or folder name //With a small wildcard 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 b43b1118ad..3c7fdc60d4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java @@ -91,9 +91,9 @@ public class IgnoreRule { endIndex --; dirOnly = true; } - boolean hasSlash = pattern.contains("/"); pattern = pattern.substring(startIndex, endIndex); + boolean hasSlash = pattern.contains("/"); if (!hasSlash) nameOnly = true; @@ -188,8 +188,11 @@ public class IgnoreRule { if (nameOnly) { //Iterate through each sub-name - for (String folderName : target.split("/")) { - if (folderName.equals(pattern)) + final String[] segments = target.split("/"); + for (int idx = 0; idx < segments.length; idx++) { + final String segmentName = segments[idx]; + if (segmentName.equals(pattern) && + doesMatchDirectoryExpectations(isDirectory, idx, segments.length)) return true; } } @@ -199,23 +202,29 @@ public class IgnoreRule { if (matcher.isMatch()) return true; + final String[] segments = target.split("/"); if (nameOnly) { - for (String folderName : target.split("/")) { + for (int idx = 0; idx < segments.length; idx++) { + final String segmentName = segments[idx]; //Iterate through each sub-directory matcher.reset(); - matcher.append(folderName); - if (matcher.isMatch()) + matcher.append(segmentName); + if (matcher.isMatch() && + doesMatchDirectoryExpectations(isDirectory, idx, segments.length)) return true; } } else { //TODO: This is the slowest operation //This matches e.g. "/src/ne?" to "/src/new/file.c" matcher.reset(); - for (String folderName : target.split("/")) { - if (folderName.length() > 0) - matcher.append("/" + folderName); + for (int idx = 0; idx < segments.length; idx++) { + final String segmentName = segments[idx]; + if (segmentName.length() > 0) { + matcher.append("/" + segmentName); + } - if (matcher.isMatch()) + if (matcher.isMatch() && + doesMatchDirectoryExpectations(isDirectory, idx, segments.length)) return true; } } @@ -235,4 +244,14 @@ public class IgnoreRule { public boolean getResult() { return !negation; } + + private boolean doesMatchDirectoryExpectations(boolean isDirectory, int segmentIdx, int segmentLength) { + // The segment we are checking is a directory, expectations are met. + if (segmentIdx < segmentLength - 1) { + return true; + } + + // We are checking the last part of the segment for which isDirectory has to be considered. + return !dirOnly || isDirectory; + } } \ No newline at end of file -- cgit v1.2.3