mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[github] Fix exception thrown with non-linear history in RiE (IDEA-346042)
#IDEA-346042 Fixed Exception was thrown in the case of non-linear history because SinglePatchFileHistory cannot compare refs. The real solution would be to make `git4idea.changes.MutableLinearGitFileHistory` resilient to merge commits. GitOrigin-RevId: 4c5df96e0884a4f49227ad1c0d07a0358d77403f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
651938574a
commit
9b9c772d8c
@@ -30,20 +30,8 @@ internal class GitBranchComparisonResultImpl(private val project: Project,
|
||||
override val patchesByChange: Map<RefComparisonChange, GitTextFilePatchWithHistory> = Collections.unmodifiableMap(_diffDataByChange)
|
||||
|
||||
init {
|
||||
val commitsHashes = commits.mapTo(mutableSetOf()) { it.sha }
|
||||
|
||||
// One or more merge commit for changes that are included into PR (master merges are ignored)
|
||||
val linearHistory = commits.all { commit ->
|
||||
commit.parents.count { commitsHashes.contains(it) } <= 1
|
||||
}
|
||||
|
||||
try {
|
||||
if (linearHistory) {
|
||||
initForLinearHistory(commits)
|
||||
}
|
||||
else {
|
||||
initForHistoryWithMerges(commits)
|
||||
}
|
||||
initForLinearHistory(commits)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
throw RuntimeException("Unable to build branch comparison result between $baseSha and $headSha via $mergeBaseSha - ${e.message}", e)
|
||||
@@ -57,31 +45,33 @@ internal class GitBranchComparisonResultImpl(private val project: Project,
|
||||
|
||||
val commitsHashes = listOf(mergeBaseSha) + commits.map { it.sha }
|
||||
for (commitWithPatches in commits) {
|
||||
|
||||
val commitSha = commitWithPatches.sha
|
||||
val commitChanges = mutableListOf<RefComparisonChange>()
|
||||
|
||||
for (patch in commitWithPatches.patches) {
|
||||
val change = createChangeFromPatch(previousCommitSha, commitSha, patch)
|
||||
commitChanges.add(change)
|
||||
if (commitWithPatches.parents.count { commitsHashes.contains(it) } <= 1) {
|
||||
for (patch in commitWithPatches.patches) {
|
||||
val change = createChangeFromPatch(previousCommitSha, commitSha, patch)
|
||||
commitChanges.add(change)
|
||||
|
||||
if (patch is TextFilePatch) {
|
||||
val beforePath = patch.beforeName
|
||||
val afterPath = patch.afterName
|
||||
if (patch is TextFilePatch) {
|
||||
val beforePath = patch.beforeName
|
||||
val afterPath = patch.afterName
|
||||
|
||||
val historyBefore = beforePath?.let { fileHistoriesByLastKnownFilePath.remove(it) }
|
||||
val fileHistory = (historyBefore ?: MutableLinearGitFileHistory(commitsHashes)).apply {
|
||||
append(previousCommitSha, beforePath)
|
||||
append(commitSha, patch)
|
||||
val historyBefore = beforePath?.let { fileHistoriesByLastKnownFilePath.remove(it) }
|
||||
val fileHistory = (historyBefore ?: MutableLinearGitFileHistory(commitsHashes)).apply {
|
||||
append(previousCommitSha, beforePath)
|
||||
append(commitSha, patch)
|
||||
}
|
||||
val path = (afterPath ?: beforePath)!!
|
||||
fileHistoriesByLastKnownFilePath[path] = fileHistory
|
||||
|
||||
patch.beforeVersionId = previousCommitSha
|
||||
patch.afterVersionId = commitSha
|
||||
_diffDataByChange[change] = GitTextFilePatchWithHistory(patch, false, fileHistory)
|
||||
}
|
||||
val path = (afterPath ?: beforePath)!!
|
||||
fileHistoriesByLastKnownFilePath[path] = fileHistory
|
||||
|
||||
patch.beforeVersionId = previousCommitSha
|
||||
patch.afterVersionId = commitSha
|
||||
_diffDataByChange[change] = GitTextFilePatchWithHistory(patch, false, fileHistory)
|
||||
}
|
||||
}
|
||||
|
||||
_changesByCommits[commitWithPatches.sha] = commitChanges
|
||||
previousCommitSha = commitSha
|
||||
}
|
||||
@@ -109,27 +99,6 @@ internal class GitBranchComparisonResultImpl(private val project: Project,
|
||||
}
|
||||
}
|
||||
|
||||
private fun initForHistoryWithMerges(commits: List<GitCommitShaWithPatches>) {
|
||||
val commitsHashes = commits.mapTo(mutableSetOf()) { it.sha }
|
||||
for (commitWithPatches in commits) {
|
||||
val previousCommitSha = commitWithPatches.parents.find { commitsHashes.contains(it) } ?: mergeBaseSha
|
||||
val commitSha = commitWithPatches.sha
|
||||
val commitChanges = commitWithPatches.patches.map { createChangeFromPatch(previousCommitSha, commitSha, it) }
|
||||
_changesByCommits[commitWithPatches.sha] = commitChanges
|
||||
}
|
||||
|
||||
for (patch in headPatches) {
|
||||
val change = createChangeFromPatch(mergeBaseSha, headSha, patch)
|
||||
_changes.add(change)
|
||||
|
||||
if (patch is TextFilePatch) {
|
||||
patch.beforeVersionId = baseSha
|
||||
patch.afterVersionId = headSha
|
||||
_diffDataByChange[change] = GitTextFilePatchWithHistory(patch, true, SinglePatchGitFileHistory(patch))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createChangeFromPatch(beforeRef: String, afterRef: String, patch: FilePatch): RefComparisonChange {
|
||||
val beforePath = if (patch.isNewFile) null else VcsUtil.getFilePath(vcsRoot, patch.beforeName)
|
||||
val afterPath = if (patch.isDeletedFile) null else VcsUtil.getFilePath(vcsRoot, patch.afterName)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package git4idea.changes
|
||||
|
||||
import com.intellij.openapi.diff.impl.patch.TextFilePatch
|
||||
|
||||
// Still used by a plugin
|
||||
@Suppress("unused")
|
||||
internal class SinglePatchGitFileHistory(private val patch: TextFilePatch) : GitFileHistory {
|
||||
|
||||
override fun findStartCommit(): String? = patch.beforeVersionId
|
||||
|
||||
Reference in New Issue
Block a user