Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[jgit-dev] PathMatcher behaviour is inconsistent with "git check-attr"

Hello,
There's a case when PathMatcher behaviour differs from "git check-attr". If I create .gitattributes 
file with the following content:

images/** attr=value

and then run

  $ git check-attr attr images
  images/: attr: unspecified

  $ git check-attr attr images/
  images/: attr: unspecified

  $ git check-attr attr images/x
  images/x: attr: value

If I do the same with PathMatcher.createPathMatcher(), with every reasonable parameters it says that 
all the paths above match to the pattern "images/**". So it's an inconsistency with Git behaviour.

It's not a surprise because near line 234 of PathMatcher.java there's a comment

                                       if (matcher == matchers.size() - 2
                                                       && matchers.get(matcher + 1) == WILD)
                                               // ** can match *nothing*: a/b/** match also a/b
                                               return true;

stating that a/b/** should match a/b, what's wrong.

I've attached a patch fixing the problem for all my cases, but I was surprised why the code has 
  matchers.size() - 2
and
  matcher + 1

instead of 
  matchers.size() - 1
and
  matcher

I've changed it for the latter and the code still works. For me it makes more sense as it checks 
whether current segment is double star and it is actually the last one.

Could you please have a look at those 4 lines and maybe apply my changes?
--
Dmitry Pavlenko,
TMate Software,
http://subgit.com/ - git-svn bridge
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..36eaa0ef6 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
@@ -231,10 +231,11 @@ boolean iterate(final String path, final int startIncl, final int endExcl,
 					match = matches(matcher, path, left, endExcl,
 							assumeDirectory);
 				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)
+						// a/b/** doesn't match a/b
+						// but a/b/** matches a/b/x
+						return Strings.stripTrailing(path.substring(left, endExcl), slash).length() != 0;
 					if (matcher < matchers.size() - 1
 							&& matchers.get(matcher) == WILD) {
 						// ** can match *nothing*: a/**/b match also a/b

Back to the top