Browse Source

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>
tags/v5.12.0.202105261145-m3
Thomas Wolf 3 years ago
parent
commit
2a0295ccfd

+ 10
- 0
org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine.patch View File

@@ -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

+ 4
- 0
org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PostImage View File

@@ -0,0 +1,4 @@
foo

bar
fum

+ 4
- 0
org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PreImage View File

@@ -0,0 +1,4 @@
foo

fie
fum

+ 8
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java View File

@@ -295,6 +295,14 @@ public class ApplyCommandTest extends RepositoryTestCase {
checkBinary("umlaut", true);
}

@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);

+ 14
- 2
org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java View File

@@ -640,6 +640,11 @@ public class ApplyCommand extends GitCommand<ApplyResult> {
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 @@ public class ApplyCommand extends GitCommand<ApplyResult> {
// 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 @@ public class ApplyCommand extends GitCommand<ApplyResult> {
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 '-':

Loading…
Cancel
Save