diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java index 8038206e9..4c329cb19 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java @@ -76,7 +76,8 @@ public void setup() { "b/c", "c/d/e", "c/d/f", - "d/e/f/g" + "d/e/f/g", + "d/e/f/g.x" }; // @formatter:on filter = PathFilterGroup.createFromStrings(paths); @@ -90,6 +91,7 @@ public void testExact() throws MissingObjectException, assertTrue(filter.include(fakeWalk("c/d/e"))); assertTrue(filter.include(fakeWalk("c/d/f"))); assertTrue(filter.include(fakeWalk("d/e/f/g"))); + assertTrue(filter.include(fakeWalk("d/e/f/g.x"))); } @Test @@ -132,6 +134,11 @@ public void testFilterIsPrefixOfKey() throws MissingObjectException, assertTrue(filter.include(fakeWalk("c/d/e/f"))); assertTrue(filter.include(fakeWalk("c/d/f/g"))); assertTrue(filter.include(fakeWalk("d/e/f/g/h"))); + assertTrue(filter.include(fakeWalk("d/e/f/g/y"))); + assertTrue(filter.include(fakeWalk("d/e/f/g.x/h"))); + // listed before g/y, so can't StopWalk here, but it's not included + // either + assertFalse(filter.include(fakeWalk("d/e/f/g.y"))); } @Test @@ -172,6 +179,9 @@ public void testStopWalk() throws MissingObjectException, // good } + // less obvious #2 due to git sorting order + filter.include(fakeWalk("d/e/f/g/h.txt")); + // non-ascii try { filter.include(fakeWalk("\u00C0")); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java index 66d9f87a7..bdfde0bfc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java @@ -208,6 +208,19 @@ private Group(final PathFilter[] pathFilters) { if (compare(max, pf.pathRaw) < 0) max = pf.pathRaw; } + // Adjust max for the git sort order. A path we compare + // with may end with a slash at any position (but the + // first, but we ignore that here since it's not relevant). + // Such paths must be included in the processing + // before we can give up and throw a StopWalkException. + byte[] newMax = new byte[max.length + 1]; + for (int i = 0; i < max.length; ++i) + if ((max[i] & 0xFF) < '/') + newMax[i] = '/'; + else + newMax[i] = max[i]; + newMax[newMax.length - 1] = '/'; + max = newMax; } private static int compare(byte[] a, byte[] b) {