IDEA-184779 git: load commit message for annotations from log if available

This commit is contained in:
Aleksey Pivovarov
2018-06-24 16:24:19 +03:00
parent 72ec344b57
commit 126f5dc2e9
2 changed files with 53 additions and 14 deletions
@@ -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<GitRevisionNumber> 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<VcsFileRevision> 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;
}
@@ -52,6 +52,7 @@ public class GitFileAnnotation extends FileAnnotation {
@NotNull private final List<LineInfo> myLines;
@Nullable private List<VcsFileRevision> myRevisions;
@Nullable private TObjectIntHashMap<VcsRevisionNumber> myRevisionMap;
@NotNull private final Map<VcsRevisionNumber, String> 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) {