[change-reminder] do not create content revisions while processing commits

This commit adds a method to GitCommit that allows accessing paths affected by this commit directly. When changes in the commit aren't parsed yet, this allows to avoid expensive and unnecessary creation of GitContentRevision instances.

FileHistoryProvider only takes one FilePath from each commit, but since there are no renames, this is equivalent to taking both paths, which is what the new method does.

IDEA-219351

GitOrigin-RevId: 71425add1af27c47d8ae140bd3bd9f06944db8d1
This commit is contained in:
Julia Beliaeva
2019-09-02 20:01:51 +00:00
committed by intellij-monorepo-bot
parent d397d17af8
commit 587734cc55
3 changed files with 53 additions and 7 deletions
@@ -18,10 +18,7 @@ import com.intellij.vcs.log.impl.VcsStatusMerger.MergedStatusInfo;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;
@@ -65,6 +62,11 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme
return myChanges.get().size();
}
@NotNull
protected Changes getChangesObject() {
return myChanges.get();
}
protected interface Changes {
@NotNull
Collection<Change> getMergedChanges();
@@ -179,6 +181,16 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme
private List<MergedStatusInfo<VcsFileStatusInfo>> getMergedStatusInfo() {
return myStatusMerger.merge(myChangesOutput);
}
@ApiStatus.Internal
@NotNull
public Collection<VcsFileStatusInfo> getMergedStatuses() {
Collection<VcsFileStatusInfo> result = new HashSet<>();
for (MergedStatusInfo<VcsFileStatusInfo> mergedStatusInfo : getMergedStatusInfo()) {
result.add(mergedStatusInfo.getStatusInfo());
}
return result;
}
}
private static class MyMergedChange extends MergedChange {
@@ -39,12 +39,12 @@ internal class FilesHistoryProvider(private val project: Project,
val commitsData = mutableSetOf<Commit>()
processCommitsFromHashes(project, root, hashes.keys.toList()) consume@{ commit ->
if (commit.changes.isNotEmpty()) {
val affectedPaths = commit.affectedPaths
if (affectedPaths.isNotEmpty()) {
val id = hashes[commit.id.asString()] ?: return@consume
val time = commit.commitTime
val files = commit.changes.mapNotNull { ChangesUtil.getFilePath(it) }.toSet()
val author = commit.author
commitsData.add(Commit(id, time, author.name, files))
commitsData.add(Commit(id, time, author.name, affectedPaths))
}
}
return commitsData
@@ -16,17 +16,22 @@
package git4idea;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangesUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcs.log.Hash;
import com.intellij.vcs.log.VcsShortCommitDetails;
import com.intellij.vcs.log.VcsUser;
import com.intellij.vcs.log.impl.VcsChangesLazilyParsedDetails;
import com.intellij.vcs.log.impl.VcsFileStatusInfo;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Represents a Git commit with its meta information (hash, author, message, etc.), its parents and the {@link Change changes}.
@@ -43,6 +48,35 @@ public final class GitCommit extends VcsChangesLazilyParsedDetails {
new GitChangesParser());
}
@ApiStatus.Internal
@NotNull
public Set<FilePath> getAffectedPaths() {
Changes changesObject = getChangesObject();
if (changesObject instanceof UnparsedChanges) {
Set<FilePath> result = new HashSet<>();
for (VcsFileStatusInfo statusInfo : ((UnparsedChanges)changesObject).getMergedStatuses()) {
result.add(GitContentRevision.createPath(getRoot(), statusInfo.getFirstPath()));
String secondPath = statusInfo.getSecondPath();
if (secondPath != null) {
result.add(GitContentRevision.createPath(getRoot(), secondPath));
}
}
return result;
}
Set<FilePath> result = new HashSet<>();
for (Change change : getChanges()) {
FilePath beforePath = ChangesUtil.getBeforePath(change);
if (beforePath != null) result.add(beforePath);
FilePath afterPath = ChangesUtil.getAfterPath(change);
if (afterPath != null) result.add(afterPath);
}
return result;
}
private static class GitChangesParser implements ChangesParser {
@Override
public List<Change> parseStatusInfo(@NotNull Project project,