[git] fix parsing commits with \u0001 symbol in commit message
authorJulia Beliaeva <Julia.Beliaeva@jetbrains.com>
Sun, 16 Oct 2016 22:58:27 +0000 (01:58 +0300)
committerJulia Beliaeva <Julia.Beliaeva@jetbrains.com>
Thu, 27 Oct 2016 21:12:47 +0000 (00:12 +0300)
In order to separate a commit record, find "record end" symbol first. After this, find the beginning of the next record ("record start" symbol). This helps with commit messages containing "record start" (\u0001 used for that), since "record start" in the message is not treated now as a beginning of a new record.

This fixes EA-90019.

plugins/git4idea/src/git4idea/history/GitHistoryUtils.java

index c65399c8e1858d7e5ca4f099a7b27b16d4d9d04f..118cc1d54aa86ac73d4914c2a151efcc8a21ae16 100644 (file)
@@ -538,23 +538,46 @@ public class GitHistoryUtils {
                                                  int bufferSize)
     throws VcsException {
     final StringBuilder buffer = new StringBuilder();
+    final Ref<Boolean> foundRecordEnd = Ref.create(false);
     final Ref<VcsException> ex = new Ref<>();
     final AtomicInteger records = new AtomicInteger();
     handler.addLineListener(new GitLineHandlerListener() {
       @Override
       public void onLineAvailable(String line, Key outputType) {
         try {
+          // format of the record is <RECORD_START>.*<RECORD_END>.*
+          // then next record goes
+          // (rather inconveniently, after RECORD_END there is a list of modified files)
+          // so here I'm trying to find text between two RECORD_START symbols
+          // that simultaneously contains a RECORD_END
+          // this helps to deal with commits like a929478f6720ac15d949117188cd6798b4a9c286 in linux repo that have RECORD_START symbols in the message
+          // wont help with RECORD_END symbols in the message however (have not seen those yet)
+
           String tail = null;
-          int nextRecordStart = line.indexOf(GitLogParser.RECORD_START);
-          if (nextRecordStart == -1) {
-            buffer.append(line).append("\n");
-          }
-          else if (nextRecordStart == 0) {
-            tail = line + "\n";
+          if (!foundRecordEnd.get()) {
+            int recordEnd = line.indexOf(GitLogParser.RECORD_END);
+            if (recordEnd != -1) {
+              foundRecordEnd.set(true);
+              buffer.append(line.substring(0, recordEnd + 1));
+              line = line.substring(recordEnd + 1);
+            }
+            else {
+              buffer.append(line).append("\n");
+            }
           }
-          else {
-            buffer.append(line.substring(0, nextRecordStart));
-            tail = line.substring(nextRecordStart) + "\n";
+
+          if (foundRecordEnd.get()) {
+            int nextRecordStart = line.indexOf(GitLogParser.RECORD_START);
+            if (nextRecordStart == -1) {
+              buffer.append(line).append("\n");
+            }
+            else if (nextRecordStart == 0) {
+              tail = line + "\n";
+            }
+            else {
+              buffer.append(line.substring(0, nextRecordStart));
+              tail = line.substring(nextRecordStart) + "\n";
+            }
           }
 
           if (tail != null) {
@@ -563,6 +586,7 @@ public class GitHistoryUtils {
               buffer.setLength(0);
             }
             buffer.append(tail);
+            foundRecordEnd.set(false);
           }
         }
         catch (Exception e) {