git: fix "annotate previous revision" for renamed files

In some cases (ex: when a file was split into two files), `git log` might detect more renames than `git blame`.

In this case we will fallback to the old history-based approach.
This might be not particulary right (ex: in tricky cases with multiple renames in multiple branches), but works good enough in general.
This commit is contained in:
Aleksey Pivovarov
2016-09-06 15:21:41 +03:00
parent c7c745c197
commit e13e5a7d43
@@ -38,6 +38,7 @@ import git4idea.GitFileRevision;
import git4idea.GitRevisionNumber;
import git4idea.GitVcs;
import git4idea.i18n.GitBundle;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,6 +52,7 @@ public class GitFileAnnotation extends FileAnnotation {
@NotNull private final List<LineInfo> myLines;
@Nullable private List<VcsFileRevision> myRevisions;
@Nullable private TObjectIntHashMap<VcsRevisionNumber> myRevisionMap;
private final LineAnnotationAspect DATE_ASPECT = new GitAnnotationAspect(LineAnnotationAspect.DATE, true) {
@Override
@@ -113,6 +115,11 @@ public class GitFileAnnotation extends FileAnnotation {
public void setRevisions(@NotNull List<VcsFileRevision> revisions) {
myRevisions = revisions;
myRevisionMap = new TObjectIntHashMap<>();
for (int i = 0; i < myRevisions.size(); i++) {
myRevisionMap.put(myRevisions.get(i).getRevisionNumber(), i);
}
}
@Override
@@ -292,7 +299,21 @@ public class GitFileAnnotation extends FileAnnotation {
@Override
public VcsFileRevision getPreviousRevision(int lineNumber) {
LineInfo lineInfo = getLineInfo(lineNumber);
return lineInfo != null ? lineInfo.getPreviousFileRevision() : null;
if (lineInfo == null) return null;
VcsFileRevision previousFileRevision = lineInfo.getPreviousFileRevision();
if (previousFileRevision != null) return previousFileRevision;
GitRevisionNumber revisionNumber = lineInfo.getRevisionNumber();
if (myRevisions != null && myRevisionMap != null &&
myRevisionMap.contains(revisionNumber)) {
int index = myRevisionMap.get(revisionNumber);
if (index + 1 < myRevisions.size()) {
return myRevisions.get(index + 1);
}
}
return null;
}
@Nullable