ApplyCommand: handle completely empty context lines in text patches
C git treats completely empty lines as empty context lines (which
traditionally have a single blank). Apparently newer GNU diff may
produce such lines; see [1]. ("Newer" meaning "since 2006"...)
[1] https://github.com/git/git/commit/b507b465f7831
Change-Id: I80c1f030edb17a46289b1dabf11a2648d2660d38
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine.patch
new file mode 100644
index 0000000..18c80c4
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine.patch
@@ -0,0 +1,10 @@
+diff --git a/emptyLine b/emptyLine
+index 1fd3fa2..45c2c9b 100644
+--- a/emptyLine
++++ b/emptyLine
+@@ -1,4 +1,4 @@
+ foo
+
+-fie
++bar
+ fum
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PostImage
new file mode 100644
index 0000000..45c2c9b
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PostImage
@@ -0,0 +1,4 @@
+foo
+
+bar
+fum
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PreImage
new file mode 100644
index 0000000..1fd3fa2
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PreImage
@@ -0,0 +1,4 @@
+foo
+
+fie
+fum
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
index b997ac0..807b961 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
@@ -296,6 +296,14 @@
}
@Test
+ public void testEmptyLine() throws Exception {
+ // C git accepts completely empty lines as empty context lines.
+ // According to comments in the C git sources (apply.c), newer GNU diff
+ // may produce such diffs.
+ checkBinary("emptyLine", true);
+ }
+
+ @Test
public void testAddA1() throws Exception {
ApplyResult result = init("A1", false, true);
assertEquals(1, result.getUpdatedFiles().size());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
index ec53412..f649c5f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
@@ -640,6 +640,11 @@
int sz = hunkLines.size();
for (int j = 1; j < sz; j++) {
ByteBuffer hunkLine = hunkLines.get(j);
+ if (!hunkLine.hasRemaining()) {
+ // Completely empty line; accept as empty context line
+ applyAt++;
+ continue;
+ }
switch (hunkLine.array()[hunkLine.position()]) {
case ' ':
applyAt++;
@@ -676,8 +681,7 @@
// Must be the marker for the final newline
break;
}
- out.write(line.array(), line.position(),
- line.limit() - line.position());
+ out.write(line.array(), line.position(), line.remaining());
if (l.hasNext()) {
out.write('\n');
}
@@ -703,6 +707,14 @@
int pos = line;
for (int j = 1; j < sz; j++) {
ByteBuffer hunkLine = hunkLines.get(j);
+ if (!hunkLine.hasRemaining()) {
+ // Empty line. Accept as empty context line.
+ if (pos >= limit || newLines.get(pos).hasRemaining()) {
+ return false;
+ }
+ pos++;
+ continue;
+ }
switch (hunkLine.array()[hunkLine.position()]) {
case ' ':
case '-':