Skip to content
This repository was archived by the owner on Nov 12, 2019. It is now read-only.

Empty-context add-only patches were applied in the wrong place #10

Merged
merged 1 commit into from
Jun 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 29 additions & 24 deletions java-diff-utils-lib/src/main/java/difflib/DiffUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,25 +204,8 @@ public static Patch<String> parseUnifiedDiff(List<String> diff) {
Matcher m = unifiedDiffChunkRe.matcher(line);
if (m.find()) {
// Process the lines in the previous chunk
if (rawChunk.size() != 0) {
List<String> oldChunkLines = new ArrayList<String>();
List<String> newChunkLines = new ArrayList<String>();

for (String[] raw_line : rawChunk) {
tag = raw_line[0];
rest = raw_line[1];
if (tag.equals(" ") || tag.equals("-")) {
oldChunkLines.add(rest);
}
if (tag.equals(" ") || tag.equals("+")) {
newChunkLines.add(rest);
}
}
patch.addDelta(new ChangeDelta<String>(new Chunk<String>(
old_ln - 1, oldChunkLines), new Chunk<String>(
new_ln - 1, newChunkLines)));
rawChunk.clear();
}
processRawChunk(rawChunk, patch, old_ln, new_ln);

// Parse the @@ header
old_ln = m.group(1) == null ? 1 : Integer.parseInt(m.group(1));
new_ln = m.group(3) == null ? 1 : Integer.parseInt(m.group(3));
Expand All @@ -247,6 +230,15 @@ public static Patch<String> parseUnifiedDiff(List<String> diff) {
}

// Process the lines in the last chunk
processRawChunk(rawChunk, patch, old_ln, new_ln);

return patch;
}

public static void processRawChunk(List<String[]> rawChunk, Patch patch, int old_ln, int new_ln) {
String tag;
String rest;

if (rawChunk.size() != 0) {
List<String> oldChunkLines = new ArrayList<String>();
List<String> newChunkLines = new ArrayList<String>();
Expand All @@ -262,13 +254,18 @@ public static Patch<String> parseUnifiedDiff(List<String> diff) {
}
}

patch.addDelta(new ChangeDelta<String>(new Chunk<String>(
old_ln - 1, oldChunkLines), new Chunk<String>(new_ln - 1,
newChunkLines)));
if (oldChunkLines.isEmpty()) {
patch.addDelta(new InsertDelta<String>(new Chunk<String>(old_ln, oldChunkLines),
new Chunk<String>(new_ln - 1, newChunkLines)));
} else if (newChunkLines.isEmpty()) {
patch.addDelta(new DeleteDelta<String>(new Chunk<String>(old_ln - 1, oldChunkLines),
new Chunk<String>(new_ln, newChunkLines)));
} else {
patch.addDelta(new ChangeDelta<String>(new Chunk<String>(old_ln - 1, oldChunkLines),
new Chunk<String>(new_ln - 1, newChunkLines)));
}
rawChunk.clear();
}

return patch;
}

/**
Expand Down Expand Up @@ -416,6 +413,14 @@ private static List<String> processDeltas(List<String> origLines,
revTotal++;
}

// In case of empty chunk and context
if (origTotal == 0 && origStart > 1)
--origStart;

// In case of empty chunk and context
if (revTotal == 0 && revStart > 1)
--revStart;

// Create and insert the block header, conforming to the Unified Diff
// standard
StringBuffer header = new StringBuffer();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package diffutils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import difflib.DiffUtils;
import difflib.Patch;
import difflib.PatchFailedException;

import junit.framework.TestCase;

public class EmptyContextUnifiedDiffTest extends TestCase {

public List<String> fileToLines(String filename) {
List<String> lines = new LinkedList<String>();
String line = "";
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(filename));
while ((line = in.readLine()) != null) {
lines.add(line);
}
} catch (IOException e) {
e.printStackTrace();
fail(e.getMessage());
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// ignore ... any errors should already have been
// reported via an IOException from the final flush.
}
}
}
return lines;
}

public void testEmptyUnifiedContextPatch() {
List<String> origLines = fileToLines(TestConstants.MOCK_FOLDER + "unified_empty_context_original.txt");
List<String> revLines = fileToLines(TestConstants.MOCK_FOLDER + "unified_empty_context_revised.txt");
List<String> unifiedDiff = fileToLines(TestConstants.MOCK_FOLDER + "unified_empty_context_patch.txt");

List<String> patchedLines = null;
Patch patch = DiffUtils.parseUnifiedDiff(unifiedDiff);

try {
patchedLines = (List<String>) patch.applyTo(origLines);
} catch (PatchFailedException e) {
fail(e.getMessage());
}

verifyLinesEqual(patchedLines, revLines);
}

public void testEmptyUnifiedContextDiff() {
List<String> origLines = fileToLines(TestConstants.MOCK_FOLDER + "unified_empty_context_original.txt");
List<String> revLines = fileToLines(TestConstants.MOCK_FOLDER + "unified_empty_context_revised.txt");

List<String> patchedLines = null;

// Generate a 0-context diff then reapply
Patch generatedPatch = DiffUtils.diff(origLines, revLines);
List<String> generatedDiff = DiffUtils.generateUnifiedDiff("original", "revised", origLines, generatedPatch, 0);
Patch newPatch = DiffUtils.parseUnifiedDiff(generatedDiff);

try {
patchedLines = (List<String>) newPatch.applyTo(origLines);
} catch (PatchFailedException e) {
fail(e.getMessage());
}

verifyLinesEqual(patchedLines, revLines);
}

public void verifyLinesEqual(List<String> patchedLines, List<String> revLines) {
assertTrue(revLines.size() == patchedLines.size());
for (int i = 0; i < revLines.size(); i++) {
String l1 = revLines.get(i);
String l2 = patchedLines.get(i);
if (!l1.equals(l2)) {
fail("Line " + (i + 1) + " of the patched file did not match the revised original");
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This
is
a
test
file
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
--- uc_original.txt 2011-06-14 16:21:56.578627000 +0300
+++ uc_insert_revised.txt 2011-06-14 16:20:37.654820000 +0300
@@ -2,0 +3 @@
+not
@@ -5 +5,0 @@
-file
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This
is
not
a
test