java-diff-utils / java-diff-utils

Diff Utils library is an OpenSource library for performing the comparison / diff operations between texts or some kind of data: computing diffs, applying patches, generating unified diffs or parsing them, generating diff output for easy future displaying (like side-by-side view) and so on.

Home Page:https://java-diff-utils.github.io/java-diff-utils/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Diff created with java-diff-utils cannot be applied with `git apply` if file is shorter than context

lgrammel opened this issue · comments

Describe the bug
Diff cannot be applied with git apply

To Reproduce

  1. original content
const world: string = 'world',
      p: number | undefined = 42;

console.log(`Hello, ${world}!`);
  1. new content
const world: string = 'world';
const p: number | undefined = 42;

console.log(`Hello, ${world}!`);
  1. code to create diff (Kotlin)
/**
 * @param contextSize
 *        How many lines of context around each changed line should be included.
 */
class DiffFactory(private val contextSize: Int) {

    companion object {

        private const val LINE_SEPARATOR = "\n"
    }

    /**
     * Creates a git-apply compatible diff.
     */
    fun computeDiff(
        filename: String,
        originalContent: String,
        newContent: String
    ): String = UnifiedDiffUtils.generateUnifiedDiff(
        "a/$filename", // a/ and b/ required for git-apply compatibility
        "b/$filename",
        originalContent.split(LINE_SEPARATOR),
        DiffUtils.diff(
            originalContent, newContent,
            NullDiffAlgorithmListener
        ),
        contextSize
    ).joinToString(LINE_SEPARATOR)
}
  1. With contextSize = 3 the following diff gets created:
--- a/examples/unchain-variable-declaration.js
+++ b/examples/unchain-variable-declaration.js
@@ -1,5 +1,5 @@
-const world: string = 'world',
-      p: number | undefined = 42;
+const world: string = 'world';
+const p: number | undefined = 42;
 
 console.log(`Hello, ${world}!`);
 

(important: line with 1 space at the end - I've also added an empty newline to support git apply call from file instead of system in)
5. git apply fails

> git apply example.diff
error: patch failed: examples/unchain-variable-declaration.js:1
error: examples/unchain-variable-declaration.js: patch does not apply

Expected behavior
Git apply works with the following patch:

--- a/examples/unchain-variable-declaration.js
+++ b/examples/unchain-variable-declaration.js
@@ -1,4 +1,4 @@
-const world: string = 'world',
-      p: number | undefined = 42;
+const world: string = 'world';
+const p: number | undefined = 42;
 
 console.log(`Hello, ${world}!`);

The difference is that the index is limited to 1,4 (original input is 4 lines long).

System

  • Kotlin 1.4

I created a test from your sources and I got the correct result (GenerateunifiedDiffTest.testWrongContextLength):

--- a/$filename
+++ b/$filename
@@ -1,4 +1,4 @@
-const world: string = 'world',
-      p: number | undefined = 42;
+const world: string = 'world';
+const p: number | undefined = 42;
 
 console.log(`Hello, ${world}!`);

So I must assume, there is something different in your setup.

Thanks for taking a look. I'll see if I can find out what is different in my setup.