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 '-':