David Wong
David Wong

Reputation: 19

Different result between JGit diff and git diff

I'm trying to get differences of two commits in Java by JGit library. Here is my code:

    public static void getDiffBlocks2(Git git, String javaFilePath) throws IOException {
        Repository repository = git.getRepository();
        ObjectId baseCommitId = repository.resolve("commitID1");
        ObjectId headCommitId = repository.resolve("commitID2");

        // Parse the commits
        RevWalk revWalk = new RevWalk(repository);
        RevCommit baseCommit = revWalk.parseCommit(baseCommitId);
        RevCommit headCommit = revWalk.parseCommit(headCommitId);

        // Prepare the tree parsers for the base and head commits
        CanonicalTreeParser baseTreeParser = new CanonicalTreeParser();
        try (ObjectReader reader = repository.newObjectReader()) {
            baseTreeParser.reset(reader, baseCommit.getTree().getId());
        }

        CanonicalTreeParser headTreeParser = new CanonicalTreeParser();
        try (ObjectReader reader = repository.newObjectReader()) {
            headTreeParser.reset(reader, headCommit.getTree().getId());
        }

        // Use a ByteArrayOutputStream to capture the diff output
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        DiffFormatter diffFormatter = new DiffFormatter(outputStream);
        diffFormatter.setRepository(repository);
        diffFormatter.setDiffComparator(RawTextComparator.WS_IGNORE_ALL);
        diffFormatter.setDetectRenames(true);

        // Get the diff entries
        List<DiffEntry> diffs = diffFormatter.scan(baseTreeParser, headTreeParser);

        // Format the diff entries
        for (DiffEntry entry : diffs) {
            if (entry.getNewPath().equals(javaFilePath) || entry.getOldPath().equals(javaFilePath)) {
                diffFormatter.format(entry);
            }
        }

        // Convert the diff output to a string
        String diffOutput = outputStream.toString();
        List<String> filteredLines;
        // The following part is just filtering and can be ignored.
        try (BufferedReader reader = new BufferedReader(new StringReader(diffOutput))) {
            // Regex pattern to match the lines with @@ -<numbers> +<numbers> @@
            Pattern pattern = Pattern.compile("^@@ -[0-9]+(,[0-9]+)? \\+[0-9]+(,[0-9]+)? @@");
            // Regex pattern to extract the +<numbers>
            Pattern extractPattern = Pattern.compile("\\+([0-9]+(,[0-9]+)?)");

            filteredLines = reader.lines()
                    .filter(line -> pattern.matcher(line).find())
                    .map(line -> {
                        Matcher matcher = extractPattern.matcher(line);
                        if (matcher.find()) {
                            return matcher.group(1);
                        }
                        return null;
                    })
                    .filter(line -> line != null)
                    .collect(Collectors.toList());
        }

        // Print the filtered lines
        filteredLines.forEach(System.out::println);
    }

The compare result in variable diffOutput is total different with the result return by git diff command. Here are the results:

JGit (result 1):

diff --git a/runner.ps1 b/runner.ps1
index ea0402a..09592bf 100644
--- a/runner.ps1
+++ b/runner.ps1
@@ -7,13 +7,13 @@
   | |     __/ |
   |_|    |___/";
 $changed_files = git diff --name-only --diff-filter=ACM $CI_MERGE_REQUEST_DIFF_BASE_SHA HEAD;
-$config_param = $CI_COMMIT_SHA + ";" + $CI_COMMIT_AUTHOR + ";" + $CI_PROJECT_NAME + ";" + $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME + ";" + $CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
+$commit_info = $CI_COMMIT_SHA + ";" + $CI_COMMIT_AUTHOR + ";" + $CI_PROJECT_NAME + ";" + $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME + ";" + $CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
 echo "******************************  Modified files as follows  ******************************";
 foreach ($cFile in $changed_files) {
 echo "    - $cFile";
 }
 echo "begin to java parser ......";
-$result = java -jar "$PARSER" "$changed_files" "$config_param";
+$result = java -jar "$PARSER" "$changed_files" "$commit_info";
 foreach ($info in $result) {
 echo "$info";
 }
@@ -39,6 +39,7 @@
 };
 echo " ";
 echo "-------------------- Checking The Unit Test Case Method --------------------";
+$java_file_mode_ranges = "";
 foreach ($java_file in $java_files) {
 $test_file_tmp = ($java_file -replace 'src/main/','src/test/');
 $test_file = ($test_file_tmp -replace '\.java','Test.java');
@@ -52,7 +53,7 @@
 echo "    -[$java_file]";
 echo "    -[$mod_ranges]";
 echo "    -[$test_file]";
-java -jar "$PARSER" "$java_file" "$mod_ranges" "$test_file" "$config_param";
+java -jar "$PARSER" "$java_file" "$mod_ranges" "$test_file" "$commit_info";
 if ($LASTEXITCODE -ne 0) {
 echo "receive java parser exit code=$LASTEXITCODE";
 echo "Check the unit test method failed, Pipeline check failure!!!";

Git (result 2):

The command is git diff --unified=0 --word-diff=porcelain commitId1 commitId2 runner.ps1

diff --git a/runner.ps1 b/runner.ps1
index ea0402a..09592bf 100644
--- a/runner.ps1
+++ b/runner.ps1
@@ -10 +10 @@ $changed_files = git diff --name-only --diff-filter=ACM $CI_MERGE_REQUEST_DIFF_B
-$config_param
+$commit_info
  = $CI_COMMIT_SHA + ";" + $CI_COMMIT_AUTHOR + ";" + $CI_PROJECT_NAME + ";" + $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME + ";" + $CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
~
@@ -16 +16 @@ echo "begin to java parser ......";
 $result = java -jar "$PARSER" "$changed_files"
-"$config_param";
+"$commit_info";
~
@@ -41,0 +42 @@ echo "-------------------- Checking The Unit Test Case Method ------------------
+$java_file_mode_ranges = "";
~
@@ -55 +56 @@ echo "    -[$test_file]";
 java -jar "$PARSER" "$java_file" "$mod_ranges" "$test_file"
-"$config_param";
+"$commit_info";As

As you can see, changed lines numbers are totally different.

Background:

I'm trying to run a Java application in Gitlab Runner. For some reasons, I don't want to run git diff command in Gitlab Runner, so I use JGit. There are two repositories, one is my local repository and the other is repository created by Girlab Runner, which Java application is able to get. I was thinking maybe I should use local repository at first, but I also tested JGit in local repository, the result is same with result 1. So I doubt it might be using JGit incorrectly. I'm not familiar with JGit and have no idea what's wrong, so please help, Thanks a lot !

Upvotes: 0

Views: 31

Answers (0)

Related Questions