diff --git a/plugins/changeReminder/intellij.vcs.changeReminder.iml b/plugins/changeReminder/intellij.vcs.changeReminder.iml index eb78b7b7f042..e8803fe039f4 100644 --- a/plugins/changeReminder/intellij.vcs.changeReminder.iml +++ b/plugins/changeReminder/intellij.vcs.changeReminder.iml @@ -11,6 +11,7 @@ + diff --git a/plugins/changeReminder/src/com/jetbrains/changeReminder/predict/PredictionService.kt b/plugins/changeReminder/src/com/jetbrains/changeReminder/predict/PredictionService.kt index 5b8500fd1985..c65dc151a17b 100644 --- a/plugins/changeReminder/src/com/jetbrains/changeReminder/predict/PredictionService.kt +++ b/plugins/changeReminder/src/com/jetbrains/changeReminder/predict/PredictionService.kt @@ -100,7 +100,7 @@ class PredictionService(val project: Project, dataManager.addDataPackChangeListener(dataPackChangeListener) dataManager.index.addListener(indexingFinishedListener) - val filesHistoryProvider = dataManager.index.dataGetter?.let { FilesHistoryProvider(project, it) } ?: return + val filesHistoryProvider = dataManager.index.dataGetter?.let { FilesHistoryProvider(project, dataManager, it) } ?: return predictionRequirements = PredictionRequirements(dataManager, filesHistoryProvider) calculatePrediction() } diff --git a/plugins/changeReminder/src/com/jetbrains/changeReminder/repository/FilesHistoryProvider.kt b/plugins/changeReminder/src/com/jetbrains/changeReminder/repository/FilesHistoryProvider.kt index a26b44e4cd43..d1c93f3fba00 100644 --- a/plugins/changeReminder/src/com/jetbrains/changeReminder/repository/FilesHistoryProvider.kt +++ b/plugins/changeReminder/src/com/jetbrains/changeReminder/repository/FilesHistoryProvider.kt @@ -1,18 +1,26 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.jetbrains.changeReminder.repository +import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project import com.intellij.openapi.vcs.FilePath import com.intellij.openapi.vcs.changes.ChangesUtil import com.intellij.openapi.vfs.VirtualFile +import com.intellij.vcs.log.data.VcsLogData import com.intellij.vcs.log.data.index.IndexDataGetter +import com.intellij.vcs.log.graph.impl.facade.PermanentGraphImpl +import com.intellij.vcs.log.graph.utils.DfsWalk +import com.intellij.vcs.log.util.VcsLogUtil import com.intellij.vcs.log.visible.filters.VcsLogFilterObject import com.jetbrains.changeReminder.processCommitsFromHashes import com.jetbrains.changeReminder.retainAll +import gnu.trove.TIntHashSet data class Commit(val id: Int, val time: Long, val author: String, val files: Set) -internal class FilesHistoryProvider(private val project: Project, private val dataGetter: IndexDataGetter) { +internal class FilesHistoryProvider(private val project: Project, + private val dataManager: VcsLogData, + private val dataGetter: IndexDataGetter) { private val filesHistoryCache = HashMap>() private fun getCommitHashesWithFile(file: FilePath): Collection { @@ -42,11 +50,32 @@ internal class FilesHistoryProvider(private val project: Project, private val da return commitsData } + private fun getCommitsFromHead(root: VirtualFile): TIntHashSet { + val dataPack = dataManager.dataPack + val branchName = dataManager.getLogProvider(root).getCurrentBranch(root) ?: return TIntHashSet() + val branchRef = VcsLogUtil.findBranch(dataPack.refsModel, root, branchName) ?: return TIntHashSet() + val branchIndex = dataManager.getCommitIndex(branchRef.commitHash, branchRef.root) + + val permanentGraph = dataPack.permanentGraph as? PermanentGraphImpl ?: return TIntHashSet() + + val branchNodeId = permanentGraph.permanentCommitsInfo.getNodeId(branchIndex) + val commitsFromHead = TIntHashSet() + DfsWalk(listOf(branchNodeId), permanentGraph.linearGraph).walk(true) { + ProgressManager.checkCanceled() + commitsFromHead.add(permanentGraph.permanentCommitsInfo.getCommitId(it)) + true + } + return commitsFromHead + } + fun getFilesHistory(root: VirtualFile, files: Collection): Collection { filesHistoryCache.retainAll(files) - - filesHistoryCache.putAll(files.filter { it !in filesHistoryCache } - .associateWith { getCommitHashesWithFile(it) }) + val commitsFromHead = getCommitsFromHead(root) + filesHistoryCache.putAll(files + .filter { it !in filesHistoryCache } + .associateWith { file -> + getCommitHashesWithFile(file).filter { it in commitsFromHead } + }) val commits = files.mapNotNull { filesHistoryCache[it] }.flatten() return getCommitsData(root, commits)