From 587734cc55af90da08b131ae3033bb93b785925d Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Sun, 1 Sep 2019 00:14:44 +0300 Subject: [PATCH] [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 --- .../impl/VcsChangesLazilyParsedDetails.java | 20 ++++++++--- .../repository/FilesHistoryProvider.kt | 6 ++-- plugins/git4idea/src/git4idea/GitCommit.java | 34 +++++++++++++++++++ 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java index 7b1b18ae4fb4..ca9dbfd7df24 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java @@ -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 getMergedChanges(); @@ -179,6 +181,16 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme private List> getMergedStatusInfo() { return myStatusMerger.merge(myChangesOutput); } + + @ApiStatus.Internal + @NotNull + public Collection getMergedStatuses() { + Collection result = new HashSet<>(); + for (MergedStatusInfo mergedStatusInfo : getMergedStatusInfo()) { + result.add(mergedStatusInfo.getStatusInfo()); + } + return result; + } } private static class MyMergedChange extends MergedChange { diff --git a/plugins/changeReminder/src/com/jetbrains/changeReminder/repository/FilesHistoryProvider.kt b/plugins/changeReminder/src/com/jetbrains/changeReminder/repository/FilesHistoryProvider.kt index d1c93f3fba00..212193aed0b2 100644 --- a/plugins/changeReminder/src/com/jetbrains/changeReminder/repository/FilesHistoryProvider.kt +++ b/plugins/changeReminder/src/com/jetbrains/changeReminder/repository/FilesHistoryProvider.kt @@ -39,12 +39,12 @@ internal class FilesHistoryProvider(private val project: Project, val commitsData = mutableSetOf() 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 diff --git a/plugins/git4idea/src/git4idea/GitCommit.java b/plugins/git4idea/src/git4idea/GitCommit.java index f02bd7e2b932..b0c321726088 100644 --- a/plugins/git4idea/src/git4idea/GitCommit.java +++ b/plugins/git4idea/src/git4idea/GitCommit.java @@ -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 getAffectedPaths() { + Changes changesObject = getChangesObject(); + if (changesObject instanceof UnparsedChanges) { + Set 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 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 parseStatusInfo(@NotNull Project project,