Browse Source
* changes: Delete deprecated PackWriter.preparePack() methods Delete deprecated class IgnoreRule Delete deprecated checkoutEntry() methods in DirCacheCheckoutstable-4.1
Shawn Pearce
10 years ago
committed by
Gerrit Code Review @ Eclipse.org
8 changed files with 79 additions and 1034 deletions
@ -1,400 +0,0 @@
|
||||
/* |
||||
* Copyright (C) 2010, Red Hat Inc. |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.ignore; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertFalse; |
||||
import static org.junit.Assert.assertTrue; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
|
||||
/** |
||||
* Tests ignore pattern matches |
||||
*/ |
||||
@SuppressWarnings("deprecation") |
||||
public class IgnoreMatcherTest { |
||||
|
||||
@Test |
||||
public void testBasic() { |
||||
String pattern = "/test.stp"; |
||||
assertMatched(pattern, "/test.stp"); |
||||
|
||||
pattern = "#/test.stp"; |
||||
assertNotMatched(pattern, "/test.stp"); |
||||
} |
||||
|
||||
@Test |
||||
public void testFileNameWildcards() { |
||||
//Test basic * and ? for any pattern + any character
|
||||
String pattern = "*.st?"; |
||||
assertMatched(pattern, "/test.stp"); |
||||
assertMatched(pattern, "/anothertest.stg"); |
||||
assertMatched(pattern, "/anothertest.st0"); |
||||
assertNotMatched(pattern, "/anothertest.sta1"); |
||||
//Check that asterisk does not expand to "/"
|
||||
assertNotMatched(pattern, "/another/test.sta1"); |
||||
|
||||
//Same as above, with a leading slash to ensure that doesn't cause problems
|
||||
pattern = "/*.st?"; |
||||
assertMatched(pattern, "/test.stp"); |
||||
assertMatched(pattern, "/anothertest.stg"); |
||||
assertMatched(pattern, "/anothertest.st0"); |
||||
assertNotMatched(pattern, "/anothertest.sta1"); |
||||
//Check that asterisk does not expand to "/"
|
||||
assertNotMatched(pattern, "/another/test.sta1"); |
||||
|
||||
//Test for numbers
|
||||
pattern = "*.sta[0-5]"; |
||||
assertMatched(pattern, "/test.sta5"); |
||||
assertMatched(pattern, "/test.sta4"); |
||||
assertMatched(pattern, "/test.sta3"); |
||||
assertMatched(pattern, "/test.sta2"); |
||||
assertMatched(pattern, "/test.sta1"); |
||||
assertMatched(pattern, "/test.sta0"); |
||||
assertMatched(pattern, "/anothertest.sta2"); |
||||
assertNotMatched(pattern, "test.stag"); |
||||
assertNotMatched(pattern, "test.sta6"); |
||||
|
||||
//Test for letters
|
||||
pattern = "/[tv]est.sta[a-d]"; |
||||
assertMatched(pattern, "/test.staa"); |
||||
assertMatched(pattern, "/test.stab"); |
||||
assertMatched(pattern, "/test.stac"); |
||||
assertMatched(pattern, "/test.stad"); |
||||
assertMatched(pattern, "/vest.stac"); |
||||
assertNotMatched(pattern, "test.stae"); |
||||
assertNotMatched(pattern, "test.sta9"); |
||||
|
||||
//Test child directory/file is matched
|
||||
pattern = "/src/ne?"; |
||||
assertMatched(pattern, "/src/new/"); |
||||
assertMatched(pattern, "/src/new"); |
||||
assertMatched(pattern, "/src/new/a.c"); |
||||
assertMatched(pattern, "/src/new/a/a.c"); |
||||
assertNotMatched(pattern, "/src/new.c"); |
||||
|
||||
//Test name-only fnmatcher matches
|
||||
pattern = "ne?"; |
||||
assertMatched(pattern, "/src/new/"); |
||||
assertMatched(pattern, "/src/new"); |
||||
assertMatched(pattern, "/src/new/a.c"); |
||||
assertMatched(pattern, "/src/new/a/a.c"); |
||||
assertMatched(pattern, "/neb"); |
||||
assertNotMatched(pattern, "/src/new.c"); |
||||
} |
||||
|
||||
@Test |
||||
public void testTargetWithoutLeadingSlash() { |
||||
//Test basic * and ? for any pattern + any character
|
||||
String pattern = "/*.st?"; |
||||
assertMatched(pattern, "test.stp"); |
||||
assertMatched(pattern, "anothertest.stg"); |
||||
assertMatched(pattern, "anothertest.st0"); |
||||
assertNotMatched(pattern, "anothertest.sta1"); |
||||
//Check that asterisk does not expand to ""
|
||||
assertNotMatched(pattern, "another/test.sta1"); |
||||
|
||||
//Same as above, with a leading slash to ensure that doesn't cause problems
|
||||
pattern = "/*.st?"; |
||||
assertMatched(pattern, "test.stp"); |
||||
assertMatched(pattern, "anothertest.stg"); |
||||
assertMatched(pattern, "anothertest.st0"); |
||||
assertNotMatched(pattern, "anothertest.sta1"); |
||||
//Check that asterisk does not expand to ""
|
||||
assertNotMatched(pattern, "another/test.sta1"); |
||||
|
||||
//Test for numbers
|
||||
pattern = "/*.sta[0-5]"; |
||||
assertMatched(pattern, "test.sta5"); |
||||
assertMatched(pattern, "test.sta4"); |
||||
assertMatched(pattern, "test.sta3"); |
||||
assertMatched(pattern, "test.sta2"); |
||||
assertMatched(pattern, "test.sta1"); |
||||
assertMatched(pattern, "test.sta0"); |
||||
assertMatched(pattern, "anothertest.sta2"); |
||||
assertNotMatched(pattern, "test.stag"); |
||||
assertNotMatched(pattern, "test.sta6"); |
||||
|
||||
//Test for letters
|
||||
pattern = "/[tv]est.sta[a-d]"; |
||||
assertMatched(pattern, "test.staa"); |
||||
assertMatched(pattern, "test.stab"); |
||||
assertMatched(pattern, "test.stac"); |
||||
assertMatched(pattern, "test.stad"); |
||||
assertMatched(pattern, "vest.stac"); |
||||
assertNotMatched(pattern, "test.stae"); |
||||
assertNotMatched(pattern, "test.sta9"); |
||||
|
||||
//Test child directory/file is matched
|
||||
pattern = "/src/ne?"; |
||||
assertMatched(pattern, "src/new/"); |
||||
assertMatched(pattern, "src/new"); |
||||
assertMatched(pattern, "src/new/a.c"); |
||||
assertMatched(pattern, "src/new/a/a.c"); |
||||
assertNotMatched(pattern, "src/new.c"); |
||||
|
||||
//Test name-only fnmatcher matches
|
||||
pattern = "ne?"; |
||||
assertMatched(pattern, "src/new/"); |
||||
assertMatched(pattern, "src/new"); |
||||
assertMatched(pattern, "src/new/a.c"); |
||||
assertMatched(pattern, "src/new/a/a.c"); |
||||
assertMatched(pattern, "neb"); |
||||
assertNotMatched(pattern, "src/new.c"); |
||||
} |
||||
|
||||
@Test |
||||
public void testParentDirectoryGitIgnores() { |
||||
//Contains git ignore patterns such as might be seen in a parent directory
|
||||
|
||||
//Test for wildcards
|
||||
String pattern = "/*/*.c"; |
||||
assertMatched(pattern, "/file/a.c"); |
||||
assertMatched(pattern, "/src/a.c"); |
||||
assertNotMatched(pattern, "/src/new/a.c"); |
||||
|
||||
//Test child directory/file is matched
|
||||
pattern = "/src/new"; |
||||
assertMatched(pattern, "/src/new/"); |
||||
assertMatched(pattern, "/src/new"); |
||||
assertMatched(pattern, "/src/new/a.c"); |
||||
assertMatched(pattern, "/src/new/a/a.c"); |
||||
assertNotMatched(pattern, "/src/new.c"); |
||||
|
||||
//Test child directory is matched, slash after name
|
||||
pattern = "/src/new/"; |
||||
assertMatched(pattern, "/src/new/"); |
||||
assertMatched(pattern, "/src/new/a.c"); |
||||
assertMatched(pattern, "/src/new/a/a.c"); |
||||
assertNotMatched(pattern, "/src/new"); |
||||
assertNotMatched(pattern, "/src/new.c"); |
||||
|
||||
//Test directory is matched by name only
|
||||
pattern = "b1"; |
||||
assertMatched(pattern, "/src/new/a/b1/a.c"); |
||||
assertNotMatched(pattern, "/src/new/a/b2/file.c"); |
||||
assertNotMatched(pattern, "/src/new/a/bb1/file.c"); |
||||
assertNotMatched(pattern, "/src/new/a/file.c"); |
||||
} |
||||
|
||||
@Test |
||||
public void testTrailingSlash() { |
||||
String pattern = "/src/"; |
||||
assertMatched(pattern, "/src/"); |
||||
assertMatched(pattern, "/src/new"); |
||||
assertMatched(pattern, "/src/new/a.c"); |
||||
assertMatched(pattern, "/src/a.c"); |
||||
assertNotMatched(pattern, "/src"); |
||||
assertNotMatched(pattern, "/srcA/"); |
||||
} |
||||
|
||||
@Test |
||||
public void testNameOnlyMatches() { |
||||
/* |
||||
* Name-only matches do not contain any path separators |
||||
*/ |
||||
//Test matches for file extension
|
||||
String pattern = "*.stp"; |
||||
assertMatched(pattern, "/test.stp"); |
||||
assertMatched(pattern, "/src/test.stp"); |
||||
assertNotMatched(pattern, "/test.stp1"); |
||||
assertNotMatched(pattern, "/test.astp"); |
||||
|
||||
//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
|
||||
pattern = "?rc"; |
||||
assertMatched(pattern, "/src/a.c"); |
||||
assertMatched(pattern, "/src/new/a.c"); |
||||
assertMatched(pattern, "/new/src/a.c"); |
||||
assertMatched(pattern, "/file/src"); |
||||
assertMatched(pattern, "/src/"); |
||||
|
||||
//Test matches for name-only, applies to file name or folder name
|
||||
//With a small wildcard
|
||||
pattern = "?r[a-c]"; |
||||
assertMatched(pattern, "/src/a.c"); |
||||
assertMatched(pattern, "/src/new/a.c"); |
||||
assertMatched(pattern, "/new/src/a.c"); |
||||
assertMatched(pattern, "/file/src"); |
||||
assertMatched(pattern, "/src/"); |
||||
assertMatched(pattern, "/srb/a.c"); |
||||
assertMatched(pattern, "/grb/new/a.c"); |
||||
assertMatched(pattern, "/new/crb/a.c"); |
||||
assertMatched(pattern, "/file/3rb"); |
||||
assertMatched(pattern, "/xrb/"); |
||||
assertMatched(pattern, "/3ra/a.c"); |
||||
assertMatched(pattern, "/5ra/new/a.c"); |
||||
assertMatched(pattern, "/new/1ra/a.c"); |
||||
assertMatched(pattern, "/file/dra"); |
||||
assertMatched(pattern, "/era/"); |
||||
assertNotMatched(pattern, "/crg"); |
||||
assertNotMatched(pattern, "/cr3"); |
||||
} |
||||
|
||||
@Test |
||||
public void testNegation() { |
||||
String pattern = "!/test.stp"; |
||||
assertMatched(pattern, "/test.stp"); |
||||
} |
||||
|
||||
@Test |
||||
public void testGetters() { |
||||
IgnoreRule r = new IgnoreRule("/pattern/"); |
||||
assertFalse(r.getNameOnly()); |
||||
assertTrue(r.dirOnly()); |
||||
assertFalse(r.getNegation()); |
||||
assertEquals(r.getPattern(), "/pattern"); |
||||
|
||||
r = new IgnoreRule("/patter?/"); |
||||
assertFalse(r.getNameOnly()); |
||||
assertTrue(r.dirOnly()); |
||||
assertFalse(r.getNegation()); |
||||
assertEquals(r.getPattern(), "/patter?"); |
||||
|
||||
r = new IgnoreRule("patt*"); |
||||
assertTrue(r.getNameOnly()); |
||||
assertFalse(r.dirOnly()); |
||||
assertFalse(r.getNegation()); |
||||
assertEquals(r.getPattern(), "patt*"); |
||||
|
||||
r = new IgnoreRule("pattern"); |
||||
assertTrue(r.getNameOnly()); |
||||
assertFalse(r.dirOnly()); |
||||
assertFalse(r.getNegation()); |
||||
assertEquals(r.getPattern(), "pattern"); |
||||
|
||||
r = new IgnoreRule("!pattern"); |
||||
assertTrue(r.getNameOnly()); |
||||
assertFalse(r.dirOnly()); |
||||
assertTrue(r.getNegation()); |
||||
assertEquals(r.getPattern(), "pattern"); |
||||
|
||||
r = new IgnoreRule("!/pattern"); |
||||
assertFalse(r.getNameOnly()); |
||||
assertFalse(r.dirOnly()); |
||||
assertTrue(r.getNegation()); |
||||
assertEquals(r.getPattern(), "/pattern"); |
||||
|
||||
r = new IgnoreRule("!/patter?"); |
||||
assertFalse(r.getNameOnly()); |
||||
assertFalse(r.dirOnly()); |
||||
assertTrue(r.getNegation()); |
||||
assertEquals(r.getPattern(), "/patter?"); |
||||
} |
||||
|
||||
@Test |
||||
public void testResetState() { |
||||
String pattern = "/build/*"; |
||||
String target = "/build"; |
||||
// Don't use the assert methods of this class, as we want to test
|
||||
// whether the state in IgnoreRule is reset properly
|
||||
IgnoreRule r = new IgnoreRule(pattern); |
||||
// Result should be the same for the same inputs
|
||||
assertFalse(r.isMatch(target, true)); |
||||
assertFalse(r.isMatch(target, true)); |
||||
} |
||||
|
||||
/** |
||||
* Check for a match. If target ends with "/", match will assume that the |
||||
* target is meant to be a directory. |
||||
* @param pattern |
||||
* Pattern as it would appear in a .gitignore file |
||||
* @param target |
||||
* Target file path relative to repository's GIT_DIR |
||||
*/ |
||||
public void assertMatched(String pattern, String target) { |
||||
boolean value = match(pattern, target); |
||||
assertTrue("Expected a match for: " + pattern + " with: " + target, |
||||
value); |
||||
} |
||||
|
||||
/** |
||||
* Check for a match. If target ends with "/", match will assume that the |
||||
* target is meant to be a directory. |
||||
* @param pattern |
||||
* Pattern as it would appear in a .gitignore file |
||||
* @param target |
||||
* Target file path relative to repository's GIT_DIR |
||||
*/ |
||||
public void assertNotMatched(String pattern, String target) { |
||||
boolean value = match(pattern, target); |
||||
assertFalse("Expected no match for: " + pattern + " with: " + target, |
||||
value); |
||||
} |
||||
|
||||
/** |
||||
* Check for a match. If target ends with "/", match will assume that the |
||||
* target is meant to be a directory. |
||||
* |
||||
* @param pattern |
||||
* Pattern as it would appear in a .gitignore file |
||||
* @param target |
||||
* Target file path relative to repository's GIT_DIR |
||||
* @return Result of IgnoreRule.isMatch(String, boolean) |
||||
*/ |
||||
private static boolean match(String pattern, String target) { |
||||
IgnoreRule r = new IgnoreRule(pattern); |
||||
//If speed of this test is ever an issue, we can use a presetRule field
|
||||
//to avoid recompiling a pattern each time.
|
||||
return r.isMatch(target, target.endsWith("/")); |
||||
} |
||||
} |
@ -1,278 +0,0 @@
|
||||
/* |
||||
* Copyright (C) 2010, Red Hat Inc. |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.ignore; |
||||
|
||||
import org.eclipse.jgit.errors.InvalidPatternException; |
||||
import org.eclipse.jgit.fnmatch.FileNameMatcher; |
||||
|
||||
/** |
||||
* A single ignore rule corresponding to one line in a .gitignore or ignore |
||||
* file. Parses the ignore pattern |
||||
* |
||||
* Inspiration from: Ferry Huberts |
||||
* |
||||
* @deprecated this rule does not support double star pattern and is slow |
||||
* parsing glob expressions. Consider to use {@link FastIgnoreRule} |
||||
* instead. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=440732
|
||||
*/ |
||||
@Deprecated |
||||
public class IgnoreRule { |
||||
private String pattern; |
||||
private boolean negation; |
||||
private boolean nameOnly; |
||||
private boolean dirOnly; |
||||
private FileNameMatcher matcher; |
||||
|
||||
/** |
||||
* Create a new ignore rule with the given pattern. Assumes that |
||||
* the pattern is already trimmed. |
||||
* |
||||
* @param pattern |
||||
* Base pattern for the ignore rule. This pattern will |
||||
* be parsed to generate rule parameters. |
||||
*/ |
||||
public IgnoreRule (String pattern) { |
||||
this.pattern = pattern; |
||||
negation = false; |
||||
nameOnly = false; |
||||
dirOnly = false; |
||||
matcher = null; |
||||
setup(); |
||||
} |
||||
|
||||
/** |
||||
* Remove leading/trailing characters as needed. Set up |
||||
* rule variables for later matching. |
||||
*/ |
||||
private void setup() { |
||||
int startIndex = 0; |
||||
int endIndex = pattern.length(); |
||||
if (pattern.startsWith("!")) { //$NON-NLS-1$
|
||||
startIndex++; |
||||
negation = true; |
||||
} |
||||
|
||||
if (pattern.endsWith("/")) { //$NON-NLS-1$
|
||||
endIndex --; |
||||
dirOnly = true; |
||||
} |
||||
|
||||
pattern = pattern.substring(startIndex, endIndex); |
||||
boolean hasSlash = pattern.contains("/"); //$NON-NLS-1$
|
||||
|
||||
if (!hasSlash) |
||||
nameOnly = true; |
||||
else if (!pattern.startsWith("/")) { //$NON-NLS-1$
|
||||
//Contains "/" but does not start with one
|
||||
//Adding / to the start should not interfere with matching
|
||||
pattern = "/" + pattern; //$NON-NLS-1$
|
||||
} |
||||
|
||||
if (pattern.contains("*") || pattern.contains("?") || pattern.contains("[")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
try { |
||||
matcher = new FileNameMatcher(pattern, Character.valueOf('/')); |
||||
} catch (InvalidPatternException e) { |
||||
// Ignore pattern exceptions
|
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* @return |
||||
* True if the pattern is just a file name and not a path |
||||
*/ |
||||
public boolean getNameOnly() { |
||||
return nameOnly; |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @return |
||||
* True if the pattern should match directories only |
||||
*/ |
||||
public boolean dirOnly() { |
||||
return dirOnly; |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @return |
||||
* True if the pattern had a "!" in front of it |
||||
*/ |
||||
public boolean getNegation() { |
||||
return negation; |
||||
} |
||||
|
||||
/** |
||||
* @return |
||||
* The blob pattern to be used as a matcher |
||||
*/ |
||||
public String getPattern() { |
||||
return pattern; |
||||
} |
||||
|
||||
/** |
||||
* Returns true if a match was made. |
||||
* <br> |
||||
* This function does NOT return the actual ignore status of the |
||||
* target! Please consult {@link #getResult()} for the ignore status. The actual |
||||
* ignore status may be true or false depending on whether this rule is |
||||
* an ignore rule or a negation rule. |
||||
* |
||||
* @param target |
||||
* Name pattern of the file, relative to the base directory of this rule |
||||
* @param isDirectory |
||||
* Whether the target file is a directory or not |
||||
* @return |
||||
* True if a match was made. This does not necessarily mean that |
||||
* the target is ignored. Call {@link IgnoreRule#getResult() getResult()} for the result. |
||||
*/ |
||||
public boolean isMatch(String target, boolean isDirectory) { |
||||
if (!target.startsWith("/")) //$NON-NLS-1$
|
||||
target = "/" + target; //$NON-NLS-1$
|
||||
|
||||
if (matcher == null) { |
||||
if (target.equals(pattern)) { |
||||
//Exact match
|
||||
if (dirOnly && !isDirectory) |
||||
//Directory expectations not met
|
||||
return false; |
||||
else |
||||
//Directory expectations met
|
||||
return true; |
||||
} |
||||
|
||||
/* |
||||
* Add slashes for startsWith check. This avoids matching e.g. |
||||
* "/src/new" to /src/newfile" but allows "/src/new" to match |
||||
* "/src/new/newfile", as is the git standard |
||||
*/ |
||||
if ((target).startsWith(pattern + "/")) //$NON-NLS-1$
|
||||
return true; |
||||
|
||||
if (nameOnly) { |
||||
//Iterate through each sub-name
|
||||
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; |
||||
} |
||||
} |
||||
|
||||
} else { |
||||
matcher.reset(); |
||||
matcher.append(target); |
||||
if (matcher.isMatch()) |
||||
return true; |
||||
|
||||
final String[] segments = target.split("/"); //$NON-NLS-1$
|
||||
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); |
||||
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 (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; |
||||
|
||||
matcher.append("/" + segmentName); //$NON-NLS-1$
|
||||
|
||||
if (matcher.isMatch() |
||||
&& doesMatchDirectoryExpectations(isDirectory, idx, |
||||
segments.length)) |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* If a call to <code>isMatch(String, boolean)</code> was previously |
||||
* made, this will return whether or not the target was ignored. Otherwise |
||||
* this just indicates whether the rule is non-negation or negation. |
||||
* |
||||
* @return |
||||
* True if the target is to be ignored, false otherwise. |
||||
*/ |
||||
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; |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return pattern; |
||||
} |
||||
} |
Loading…
Reference in new issue