Browse Source

RawTextComparator.WS_IGNORE_CHANGE must not compare whitespace

Only the presence or absence of whitespace is significant; but not the
actual whitespace characters. Don't compare whitespace bytes.

Compare the C git implementation at [1].

[1] https://github.com/git/git/blob/0d0e1e8/xdiff/xutils.c#L173

Bug: 563570
Change-Id: I2d0522b637ba6b5c8b911b3376a9df5daa9d4c27
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
master
Thomas Wolf 5 years ago
parent
commit
6f17f9ed3f
  1. 28
      org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RawTextIgnoreWhitespaceChangeTest.java
  2. 28
      org.eclipse.jgit/src/org/eclipse/jgit/diff/RawTextComparator.java

28
org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RawTextIgnoreWhitespaceChangeTest.java

@ -75,4 +75,32 @@ public class RawTextIgnoreWhitespaceChangeTest {
assertTrue(cmp.equals(a, 5, b, 5)); assertTrue(cmp.equals(a, 5, b, 5));
assertTrue(cmp.equals(b, 5, a, 5)); assertTrue(cmp.equals(b, 5, a, 5));
} }
@Test
public void testEqualsWithTabs() {
RawText a = new RawText(
Constants.encodeASCII("a\tb\t \na\tb\t c \n foo\na b\na b"));
RawText b = new RawText(
Constants.encodeASCII("a b \na b c\n\tfoo\nab\na \tb"));
// "a\tb\t \n" == "a b \n"
assertTrue(cmp.equals(a, 0, b, 0));
assertTrue(cmp.equals(b, 0, a, 0));
// "a\tb\t c \n" == "a b c\n"
assertTrue(cmp.equals(a, 1, b, 1));
assertTrue(cmp.equals(b, 1, a, 1));
// " foo" == "\tfoo"
assertTrue(cmp.equals(a, 2, b, 2));
assertTrue(cmp.equals(b, 2, a, 2));
// "a b" != "ab"
assertFalse(cmp.equals(a, 3, b, 3));
assertFalse(cmp.equals(b, 3, a, 3));
// "a b" == "a \tb "
assertTrue(cmp.equals(a, 4, b, 4));
assertTrue(cmp.equals(b, 4, a, 4));
}
} }

28
org.eclipse.jgit/src/org/eclipse/jgit/diff/RawTextComparator.java

@ -191,21 +191,15 @@ public abstract class RawTextComparator extends SequenceComparator<RawText> {
be = trimTrailingWhitespace(b.content, bs, be); be = trimTrailingWhitespace(b.content, bs, be);
while (as < ae && bs < be) { while (as < ae && bs < be) {
byte ac = a.content[as]; byte ac = a.content[as++];
byte bc = b.content[bs]; byte bc = b.content[bs++];
if (ac != bc) if (isWhitespace(ac) && isWhitespace(bc)) {
return false;
if (isWhitespace(ac))
as = trimLeadingWhitespace(a.content, as, ae); as = trimLeadingWhitespace(a.content, as, ae);
else
as++;
if (isWhitespace(bc))
bs = trimLeadingWhitespace(b.content, bs, be); bs = trimLeadingWhitespace(b.content, bs, be);
else } else if (ac != bc) {
bs++; return false;
}
} }
return as == ae && bs == be; return as == ae && bs == be;
} }
@ -215,12 +209,12 @@ public abstract class RawTextComparator extends SequenceComparator<RawText> {
int hash = 5381; int hash = 5381;
end = trimTrailingWhitespace(raw, ptr, end); end = trimTrailingWhitespace(raw, ptr, end);
while (ptr < end) { while (ptr < end) {
byte c = raw[ptr]; byte c = raw[ptr++];
hash = ((hash << 5) + hash) + (c & 0xff); if (isWhitespace(c)) {
if (isWhitespace(c))
ptr = trimLeadingWhitespace(raw, ptr, end); ptr = trimLeadingWhitespace(raw, ptr, end);
else c = ' ';
ptr++; }
hash = ((hash << 5) + hash) + (c & 0xff);
} }
return hash; return hash;
} }

Loading…
Cancel
Save