diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java index b6c730935b39..c0d535539ebc 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java @@ -1065,8 +1065,8 @@ public class GitHistoryUtils { int bodyEnd = line.indexOf(GitLogParser.RECORD_END); if (bodyEnd >= 0) { myIsInsideBody = false; - myOutput.append(line.substring(0, bodyEnd + 1)); - processOutputLine(line.substring(bodyEnd + 1)); + myOutput.append(line.substring(0, bodyEnd + GitLogParser.RECORD_END.length())); + processOutputLine(line.substring(bodyEnd + GitLogParser.RECORD_END.length())); } else { myOutput.append(line).append("\n"); diff --git a/plugins/git4idea/src/git4idea/history/GitLogParser.java b/plugins/git4idea/src/git4idea/history/GitLogParser.java index e345f3599621..388dc07aa08b 100644 --- a/plugins/git4idea/src/git4idea/history/GitLogParser.java +++ b/plugins/git4idea/src/git4idea/history/GitLogParser.java @@ -59,12 +59,12 @@ import java.util.regex.Pattern; public class GitLogParser { // Single records begin with %x01, end with %03. Items of commit information (hash, committer, subject, etc.) are separated by %x02. // each character is declared twice - for Git pattern format and for actual character in the output. - public static final String RECORD_START = "\u0001"; + public static final String RECORD_START = "\u0001\u0001"; public static final String ITEMS_SEPARATOR = "\u0002"; - public static final String RECORD_END = "\u0003"; - public static final String RECORD_START_GIT = "%x01"; + public static final String RECORD_END = "\u0003\u0003"; + public static final String RECORD_START_GIT = "%x01%x01"; private static final String ITEMS_SEPARATOR_GIT = "%x02"; - private static final String RECORD_END_GIT = "%x03"; + private static final String RECORD_END_GIT = "%x03%x03"; private final String myFormat; // pretty custom format generated in the constructor private final GitLogOption[] myOptions; @@ -84,7 +84,7 @@ public class GitLogParser { * 2c815939f45fbcfda9583f84b14fe9d393ada790sample commit * D a.txt */ - private static final Pattern ONE_RECORD = Pattern.compile(RECORD_START + "?(.*)" + RECORD_END + "\n*(.*)", Pattern.DOTALL); + private static final Pattern ONE_RECORD = Pattern.compile("(?:" + RECORD_START + ")?(.*)" + RECORD_END + "\n*(.*)", Pattern.DOTALL); private static final String SINGLE_PATH = "([^\t\r\n]+)"; // something not empty, not a tab or newline. private static final String EOL = "\\s*(?:\r|\n|\r\n)"; private static final String PATHS = diff --git a/plugins/git4idea/tests/git4idea/history/GitLogParserTest.java b/plugins/git4idea/tests/git4idea/history/GitLogParserTest.java index a7fff1280dba..b6c62059a99a 100644 --- a/plugins/git4idea/tests/git4idea/history/GitLogParserTest.java +++ b/plugins/git4idea/tests/git4idea/history/GitLogParserTest.java @@ -152,21 +152,38 @@ public class GitLogParserTest extends GitPlatformTest { } public void test_char_0001_in_commit_message() throws VcsException { - doTestCustomCommitMessage("Commit \u0001subject", "Commit subject"); + doTestCustomCommitMessage("Commit \u0001subject", "Commit \u0001subject"); + } + + public void test_double_char_0001_in_commit_message() throws VcsException { + doTestCustomCommitMessage("Commit \u0001\u0001subject", "Commit subject"); } public void test_char_0003_in_commit_message() throws VcsException { doTestCustomCommitMessage("Commit \u0003subject", "Commit \u0003subject"); } - // this is not fixed, keeping the test for the record and possible future fixx + public void test_double_char_0003_in_commit_message() throws VcsException { + doTestCustomCommitMessage("Commit \u0003\u0003subject", "Commit \u0003\u0003subject"); + } + + public void test_both_chars_0001_and_0003_in_commit_message() throws VcsException { + doTestCustomCommitMessage("Subject \u0001of the \u0003# weirdmessage", "Subject \u0001of the \u0003# weirdmessage"); + } + + // this is not fixed, keeping the test for the record and possible future fix @SuppressWarnings("unused") - public void _test_both_chars_0001_and_0003_in_commit_message() throws VcsException { - doTestCustomCommitMessage("Subject \u0001of the \u0003# weirdmessage", "Subject of the \u0003# weird message"); + public void _test_both_double_chars_0001_and_0003_in_commit_message() throws VcsException { + doTestCustomCommitMessage("Subject \u0001\u0001of the \u0003\u0003# weirdmessage", + "Subject of the \u0003\u0003# weirdmessage"); } public void test_char_0001_twice_in_commit_message() throws VcsException { - doTestCustomCommitMessage("Subject \u0001of the \u0001# weird message", "Subject of the # weird message"); + doTestCustomCommitMessage("Subject \u0001of the \u0001# weird message", "Subject \u0001of the \u0001# weird message"); + } + + public void test_double_char_0001_twice_in_commit_message() throws VcsException { + doTestCustomCommitMessage("Subject \u0001\u0001of the \u0001\u0001# weird message", "Subject of the # weird message"); } public void test_old_refs_format() throws VcsException { @@ -295,7 +312,7 @@ public class GitLogParserTest extends GitPlatformTest { return; default: throw new AssertionError(); - } + } } private String getBeforePath(Change actualChange) { @@ -305,7 +322,7 @@ public class GitLogParserTest extends GitPlatformTest { private String getAfterPath(Change actualChange) { return FileUtil.getRelativePath(new File(myProjectPath), actualChange.getAfterRevision().getFile().getIOFile()); } - + private enum GitTestLogRecordInfo { HASH, COMMIT_TIME, @@ -516,7 +533,7 @@ public class GitLogParserTest extends GitPlatformTest { } } - + private static class GitTestChange { final Change.Type myType; final String myBeforePath; @@ -543,7 +560,7 @@ public class GitLogParserTest extends GitPlatformTest { static GitTestChange moved(String before, String after) { return new GitTestChange(Change.Type.MOVED, before, after); } - + String toOutputString() { switch (myType) { case MOVED: return outputString("R100", myBeforePath, myAfterPath); @@ -568,5 +585,4 @@ public class GitLogParserTest extends GitPlatformTest { return sb.toString(); } } - }