diff --git a/plugins/git4idea/src/git4idea/annotate/GitAnnotationProvider.java b/plugins/git4idea/src/git4idea/annotate/GitAnnotationProvider.java index 8ff787b1bd74..35cbb67dc441 100644 --- a/plugins/git4idea/src/git4idea/annotate/GitAnnotationProvider.java +++ b/plugins/git4idea/src/git4idea/annotate/GitAnnotationProvider.java @@ -38,6 +38,11 @@ import com.intellij.util.containers.Interner; import com.intellij.vcs.AnnotationProviderEx; import com.intellij.vcs.log.VcsUser; import com.intellij.vcs.log.VcsUserRegistry; +import com.intellij.vcs.log.data.VcsLogData; +import com.intellij.vcs.log.data.index.IndexDataGetter; +import com.intellij.vcs.log.impl.HashImpl; +import com.intellij.vcs.log.impl.VcsLogManager; +import com.intellij.vcs.log.impl.VcsProjectLog; import com.intellij.vcsUtil.VcsUtil; import git4idea.GitFileRevision; import git4idea.GitRevisionNumber; @@ -58,10 +63,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; +import java.util.*; public class GitAnnotationProvider implements AnnotationProviderEx { private final Project myProject; @@ -136,7 +138,7 @@ public class GitAnnotationProvider implements AnnotationProviderEx { if (actualRevision != null) { Object annotatedData = myCache.getAnnotation(repositoryFilePath, GitVcs.getKey(), actualRevision); - if (annotatedData instanceof CachedData) return restoreFromCache(file, actualRevision, (CachedData)annotatedData); + if (annotatedData instanceof CachedData) return restoreFromCache(repositoryFilePath, file, actualRevision, (CachedData)annotatedData); } GitFileAnnotation fileAnnotation = doAnnotate(repositoryFilePath, actualRevision, file); @@ -185,9 +187,31 @@ public class GitAnnotationProvider implements AnnotationProviderEx { loadFileHistoryInBackground(fileAnnotation); + loadCommitMessagesFromLog(root, fileAnnotation); + return fileAnnotation; } + private void loadCommitMessagesFromLog(@NotNull VirtualFile root, @NotNull GitFileAnnotation annotation) { + VcsLogManager logManager = VcsProjectLog.getInstance(myProject).getLogManager(); + if (logManager == null) return; + + VcsLogData dataManager = logManager.getDataManager(); + IndexDataGetter getter = dataManager.getIndex().getDataGetter(); + if (getter == null) return; + + Set revisions = ContainerUtil.map2Set(annotation.getLines(), it -> it.getRevisionNumber()); + for (GitRevisionNumber revision: revisions) { + if (annotation.getCommitMessage(revision) == null) { + int commitIndex = dataManager.getCommitIndex(HashImpl.build(revision.asString()), root); + String commitMessage = getter.getFullMessage(commitIndex); + if (commitMessage != null) { + annotation.setCommitMessage(revision, commitMessage); + } + } + } + } + private void loadFileHistoryInBackground(@NotNull GitFileAnnotation fileAnnotation) { List fileRevisions = BackgroundTaskUtil.computeInBackgroundAndTryWait( () -> { @@ -352,13 +376,17 @@ public class GitAnnotationProvider implements AnnotationProviderEx { } @NotNull - private GitFileAnnotation restoreFromCache(@NotNull VirtualFile file, + private GitFileAnnotation restoreFromCache(@NotNull FilePath repositoryFilePath, + @NotNull VirtualFile file, @Nullable VcsRevisionNumber revisionNumber, - @NotNull CachedData data) { + @NotNull CachedData data) throws VcsException { + VirtualFile root = GitUtil.getGitRoot(repositoryFilePath); GitFileAnnotation fileAnnotation = new GitFileAnnotation(myProject, file, revisionNumber, data.lines); loadFileHistoryInBackground(fileAnnotation); + loadCommitMessagesFromLog(root, fileAnnotation); + return fileAnnotation; } diff --git a/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java b/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java index d7601c86c9a0..d4f2bebdfb74 100644 --- a/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java +++ b/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java @@ -52,6 +52,7 @@ public class GitFileAnnotation extends FileAnnotation { @NotNull private final List myLines; @Nullable private List myRevisions; @Nullable private TObjectIntHashMap myRevisionMap; + @NotNull private final Map myCommitMessageMap = new HashMap<>(); private final LineAnnotationAspect DATE_ASPECT = new GitAnnotationAspect(LineAnnotationAspect.DATE, true) { @Override @@ -125,6 +126,10 @@ public class GitFileAnnotation extends FileAnnotation { } } + public void setCommitMessage(@NotNull VcsRevisionNumber revisionNumber, @NotNull String message) { + myCommitMessageMap.put(revisionNumber, message); + } + @Override public int getLineCount() { return myLines.size(); @@ -144,18 +149,14 @@ public class GitFileAnnotation extends FileAnnotation { GitRevisionNumber revisionNumber = lineInfo.getRevisionNumber(); - VcsFileRevision fileRevision = null; - if (myRevisions != null && myRevisionMap != null && - myRevisionMap.contains(revisionNumber)) { - fileRevision = myRevisions.get(myRevisionMap.get(revisionNumber)); - } - String path = null; if (!VcsUtil.getFilePath(myFile).equals(lineInfo.myFilePath)) { path = FileUtil.getLocationRelativeToUserHome(lineInfo.myFilePath.getPresentableUrl()); } - String commitMessage = fileRevision != null ? fileRevision.getCommitMessage() : lineInfo.getSubject() + "\n..."; + String commitMessage = getCommitMessage(revisionNumber); + if (commitMessage == null) commitMessage = lineInfo.getSubject() + "\n..."; + return "commit " + revisionNumber.asString() + "\nAuthor: " + lineInfo.getAuthor() + "\nDate: " + DateFormatUtil.formatDateTime(lineInfo.getAuthorDate()) + @@ -163,6 +164,16 @@ public class GitFileAnnotation extends FileAnnotation { "\n\n" + commitMessage; } + @Nullable + public String getCommitMessage(@NotNull VcsRevisionNumber revisionNumber) { + if (myRevisions != null && myRevisionMap != null && + myRevisionMap.contains(revisionNumber)) { + VcsFileRevision fileRevision = myRevisions.get(myRevisionMap.get(revisionNumber)); + return fileRevision.getCommitMessage(); + } + return myCommitMessageMap.get(revisionNumber); + } + @Nullable @Override public VcsRevisionNumber getLineRevisionNumber(int lineNumber) {