* stable-2.3: Prepare 2.3.2-SNAPSHOT builds JGit v2.3.1.201302201838-r Accept Change-Id even if footer contains not well-formed entries Fix false positives in hashing used by PathFilterGroup Change-Id: I5882aa3b482d6bcd40a45bed51e5ab03f018a5bc Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>tags/v3.0.0.201305080800-m7
@@ -134,6 +134,19 @@ public class PathFilterGroupTest { | |||
assertTrue(filter.include(fakeWalk("d/e/f/g/h"))); | |||
} | |||
@Test | |||
public void testLongPaths() throws MissingObjectException, | |||
IncorrectObjectTypeException, IOException { | |||
TreeFilter longPathFilter = PathFilterGroup | |||
.createFromStrings( | |||
"tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java", | |||
"tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest2.java"); | |||
assertFalse(longPathFilter | |||
.include(fakeWalk("tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java"))); | |||
assertFalse(longPathFilter.include(fakeWalk("tst/a-other-in-same"))); | |||
assertFalse(longPathFilter.include(fakeWalk("a-nothing-in-common"))); | |||
} | |||
@Test | |||
public void testStopWalk() throws MissingObjectException, | |||
IncorrectObjectTypeException, IOException { |
@@ -642,29 +642,58 @@ public class ChangeIdUtilTest { | |||
assertEquals(3, ChangeIdUtil.indexOfChangeId("x\n" + "\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n", | |||
"\n")); | |||
assertEquals(3, ChangeIdUtil.indexOfChangeId("x\n" + "\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n\n\n", | |||
"\n")); | |||
assertEquals(3, ChangeIdUtil.indexOfChangeId("x\n" + "\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n \n \n", | |||
"\n")); | |||
assertEquals(3, ChangeIdUtil.indexOfChangeId("x\n" + "\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n", | |||
"\n")); | |||
// leading whitespace is rejected by Gerrit | |||
assertEquals(-1, ChangeIdUtil.indexOfChangeId("x\n" + "\n" | |||
+ " Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n", | |||
"\n")); | |||
assertEquals(-1, ChangeIdUtil.indexOfChangeId("x\n" + "\n" | |||
+ "\t Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n", | |||
"\n")); | |||
assertEquals(-1, ChangeIdUtil.indexOfChangeId("x\n" + "\n" | |||
+ "Change-Id: \n", "\n")); | |||
assertEquals(3, ChangeIdUtil.indexOfChangeId("x\n" + "\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701 \n", | |||
"\n")); | |||
assertEquals(12, ChangeIdUtil.indexOfChangeId("x\n" + "\n" | |||
+ "Bug 4711\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n", | |||
"\n")); | |||
assertEquals(56, ChangeIdUtil.indexOfChangeId("x\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n" | |||
+ "\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n", | |||
"\n")); | |||
assertEquals(-1, ChangeIdUtil.indexOfChangeId("x\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n" | |||
+ "\n" + "x\n", "\n")); | |||
assertEquals(-1, ChangeIdUtil.indexOfChangeId("x\n\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n" | |||
+ "\n" + "x\n", "\n")); | |||
assertEquals(5, ChangeIdUtil.indexOfChangeId("x\r\n" + "\r\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\r\n", | |||
"\r\n")); | |||
assertEquals(3, ChangeIdUtil.indexOfChangeId("x\r" + "\r" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\r", | |||
"\r")); | |||
assertEquals(3, ChangeIdUtil.indexOfChangeId("x\r" + "\r" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\r", | |||
"\r")); | |||
assertEquals(8, ChangeIdUtil.indexOfChangeId("x\ny\n\nz\n" + "\n" | |||
+ "Change-Id: I3b7e4e16b503ce00f07ba6ad01d97a356dad7701\n", | |||
"\n")); | |||
} | |||
@Test | |||
public void testIndexOfFirstFooterLine() { | |||
assertEquals( | |||
2, | |||
ChangeIdUtil.indexOfFirstFooterLine(new String[] { "a", "", | |||
"Bug: 42", "Signed-Off-By: j.developer@a.com" })); | |||
assertEquals( | |||
3, | |||
ChangeIdUtil.indexOfFirstFooterLine(new String[] { "a", | |||
"Bug: 42", "", "Signed-Off-By: j.developer@a.com" })); | |||
} | |||
private void hookDoesNotModify(final String in) throws Exception { | |||
assertEquals(in, call(in)); | |||
} |
@@ -88,7 +88,7 @@ class ByteArraySet { | |||
} | |||
private static boolean equals(byte[] a, byte[] b, int length) { | |||
if (a.length < length || b.length < length) | |||
if (a.length != length || b.length < length) | |||
return false; | |||
for (int i = 0; i < length; ++i) { | |||
if (a[i] != b[i]) |
@@ -125,9 +125,14 @@ public class ChangeIdUtil { | |||
private static final Pattern footerPattern = Pattern | |||
.compile("(^[a-zA-Z0-9-]+:(?!//).*$)"); //$NON-NLS-1$ | |||
private static final Pattern changeIdPattern = Pattern | |||
.compile("(^" + CHANGE_ID + " *I[a-f0-9]{40}$)"); //$NON-NLS-1$ //$NON-NLS-2$ | |||
private static final Pattern includeInFooterPattern = Pattern | |||
.compile("^[ \\[].*$"); //$NON-NLS-1$ | |||
private static final Pattern trailingWhitespace = Pattern.compile("\\s+$"); | |||
/** | |||
* Find the right place to insert a Change-Id and return it. | |||
* <p> | |||
@@ -209,8 +214,11 @@ public class ChangeIdUtil { | |||
} | |||
/** | |||
* Find the index in the String {@code} message} where the Change-Id entry | |||
* begins | |||
* Return the index in the String {@code message} where the Change-Id entry | |||
* in the footer begins. If there are more than one entries matching the | |||
* pattern, return the index of the last one in the last section. Because of | |||
* Bug: 400818 we release the constraint here that a footer must contain | |||
* only lines matching {@code footerPattern}. | |||
* | |||
* @param message | |||
* @param delimiter | |||
@@ -221,14 +229,32 @@ public class ChangeIdUtil { | |||
*/ | |||
public static int indexOfChangeId(String message, String delimiter) { | |||
String[] lines = message.split(delimiter); | |||
int footerFirstLine = indexOfFirstFooterLine(lines); | |||
if (footerFirstLine == lines.length) | |||
return -1; | |||
int indexOfChangeIdLine = 0; | |||
boolean inFooter = false; | |||
for (int i = lines.length - 1; i >= 0; --i) { | |||
if (!inFooter && isEmptyLine(lines[i])) | |||
continue; | |||
inFooter = true; | |||
if (changeIdPattern.matcher(trimRight(lines[i])).matches()) { | |||
indexOfChangeIdLine = i; | |||
break; | |||
} else if (isEmptyLine(lines[i]) || i == 0) | |||
return -1; | |||
} | |||
int indexOfChangeIdLineinString = 0; | |||
for (int i = 0; i < indexOfChangeIdLine; ++i) | |||
indexOfChangeIdLineinString += lines[i].length() | |||
+ delimiter.length(); | |||
return indexOfChangeIdLineinString | |||
+ lines[indexOfChangeIdLine].indexOf(CHANGE_ID); | |||
} | |||
private static boolean isEmptyLine(String line) { | |||
return line.trim().length() == 0; | |||
} | |||
int indexOfFooter = 0; | |||
for (int i = 0; i < footerFirstLine; ++i) | |||
indexOfFooter += lines[i].length() + delimiter.length(); | |||
return message.indexOf(CHANGE_ID, indexOfFooter); | |||
private static String trimRight(String s) { | |||
return trailingWhitespace.matcher(s).replaceAll(""); //$NON-NLS-1$ | |||
} | |||
/** |