diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java index 118cc1d54aa8..39c24c130ec0 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java @@ -15,6 +15,7 @@ */ package git4idea.history; +import com.intellij.execution.process.ProcessOutputTypes; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -55,6 +56,7 @@ import git4idea.history.browser.SHAHash; import git4idea.history.browser.SymbolicRefs; import git4idea.history.browser.SymbolicRefsI; import git4idea.history.wholeTree.AbstractHash; +import git4idea.i18n.GitBundle; import git4idea.log.GitLogProvider; import git4idea.log.GitRefManager; import org.jetbrains.annotations.NotNull; @@ -537,70 +539,85 @@ public class GitHistoryUtils { @NotNull Consumer recordConsumer, int bufferSize) throws VcsException { - final StringBuilder buffer = new StringBuilder(); + final StringBuilder output = new StringBuilder(); + final StringBuilder errors = new StringBuilder(); final Ref foundRecordEnd = Ref.create(false); final Ref 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 .*.* - // 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; - 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"); - } - } - - 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) { - if (records.incrementAndGet() > bufferSize) { - recordConsumer.consume(buffer); - buffer.setLength(0); - } - buffer.append(tail); - foundRecordEnd.set(false); - } + if (outputType == ProcessOutputTypes.STDERR) { + errors.append(line).append("\n"); } - catch (Exception e) { - ex.set(new VcsException(e)); + else if (outputType == ProcessOutputTypes.STDOUT) { + try { + // format of the record is .*.* + // 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; + if (!foundRecordEnd.get()) { + int recordEnd = line.indexOf(GitLogParser.RECORD_END); + if (recordEnd != -1) { + foundRecordEnd.set(true); + output.append(line.substring(0, recordEnd + 1)); + line = line.substring(recordEnd + 1); + } + else { + output.append(line).append("\n"); + } + } + + if (foundRecordEnd.get()) { + int nextRecordStart = line.indexOf(GitLogParser.RECORD_START); + if (nextRecordStart == -1) { + output.append(line).append("\n"); + } + else if (nextRecordStart == 0) { + tail = line + "\n"; + } + else { + output.append(line.substring(0, nextRecordStart)); + tail = line.substring(nextRecordStart) + "\n"; + } + } + + if (tail != null) { + if (records.incrementAndGet() > bufferSize) { + recordConsumer.consume(output); + output.setLength(0); + } + output.append(tail); + foundRecordEnd.set(false); + } + } + catch (Exception e) { + ex.set(new VcsException(e)); + } } } @Override public void processTerminated(int exitCode) { - try { - recordConsumer.consume(buffer); + if (exitCode != 0) { + String errorMessage = errors.toString(); + if (errorMessage.isEmpty()) { + errorMessage = GitBundle.message("git.error.exit", exitCode); + } + ex.set(new VcsException(errorMessage)); } - catch (Exception e) { - ex.set(new VcsException(e)); + else { + try { + recordConsumer.consume(output); + } + catch (Exception e) { + ex.set(new VcsException(e)); + } } }