From f91cb12fa277a6e2519b2852abf78affa2a179bf Mon Sep 17 00:00:00 2001 From: Stanislau Palyn Date: Wed, 4 Feb 2026 16:30:11 +0100 Subject: [PATCH] refactor [git]: Extract getEntriesUsingLog from GitInteractiveRebaseUsingLog.kt into separate service GitOrigin-RevId: df72990b28749d34ae4bfb5097e08cb9f5a0974e --- .../src/git4idea/GitOperationsCollector.kt | 8 +- .../rebase/log/InMemoryRebaseOperations.kt | 5 +- .../GitInteractiveRebaseUsingLog.kt | 109 +--------------- .../GitInteractiveRebaseEntriesProvider.kt | 120 ++++++++++++++++++ ...GitInMemoryInteractiveRebaseProcessTest.kt | 40 +++--- .../GitInteractiveRebaseUsingLogTest.kt | 26 ++-- 6 files changed, 175 insertions(+), 133 deletions(-) create mode 100644 plugins/git4idea/src/git4idea/rebase/log/GitInteractiveRebaseEntriesProvider.kt diff --git a/plugins/git4idea/src/git4idea/GitOperationsCollector.kt b/plugins/git4idea/src/git4idea/GitOperationsCollector.kt index fdde4c9dd24d..e961bfcf89c2 100644 --- a/plugins/git4idea/src/git4idea/GitOperationsCollector.kt +++ b/plugins/git4idea/src/git4idea/GitOperationsCollector.kt @@ -17,13 +17,13 @@ import git4idea.push.GitPushRepoResult import git4idea.push.GitPushTargetType import git4idea.rebase.GitRebaseEntry import git4idea.rebase.GitRebaseOption -import git4idea.rebase.interactive.CantRebaseUsingLogException +import git4idea.rebase.log.GetEntriesUsingLogResult import git4idea.repo.GitRepository internal object GitOperationsCollector : CounterUsagesCollector() { override fun getGroup(): EventLogGroup = GROUP - private val GROUP: EventLogGroup = EventLogGroup(id = "git.operations", version = 9) + private val GROUP: EventLogGroup = EventLogGroup(id = "git.operations", version = 10) internal val UPDATE_FORCE_PUSHED_BRANCH_ACTIVITY = GROUP.registerIdeActivity("update.force.pushed") @@ -58,7 +58,7 @@ internal object GitOperationsCollector : CounterUsagesCollector() { finishEventAdditionalFields = arrayOf( IN_MEMORY_REBASE_RESULT)) - private val CANT_REBASE_USING_LOG_REASON = EventFields.Enum("cant_rebase_using_log_reason") + private val CANT_REBASE_USING_LOG_REASON = EventFields.Enum("cant_rebase_using_log_reason") private val CANT_REBASE_USING_LOG_EVENT = GROUP.registerEvent("cant.rebase.using.log", CANT_REBASE_USING_LOG_REASON) @@ -131,7 +131,7 @@ internal object GitOperationsCollector : CounterUsagesCollector() { } } - fun logCantRebaseUsingLog(project: Project, reason: CantRebaseUsingLogException.Reason) { + fun logCantRebaseUsingLog(project: Project, reason: GetEntriesUsingLogResult.FailureReason) { CANT_REBASE_USING_LOG_EVENT.log(project, reason) } diff --git a/plugins/git4idea/src/git4idea/inMemory/rebase/log/InMemoryRebaseOperations.kt b/plugins/git4idea/src/git4idea/inMemory/rebase/log/InMemoryRebaseOperations.kt index e304bfd9198f..d9221486dc2e 100644 --- a/plugins/git4idea/src/git4idea/inMemory/rebase/log/InMemoryRebaseOperations.kt +++ b/plugins/git4idea/src/git4idea/inMemory/rebase/log/InMemoryRebaseOperations.kt @@ -1,6 +1,7 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package git4idea.inMemory.rebase.log +import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.logger import com.intellij.vcs.log.VcsCommitMetadata import com.intellij.vcs.log.data.VcsLogData @@ -9,8 +10,8 @@ import git4idea.inMemory.rebase.performInMemoryRebase import git4idea.rebase.GitRebaseEntry import git4idea.rebase.interactive.GitRebaseTodoModel import git4idea.rebase.interactive.convertToModel -import git4idea.rebase.interactive.tryGetEntriesUsingLog import git4idea.rebase.log.GitCommitEditingOperationResult +import git4idea.rebase.log.GitInteractiveRebaseEntriesProvider import git4idea.rebase.log.indicesByPredicate import git4idea.repo.GitRepository @@ -53,7 +54,7 @@ internal object InMemoryRebaseOperations { val generatedEntries = when (entriesSource) { is RebaseEntriesSource.Entries -> entriesSource.entries is RebaseEntriesSource.LogData -> { - tryGetEntriesUsingLog(repository, commits.last(), entriesSource.logData) + repository.project.service().tryGetEntriesUsingLog(repository, commits.last(), entriesSource.logData) } } ?: return GitCommitEditingOperationResult.Incomplete diff --git a/plugins/git4idea/src/git4idea/rebase/interactive/GitInteractiveRebaseUsingLog.kt b/plugins/git4idea/src/git4idea/rebase/interactive/GitInteractiveRebaseUsingLog.kt index b31a5259f48b..7858079114cf 100644 --- a/plugins/git4idea/src/git4idea/rebase/interactive/GitInteractiveRebaseUsingLog.kt +++ b/plugins/git4idea/src/git4idea/rebase/interactive/GitInteractiveRebaseUsingLog.kt @@ -1,29 +1,20 @@ // Copyright 2000-2020 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 git4idea.rebase.interactive -import com.google.common.annotations.VisibleForTesting import com.intellij.openapi.application.EDT +import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.progress.coroutineToIndicator -import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.registry.Registry -import com.intellij.openapi.util.use -import com.intellij.openapi.vcs.VcsException import com.intellij.platform.ide.progress.withBackgroundProgress import com.intellij.vcs.log.Hash import com.intellij.vcs.log.VcsCommitMetadata import com.intellij.vcs.log.VcsShortCommitDetails import com.intellij.vcs.log.data.VcsLogData -import com.intellij.vcs.log.impl.VcsProjectLog -import com.intellij.vcs.log.util.VcsLogUtil import git4idea.DialogManager import git4idea.GitOperationsCollector -import git4idea.GitOperationsCollector.logCantRebaseUsingLog import git4idea.GitOperationsCollector.logRebaseStartUsingLog import git4idea.branch.GitRebaseParams -import git4idea.config.GitConfigUtil.isRebaseUpdateRefsEnabledCached -import git4idea.history.GitHistoryTraverser -import git4idea.history.GitHistoryTraverserImpl import git4idea.i18n.GitBundle import git4idea.inMemory.GitObjectRepository import git4idea.inMemory.objects.GitObject @@ -32,84 +23,18 @@ import git4idea.inMemory.rebase.performInMemoryRebase import git4idea.rebase.GitInteractiveRebaseEditorHandler import git4idea.rebase.GitRebaseEditorHandler import git4idea.rebase.GitRebaseEntry -import git4idea.rebase.GitRebaseEntryWithDetails import git4idea.rebase.GitRebaseUtils -import git4idea.rebase.GitSquashedCommitsMessage import git4idea.rebase.interactive.dialog.GitInteractiveRebaseDialog import git4idea.rebase.log.GitCommitEditingOperationResult +import git4idea.rebase.log.GitInteractiveRebaseEntriesProvider +import git4idea.rebase.log.GitRebaseEntryGeneratedUsingLog import git4idea.repo.GitRepository +import com.intellij.openapi.vcs.VcsException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext private val LOG = Logger.getInstance("Git.Interactive.Rebase.Using.Log") -@VisibleForTesting -@Throws(CantRebaseUsingLogException::class) -internal fun getEntriesUsingLog( - repository: GitRepository, - commit: VcsShortCommitDetails, - logData: VcsLogData, -): List { - Disposer.newDisposable().use { parentDisposable -> - val traverser: GitHistoryTraverser = GitHistoryTraverserImpl(repository.project, logData, parentDisposable) - val details = mutableListOf() - try { - traverser.traverse(repository.root) { (commitId, parents) -> - // commit is not merge - if (parents.size <= 1) { - loadMetadataLater(commitId) { metadata -> - details.add(metadata) - } - val hash = traverser.toHash(commitId) - hash != commit.id - } - else { - throw CantRebaseUsingLogException(CantRebaseUsingLogException.Reason.MERGE) - } - } - } - catch (_: VcsException) { - throw CantRebaseUsingLogException(CantRebaseUsingLogException.Reason.UNRESOLVED_HASH) - } - - if (details.last().id != commit.id) { - throw CantRebaseUsingLogException(CantRebaseUsingLogException.Reason.UNEXPECTED_HASH) - } - - if (details.any { detail -> GitSquashedCommitsMessage.isAutosquashCommitMessage(detail.subject) }) { - throw CantRebaseUsingLogException(CantRebaseUsingLogException.Reason.FIXUP_SQUASH) - } - - if (isRebaseUpdateRefsEnabledCached(repository.project, repository.root)) { - throw CantRebaseUsingLogException(CantRebaseUsingLogException.Reason.UPDATE_REFS) - } - - return details.map { GitRebaseEntryGeneratedUsingLog(it) }.reversed() - } -} - -internal suspend fun tryGetEntriesUsingLog( - repository: GitRepository, - commit: VcsCommitMetadata, - logData: VcsLogData? = null, -): List? { - val generatedEntries = try { - withBackgroundProgress(repository.project, GitBundle.message("rebase.progress.indicator.preparing.title")) { - val logData = logData ?: VcsProjectLog.awaitLogIsReady(repository.project)?.dataManager ?: run { - LOG.warn("Couldn't use log for rebasing - log not available") - return@withBackgroundProgress null - } - getEntriesUsingLog(repository, commit, logData) - } - } - catch (e: CantRebaseUsingLogException) { - LOG.warn("Couldn't use log for rebasing: ${e.message}") - logCantRebaseUsingLog(repository.project, e.reason) - null - } - return generatedEntries -} - /** * The process: * 1. Generate rebase entries from VCS log data @@ -120,11 +45,12 @@ internal suspend fun tryGetEntriesUsingLog( * * If log-based entry generation fails, falls back to traditional Git interactive rebase that gets entries from the editor. */ -internal suspend fun interactivelyRebaseUsingLog(repository: GitRepository, commit: VcsCommitMetadata, logData: VcsLogData? = null) { +internal suspend fun interactivelyRebaseUsingLog(repository: GitRepository, commit: VcsCommitMetadata, logData: VcsLogData) { val project = repository.project val root = repository.root - val generatedEntries = tryGetEntriesUsingLog(repository, commit, logData) + val generatedEntries = repository.project.service() + .tryGetEntriesUsingLog(repository, commit, logData) if (generatedEntries == null) { startInteractiveRebase(repository, commit) return @@ -252,24 +178,3 @@ private class GitInteractiveRebaseUsingLogEditorHandler( private fun List.toLog(): String = joinToString(", ", prefix = "[", postfix = "]") { "${it.commit} (${it.action.command})" } } - -internal class CantRebaseUsingLogException(val reason: Reason) : Exception(reason.toString()) { - enum class Reason { - MERGE, - FIXUP_SQUASH, - UNEXPECTED_HASH, - UNRESOLVED_HASH, - UPDATE_REFS // should generate an update-ref entry in the editor, which is not supported when using log - } -} - -@VisibleForTesting -internal class GitRebaseEntryGeneratedUsingLog(details: VcsCommitMetadata) : - GitRebaseEntryWithDetails(GitRebaseEntry(Action.PICK, details.id.asString(), details.subject.trimStart()), details) { - - fun equalsWithReal(realEntry: GitRebaseEntry) = - if (VcsLogUtil.HASH_PREFIX_REGEX.matcher(realEntry.commit).matches()) { - action == realEntry.action && (commit.startsWith(realEntry.commit) || realEntry.commit.startsWith(commit)) - } - else false -} \ No newline at end of file diff --git a/plugins/git4idea/src/git4idea/rebase/log/GitInteractiveRebaseEntriesProvider.kt b/plugins/git4idea/src/git4idea/rebase/log/GitInteractiveRebaseEntriesProvider.kt new file mode 100644 index 000000000000..fa00191fe9d9 --- /dev/null +++ b/plugins/git4idea/src/git4idea/rebase/log/GitInteractiveRebaseEntriesProvider.kt @@ -0,0 +1,120 @@ +// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package git4idea.rebase.log + +import com.intellij.openapi.components.Service +import com.intellij.openapi.diagnostic.thisLogger +import com.intellij.openapi.vcs.VcsException +import com.intellij.platform.ide.progress.withBackgroundProgress +import com.intellij.util.asDisposable +import com.intellij.vcs.log.VcsCommitMetadata +import com.intellij.vcs.log.VcsShortCommitDetails +import com.intellij.vcs.log.data.VcsLogData +import com.intellij.vcs.log.impl.VcsProjectLog +import com.intellij.vcs.log.util.VcsLogUtil +import git4idea.GitOperationsCollector.logCantRebaseUsingLog +import git4idea.config.GitConfigUtil.isRebaseUpdateRefsEnabledCached +import git4idea.history.GitHistoryTraverser +import git4idea.history.GitHistoryTraverserImpl +import git4idea.i18n.GitBundle +import git4idea.rebase.GitRebaseEntry +import git4idea.rebase.GitRebaseEntryWithDetails +import git4idea.rebase.GitSquashedCommitsMessage +import git4idea.repo.GitRepository +import kotlinx.coroutines.coroutineScope +import org.jetbrains.annotations.VisibleForTesting + +@Service(Service.Level.PROJECT) +internal class GitInteractiveRebaseEntriesProvider { + suspend fun tryGetEntriesUsingLog( + repository: GitRepository, + commit: VcsCommitMetadata, + logData: VcsLogData? = null, + ): List? { + return withBackgroundProgress(repository.project, GitBundle.message("rebase.progress.indicator.preparing.title")) { + val logData = logData ?: VcsProjectLog.awaitLogIsReady(repository.project)?.dataManager ?: run { + LOG.warn("Couldn't use log for rebasing - log not available") + return@withBackgroundProgress null + } + + val result = getEntriesUsingLog(repository, commit, logData) + + when (result) { + is GetEntriesUsingLogResult.Success -> result.entries + is GetEntriesUsingLogResult.Failure -> { + LOG.warn("Couldn't use log for rebasing: ${result.reason}") + logCantRebaseUsingLog(repository.project, result.reason) + null + } + } + } + } + + @VisibleForTesting + suspend fun getEntriesUsingLog( + repository: GitRepository, + commit: VcsShortCommitDetails, + logData: VcsLogData, + ): GetEntriesUsingLogResult = + coroutineScope { + val traverser: GitHistoryTraverser = GitHistoryTraverserImpl(repository.project, logData, this.asDisposable()) + val details = mutableListOf() + try { + traverser.traverse(repository.root) { (commitId, parents) -> + loadMetadataLater(commitId) { metadata -> + details.add(metadata) + } + + val hash = traverser.toHash(commitId) + parents.size <= 1 && hash != commit.id // stop when we reach merge commit or target commit + } + } + catch (_: VcsException) { + return@coroutineScope GetEntriesUsingLogResult.Failure(GetEntriesUsingLogResult.FailureReason.UNRESOLVED_HASH) + } + + if (details.last().parents.size > 1) { + return@coroutineScope GetEntriesUsingLogResult.Failure(GetEntriesUsingLogResult.FailureReason.MERGE) + } + + if (details.last().id != commit.id) { + return@coroutineScope GetEntriesUsingLogResult.Failure(GetEntriesUsingLogResult.FailureReason.UNEXPECTED_HASH) + } + + if (details.any { detail -> GitSquashedCommitsMessage.isAutosquashCommitMessage(detail.subject) }) { + return@coroutineScope GetEntriesUsingLogResult.Failure(GetEntriesUsingLogResult.FailureReason.FIXUP_SQUASH) + } + + if (isRebaseUpdateRefsEnabledCached(repository.project, repository.root)) { + return@coroutineScope GetEntriesUsingLogResult.Failure(GetEntriesUsingLogResult.FailureReason.UPDATE_REFS) + } + + return@coroutineScope GetEntriesUsingLogResult.Success(details.map { GitRebaseEntryGeneratedUsingLog(it) }.reversed()) + } + + companion object { + private val LOG = thisLogger() + } +} + +internal sealed interface GetEntriesUsingLogResult { + data class Success(val entries: List) : GetEntriesUsingLogResult + data class Failure(val reason: FailureReason) : GetEntriesUsingLogResult + + enum class FailureReason { + MERGE, + FIXUP_SQUASH, + UNEXPECTED_HASH, + UNRESOLVED_HASH, + UPDATE_REFS // should generate an update-ref entry in the editor, which is not supported when using log + } +} + +internal class GitRebaseEntryGeneratedUsingLog(details: VcsCommitMetadata) : + GitRebaseEntryWithDetails(GitRebaseEntry(Action.PICK, details.id.asString(), details.subject.trimStart()), details) { + + fun equalsWithReal(realEntry: GitRebaseEntry) = + if (VcsLogUtil.HASH_PREFIX_REGEX.matcher(realEntry.commit).matches()) { + action == realEntry.action && (commit.startsWith(realEntry.commit) || realEntry.commit.startsWith(commit)) + } + else false +} diff --git a/plugins/git4idea/tests/git4idea/inMemory/rebase/GitInMemoryInteractiveRebaseProcessTest.kt b/plugins/git4idea/tests/git4idea/inMemory/rebase/GitInMemoryInteractiveRebaseProcessTest.kt index d86a89fa58a7..e6e5528140fa 100644 --- a/plugins/git4idea/tests/git4idea/inMemory/rebase/GitInMemoryInteractiveRebaseProcessTest.kt +++ b/plugins/git4idea/tests/git4idea/inMemory/rebase/GitInMemoryInteractiveRebaseProcessTest.kt @@ -1,6 +1,8 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package git4idea.inMemory.rebase +import com.intellij.openapi.components.service +import com.intellij.vcs.log.VcsFullCommitDetails import com.intellij.vcs.log.data.VcsLogData import git4idea.GitDisposable import git4idea.inMemory.MergeConflictException @@ -8,14 +10,17 @@ import git4idea.inMemory.rebase.log.GitInMemoryOperationTest import git4idea.log.createLogDataIn import git4idea.log.refreshAndWait import git4idea.rebase.interactive.convertToModel -import git4idea.rebase.interactive.getEntriesUsingLog +import git4idea.rebase.log.GetEntriesUsingLogResult import git4idea.rebase.log.GitCommitEditingOperationResult +import git4idea.rebase.log.GitInteractiveRebaseEntriesProvider +import git4idea.rebase.log.GitRebaseEntryGeneratedUsingLog import git4idea.test.assertCommitted import git4idea.test.assertLatestHistory import git4idea.test.commit import git4idea.test.getHash import git4idea.test.last import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.assertThrows internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTest() { @@ -38,7 +43,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) val newMessageForSecond = "Reworded second commit" @@ -69,7 +74,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) model.exchangeIndices(1, 2) // Move "Add b" down, making it after "Add c" @@ -100,7 +105,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) model.drop(listOf(1)) // Drop "Add b" @@ -136,7 +141,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) model.exchangeIndices(1, 2) @@ -171,7 +176,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) // Original: initial -> config+docs -> remove+add -> service @@ -247,7 +252,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) model.exchangeIndices(1, 2) @@ -289,7 +294,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) // Original: feature1 -> feature2 -> feature3 -> feature4 @@ -334,7 +339,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) model.drop(listOf(0)) @@ -369,7 +374,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) // Original: Add -> Modify -> Move -> Update @@ -405,7 +410,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) // Don't modify the model - just pick all commits in the same order @@ -432,7 +437,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) model.reword(2, "Modified: Add c") @@ -472,7 +477,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) model.drop(listOf(1)) // drop "Add b, c" commit @@ -506,7 +511,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, firstCommit, logData) + val entries = getRebaseEntries(firstCommit) val model = convertToModel(entries) model.drop(listOf(1)) @@ -527,7 +532,7 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes refresh() updateChangeListManager() - val entries = getEntriesUsingLog(repo, initialCommit, logData) + val entries = getRebaseEntries(initialCommit) val model = convertToModel(entries) model.exchangeIndices(0, 1) @@ -548,4 +553,9 @@ internal class GitInMemoryInteractiveRebaseProcessTest : GitInMemoryOperationTes assertCommitted(3) { added("a.txt") } } } + + private fun getRebaseEntries(firstCommit: VcsFullCommitDetails): List = runBlocking { + val result = project.service().getEntriesUsingLog(repo, firstCommit, logData) as GetEntriesUsingLogResult.Success + result.entries + } } diff --git a/plugins/git4idea/tests/git4idea/rebase/interactive/GitInteractiveRebaseUsingLogTest.kt b/plugins/git4idea/tests/git4idea/rebase/interactive/GitInteractiveRebaseUsingLogTest.kt index 5db70aa7823a..fd4b8160b43a 100644 --- a/plugins/git4idea/tests/git4idea/rebase/interactive/GitInteractiveRebaseUsingLogTest.kt +++ b/plugins/git4idea/tests/git4idea/rebase/interactive/GitInteractiveRebaseUsingLogTest.kt @@ -1,6 +1,7 @@ // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package git4idea.rebase.interactive +import com.intellij.openapi.components.service import com.intellij.openapi.progress.EmptyProgressIndicator import com.intellij.openapi.ui.DialogWrapper import com.intellij.vcs.log.VcsCommitMetadata @@ -13,6 +14,8 @@ import git4idea.rebase.GitInteractiveRebaseEditorHandler import git4idea.rebase.GitRebaseEntry import git4idea.rebase.GitRebaseUtils import git4idea.rebase.interactive.dialog.GitInteractiveRebaseDialog +import git4idea.rebase.log.GetEntriesUsingLogResult +import git4idea.rebase.log.GitInteractiveRebaseEntriesProvider import git4idea.test.GitSingleRepoTest import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob @@ -116,7 +119,7 @@ class GitInteractiveRebaseUsingLogTest : GitSingleRepoTest() { 8() } } - assertExceptionDuringEntriesGeneration(commit0, CantRebaseUsingLogException.Reason.MERGE) { + assertFailureDuringEntriesGeneration(commit0, GetEntriesUsingLogResult.FailureReason.MERGE) { "We shouldn't generate entries if merge commit between HEAD and Rebase Base. Generated entries: $it" } } @@ -132,7 +135,7 @@ class GitInteractiveRebaseUsingLogTest : GitSingleRepoTest() { 4(commitMessage = "commit3") } } - assertExceptionDuringEntriesGeneration(commit0, CantRebaseUsingLogException.Reason.FIXUP_SQUASH) { + assertFailureDuringEntriesGeneration(commit0, GetEntriesUsingLogResult.FailureReason.FIXUP_SQUASH) { "We shouldn't generate entries if squash!/fixup! prefix used. Generated entries: $it" } } @@ -176,7 +179,9 @@ class GitInteractiveRebaseUsingLogTest : GitSingleRepoTest() { private fun checkEntriesGeneration(commit: VcsCommitMetadata) { logData.refreshAndWait(repo, true) - val entriesGeneratedUsingLog = getEntriesUsingLog(repo, commit, logData) + val entriesGeneratedUsingLog = runBlocking { + repo.project.service().getEntriesUsingLog(repo, commit, logData) as GetEntriesUsingLogResult.Success + }.entries val entriesGeneratedUsingGit = getRebaseEntriesUsingGit(commit) assertTrue(entriesGeneratedUsingGit.isNotEmpty() && entriesGeneratedUsingLog.isNotEmpty()) entriesGeneratedUsingLog.forEachIndexed { i, generatedEntry -> @@ -190,18 +195,19 @@ class GitInteractiveRebaseUsingLogTest : GitSingleRepoTest() { checkEntriesGeneration(commit) } - private fun assertExceptionDuringEntriesGeneration( + private fun assertFailureDuringEntriesGeneration( commit: VcsCommitMetadata, - reason: CantRebaseUsingLogException.Reason, + reason: GetEntriesUsingLogResult.FailureReason, failMessage: (entries: List) -> String, ) { logData.refreshAndWait(repo, true) - try { - val entries = getEntriesUsingLog(repo, commit, logData) - fail(failMessage(entries)) + val result = runBlocking { + repo.project.service().getEntriesUsingLog(repo, commit, logData) } - catch (e: CantRebaseUsingLogException) { - assertEquals(reason, e.reason) + + when (result) { + is GetEntriesUsingLogResult.Failure -> assertEquals(reason, result.reason) + is GetEntriesUsingLogResult.Success -> fail(failMessage(result.entries)) } } } \ No newline at end of file