mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
refactor [git]: Extract getEntriesUsingLog from GitInteractiveRebaseUsingLog.kt into separate service
GitOrigin-RevId: df72990b28749d34ae4bfb5097e08cb9f5a0974e
This commit is contained in:
committed by
intellij-monorepo-bot
parent
e52dd94ae1
commit
f91cb12fa2
@@ -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<CantRebaseUsingLogException.Reason>("cant_rebase_using_log_reason")
|
||||
private val CANT_REBASE_USING_LOG_REASON = EventFields.Enum<GetEntriesUsingLogResult.FailureReason>("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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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<GitInteractiveRebaseEntriesProvider>().tryGetEntriesUsingLog(repository, commits.last(), entriesSource.logData)
|
||||
}
|
||||
} ?: return GitCommitEditingOperationResult.Incomplete
|
||||
|
||||
|
||||
@@ -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<GitRebaseEntryGeneratedUsingLog> {
|
||||
Disposer.newDisposable().use { parentDisposable ->
|
||||
val traverser: GitHistoryTraverser = GitHistoryTraverserImpl(repository.project, logData, parentDisposable)
|
||||
val details = mutableListOf<VcsCommitMetadata>()
|
||||
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<GitRebaseEntryGeneratedUsingLog>? {
|
||||
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<GitInteractiveRebaseEntriesProvider>()
|
||||
.tryGetEntriesUsingLog(repository, commit, logData)
|
||||
if (generatedEntries == null) {
|
||||
startInteractiveRebase(repository, commit)
|
||||
return
|
||||
@@ -252,24 +178,3 @@ private class GitInteractiveRebaseUsingLogEditorHandler(
|
||||
private fun List<GitRebaseEntry>.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
|
||||
}
|
||||
@@ -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<GitRebaseEntryGeneratedUsingLog>? {
|
||||
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<VcsCommitMetadata>()
|
||||
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<GitRebaseEntryGeneratedUsingLog>) : 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
|
||||
}
|
||||
+25
-15
@@ -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<GitRebaseEntryGeneratedUsingLog> = runBlocking {
|
||||
val result = project.service<GitInteractiveRebaseEntriesProvider>().getEntriesUsingLog(repo, firstCommit, logData) as GetEntriesUsingLogResult.Success
|
||||
result.entries
|
||||
}
|
||||
}
|
||||
|
||||
+16
-10
@@ -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<GitInteractiveRebaseEntriesProvider>().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<GitRebaseEntry>) -> String,
|
||||
) {
|
||||
logData.refreshAndWait(repo, true)
|
||||
try {
|
||||
val entries = getEntriesUsingLog(repo, commit, logData)
|
||||
fail(failMessage(entries))
|
||||
val result = runBlocking {
|
||||
repo.project.service<GitInteractiveRebaseEntriesProvider>().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))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user