Simplified split hunk generation & added to file history diff
This commit is contained in:
parent
e550a6289c
commit
7506c79b63
13
src/main/kotlin/app/extensions/ArrayExtensions.kt
Normal file
13
src/main/kotlin/app/extensions/ArrayExtensions.kt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package app.extensions
|
||||||
|
|
||||||
|
fun <T> Array<T>.matchingIndexes(filter: (T) -> Boolean): List<Int> {
|
||||||
|
val matchingIndexes = mutableListOf<Int>()
|
||||||
|
|
||||||
|
this.forEachIndexed { index, item ->
|
||||||
|
if (filter(item)) {
|
||||||
|
matchingIndexes.add(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchingIndexes
|
||||||
|
}
|
@ -12,4 +12,5 @@ fun <T> flatListOf(vararg lists: List<T>): List<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return flatList
|
return flatList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package app.git.diff
|
|||||||
|
|
||||||
data class Hunk(val header: String, val lines: List<Line>)
|
data class Hunk(val header: String, val lines: List<Line>)
|
||||||
|
|
||||||
data class SplitHunk(val hunk: Hunk, val lines: List<Pair<Line?, Line?>>)
|
data class SplitHunk(val sourceHunk: Hunk, val lines: List<Pair<Line?, Line?>>)
|
||||||
|
|
||||||
data class Line(val text: String, val oldLineNumber: Int, val newLineNumber: Int, val lineType: LineType) {
|
data class Line(val text: String, val oldLineNumber: Int, val newLineNumber: Int, val lineType: LineType) {
|
||||||
// lines numbers are stored based on 0 being the first one but on a file the first line is the 1, so increment it!
|
// lines numbers are stored based on 0 being the first one but on a file the first line is the 1, so increment it!
|
||||||
|
@ -317,17 +317,17 @@ fun HunkSplitTextDiff(
|
|||||||
item {
|
item {
|
||||||
DisableSelection {
|
DisableSelection {
|
||||||
HunkHeader(
|
HunkHeader(
|
||||||
header = splitHunk.hunk.header,
|
header = splitHunk.sourceHunk.header,
|
||||||
diffEntryType = diffEntryType,
|
diffEntryType = diffEntryType,
|
||||||
onUnstageHunk = { onUnstageHunk(diffResult.diffEntry, splitHunk.hunk) },
|
onUnstageHunk = { onUnstageHunk(diffResult.diffEntry, splitHunk.sourceHunk) },
|
||||||
onStageHunk = { onStageHunk(diffResult.diffEntry, splitHunk.hunk) },
|
onStageHunk = { onStageHunk(diffResult.diffEntry, splitHunk.sourceHunk) },
|
||||||
onResetHunk = { onResetHunk(diffResult.diffEntry, splitHunk.hunk) },
|
onResetHunk = { onResetHunk(diffResult.diffEntry, splitHunk.sourceHunk) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val oldHighestLineNumber = splitHunk.hunk.lines.maxOf { it.displayOldLineNumber }
|
val oldHighestLineNumber = splitHunk.sourceHunk.lines.maxOf { it.displayOldLineNumber }
|
||||||
val newHighestLineNumber = splitHunk.hunk.lines.maxOf { it.displayNewLineNumber }
|
val newHighestLineNumber = splitHunk.sourceHunk.lines.maxOf { it.displayNewLineNumber }
|
||||||
val highestLineNumber = max(oldHighestLineNumber, newHighestLineNumber)
|
val highestLineNumber = max(oldHighestLineNumber, newHighestLineNumber)
|
||||||
val highestLineNumberLength = highestLineNumber.toString().count()
|
val highestLineNumberLength = highestLineNumber.toString().count()
|
||||||
|
|
||||||
|
@ -0,0 +1,107 @@
|
|||||||
|
package app.usecase
|
||||||
|
|
||||||
|
import app.extensions.matchingIndexes
|
||||||
|
import app.git.diff.DiffResult
|
||||||
|
import app.git.diff.Line
|
||||||
|
import app.git.diff.LineType
|
||||||
|
import app.git.diff.SplitHunk
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class GenerateSplitHunkFromDiffResultUseCase @Inject constructor() {
|
||||||
|
operator fun invoke(diffFormat: DiffResult.Text): List<SplitHunk> {
|
||||||
|
val unifiedHunksList = diffFormat.hunks
|
||||||
|
val hunksList = mutableListOf<SplitHunk>()
|
||||||
|
|
||||||
|
for (hunk in unifiedHunksList) {
|
||||||
|
val lines = hunk.lines
|
||||||
|
|
||||||
|
val linesNewSideCount =
|
||||||
|
lines.count { it.lineType == LineType.ADDED || it.lineType == LineType.CONTEXT }
|
||||||
|
val linesOldSideCount =
|
||||||
|
lines.count { it.lineType == LineType.REMOVED || it.lineType == LineType.CONTEXT }
|
||||||
|
|
||||||
|
val addedLines = lines.filter { it.lineType == LineType.ADDED }
|
||||||
|
val removedLines = lines.filter { it.lineType == LineType.REMOVED }
|
||||||
|
|
||||||
|
val oldLinesArray: Array<Line?> = if (linesNewSideCount > linesOldSideCount)
|
||||||
|
generateArrayWithContextLines(
|
||||||
|
hunkLines = lines,
|
||||||
|
linesCount = linesNewSideCount,
|
||||||
|
lineNumberCallback = { it.newLineNumber },
|
||||||
|
)
|
||||||
|
else
|
||||||
|
generateArrayWithContextLines(
|
||||||
|
hunkLines = lines,
|
||||||
|
linesCount = linesOldSideCount,
|
||||||
|
lineNumberCallback = { it.oldLineNumber },
|
||||||
|
)
|
||||||
|
|
||||||
|
// Old lines array only contains context lines for now, so copy it to new lines array
|
||||||
|
val newLinesArray = oldLinesArray.copyOf()
|
||||||
|
|
||||||
|
val arraysSize = newLinesArray.count()
|
||||||
|
|
||||||
|
for (removedLine in removedLines) {
|
||||||
|
placeLine(oldLinesArray, lines, removedLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (addedLine in addedLines) {
|
||||||
|
placeLine(newLinesArray, lines, addedLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
val newHunkLines = mutableListOf<Pair<Line?, Line?>>()
|
||||||
|
|
||||||
|
for (i in 0 until arraysSize) {
|
||||||
|
val old = oldLinesArray[i]
|
||||||
|
val new = newLinesArray[i]
|
||||||
|
|
||||||
|
newHunkLines.add(old to new)
|
||||||
|
}
|
||||||
|
|
||||||
|
hunksList.add(SplitHunk(hunk, newHunkLines))
|
||||||
|
}
|
||||||
|
|
||||||
|
return hunksList
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun generateArrayWithContextLines(
|
||||||
|
hunkLines: List<Line>,
|
||||||
|
lineNumberCallback: (Line) -> Int,
|
||||||
|
linesCount: Int
|
||||||
|
): Array<Line?> {
|
||||||
|
val linesArray = arrayOfNulls<Line?>(linesCount)
|
||||||
|
|
||||||
|
val contextLines = hunkLines.filter { it.lineType == LineType.CONTEXT }
|
||||||
|
|
||||||
|
val firstLine = hunkLines.firstOrNull()
|
||||||
|
val firstLineNumber = if (firstLine == null) {
|
||||||
|
0
|
||||||
|
} else
|
||||||
|
lineNumberCallback(firstLine)
|
||||||
|
|
||||||
|
for (contextLine in contextLines) {
|
||||||
|
val lineNumber = lineNumberCallback(contextLine)
|
||||||
|
|
||||||
|
linesArray[lineNumber - firstLineNumber] = contextLine
|
||||||
|
}
|
||||||
|
|
||||||
|
return linesArray
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun placeLine(linesArray: Array<Line?>, hunkLines: List<Line>, lineToPlace: Line) {
|
||||||
|
val previousLinesToCurrent = hunkLines.takeWhile { it != lineToPlace }
|
||||||
|
val previousContextLine = previousLinesToCurrent.lastOrNull { it.lineType == LineType.CONTEXT }
|
||||||
|
|
||||||
|
val contextArrayPosition = if (previousContextLine != null)
|
||||||
|
linesArray.indexOf(previousContextLine)
|
||||||
|
else
|
||||||
|
-1
|
||||||
|
|
||||||
|
val availableIndexes = linesArray.matchingIndexes { it == null }
|
||||||
|
|
||||||
|
// Get the position of the next available line after the previous context line
|
||||||
|
val nextAvailableLinePosition = availableIndexes.first { index -> index > contextArrayPosition }
|
||||||
|
|
||||||
|
linesArray[nextAvailableLinePosition] = lineToPlace
|
||||||
|
}
|
||||||
|
}
|
@ -5,15 +5,16 @@ import androidx.compose.foundation.lazy.LazyListState
|
|||||||
import app.exceptions.MissingDiffEntryException
|
import app.exceptions.MissingDiffEntryException
|
||||||
import app.extensions.delayedStateChange
|
import app.extensions.delayedStateChange
|
||||||
import app.git.*
|
import app.git.*
|
||||||
import app.git.diff.*
|
import app.git.diff.DiffResult
|
||||||
|
import app.git.diff.Hunk
|
||||||
import app.preferences.AppSettings
|
import app.preferences.AppSettings
|
||||||
|
import app.usecase.GenerateSplitHunkFromDiffResultUseCase
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.eclipse.jgit.diff.DiffEntry
|
import org.eclipse.jgit.diff.DiffEntry
|
||||||
import java.lang.Integer.max
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private const val DIFF_MIN_TIME_IN_MS_TO_SHOW_LOAD = 200L
|
private const val DIFF_MIN_TIME_IN_MS_TO_SHOW_LOAD = 200L
|
||||||
@ -23,6 +24,7 @@ class DiffViewModel @Inject constructor(
|
|||||||
private val diffManager: DiffManager,
|
private val diffManager: DiffManager,
|
||||||
private val statusManager: StatusManager,
|
private val statusManager: StatusManager,
|
||||||
private val settings: AppSettings,
|
private val settings: AppSettings,
|
||||||
|
private val generateSplitHunkFromDiffResultUseCase: GenerateSplitHunkFromDiffResultUseCase,
|
||||||
) {
|
) {
|
||||||
private val _diffResult = MutableStateFlow<ViewDiffResult>(ViewDiffResult.Loading(""))
|
private val _diffResult = MutableStateFlow<ViewDiffResult>(ViewDiffResult.Loading(""))
|
||||||
val diffResult: StateFlow<ViewDiffResult?> = _diffResult
|
val diffResult: StateFlow<ViewDiffResult?> = _diffResult
|
||||||
@ -91,7 +93,7 @@ class DiffViewModel @Inject constructor(
|
|||||||
diffEntry.changeType != DiffEntry.ChangeType.ADD &&
|
diffEntry.changeType != DiffEntry.ChangeType.ADD &&
|
||||||
diffEntry.changeType != DiffEntry.ChangeType.DELETE
|
diffEntry.changeType != DiffEntry.ChangeType.DELETE
|
||||||
) {
|
) {
|
||||||
val splitHunkList = generateSplitDiffFormat(diffFormat)
|
val splitHunkList = generateSplitHunkFromDiffResultUseCase(diffFormat)
|
||||||
_diffResult.value = ViewDiffResult.Loaded(
|
_diffResult.value = ViewDiffResult.Loaded(
|
||||||
diffEntryType,
|
diffEntryType,
|
||||||
DiffResult.TextSplit(diffEntry, splitHunkList)
|
DiffResult.TextSplit(diffEntry, splitHunkList)
|
||||||
@ -110,98 +112,6 @@ class DiffViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateSplitDiffFormat(diffFormat: DiffResult.Text): List<SplitHunk> {
|
|
||||||
val unifiedHunksList = diffFormat.hunks
|
|
||||||
val hunksList = mutableListOf<SplitHunk>()
|
|
||||||
|
|
||||||
for (hunk in unifiedHunksList) {
|
|
||||||
val linesNewSideCount =
|
|
||||||
hunk.lines.count { it.lineType == LineType.ADDED || it.lineType == LineType.CONTEXT }
|
|
||||||
val linesOldSideCount =
|
|
||||||
hunk.lines.count { it.lineType == LineType.REMOVED || it.lineType == LineType.CONTEXT }
|
|
||||||
|
|
||||||
val addedLines = hunk.lines.filter { it.lineType == LineType.ADDED }
|
|
||||||
val removedLines = hunk.lines.filter { it.lineType == LineType.REMOVED }
|
|
||||||
|
|
||||||
val maxLinesCountOfBothParts = max(linesNewSideCount, linesOldSideCount)
|
|
||||||
|
|
||||||
val oldLinesArray = arrayOfNulls<Line?>(maxLinesCountOfBothParts)
|
|
||||||
val newLinesArray = arrayOfNulls<Line?>(maxLinesCountOfBothParts)
|
|
||||||
|
|
||||||
val lines = hunk.lines
|
|
||||||
val firstLineOldNumber = hunk.lines.first().oldLineNumber
|
|
||||||
val firstLineNewNumber = hunk.lines.first().newLineNumber
|
|
||||||
|
|
||||||
val firstLine = if (maxLinesCountOfBothParts == linesOldSideCount) {
|
|
||||||
firstLineOldNumber
|
|
||||||
} else
|
|
||||||
firstLineNewNumber
|
|
||||||
|
|
||||||
val contextLines = lines.filter { it.lineType == LineType.CONTEXT }
|
|
||||||
|
|
||||||
for (contextLine in contextLines) {
|
|
||||||
|
|
||||||
val lineNumber = if (maxLinesCountOfBothParts == linesOldSideCount) {
|
|
||||||
contextLine.oldLineNumber
|
|
||||||
} else
|
|
||||||
contextLine.newLineNumber
|
|
||||||
|
|
||||||
oldLinesArray[lineNumber - firstLine] = contextLine
|
|
||||||
newLinesArray[lineNumber - firstLine] = contextLine
|
|
||||||
}
|
|
||||||
|
|
||||||
for (removedLine in removedLines) {
|
|
||||||
val previousLinesToCurrent = lines.takeWhile { it != removedLine }
|
|
||||||
val previousContextLine = previousLinesToCurrent.lastOrNull { it.lineType == LineType.CONTEXT }
|
|
||||||
|
|
||||||
val contextArrayPosition = if (previousContextLine != null)
|
|
||||||
oldLinesArray.indexOf(previousContextLine)
|
|
||||||
else
|
|
||||||
-1
|
|
||||||
|
|
||||||
// Get the position the list of null position of the array
|
|
||||||
val availableIndexes =
|
|
||||||
newLinesArray.mapIndexed { index, line ->
|
|
||||||
if (line != null)
|
|
||||||
null
|
|
||||||
else
|
|
||||||
index
|
|
||||||
}.filterNotNull()
|
|
||||||
val nextAvailableLinePosition = availableIndexes.first { index -> index > contextArrayPosition }
|
|
||||||
oldLinesArray[nextAvailableLinePosition] = removedLine
|
|
||||||
}
|
|
||||||
|
|
||||||
for (addedLine in addedLines) {
|
|
||||||
val previousLinesToCurrent = lines.takeWhile { it != addedLine }
|
|
||||||
val previousContextLine = previousLinesToCurrent.lastOrNull { it.lineType == LineType.CONTEXT }
|
|
||||||
|
|
||||||
val contextArrayPosition = if (previousContextLine != null)
|
|
||||||
newLinesArray.indexOf(previousContextLine)
|
|
||||||
else
|
|
||||||
-1
|
|
||||||
|
|
||||||
val availableIndexes =
|
|
||||||
newLinesArray.mapIndexed { index, line -> if (line != null) null else index }.filterNotNull()
|
|
||||||
val newLinePosition = availableIndexes.first { index -> index > contextArrayPosition }
|
|
||||||
|
|
||||||
newLinesArray[newLinePosition] = addedLine
|
|
||||||
}
|
|
||||||
|
|
||||||
val newHunkLines = mutableListOf<Pair<Line?, Line?>>()
|
|
||||||
|
|
||||||
for (i in 0 until maxLinesCountOfBothParts) {
|
|
||||||
val old = oldLinesArray[i]
|
|
||||||
val new = newLinesArray[i]
|
|
||||||
|
|
||||||
newHunkLines.add(old to new)
|
|
||||||
}
|
|
||||||
|
|
||||||
hunksList.add(SplitHunk(hunk, newHunkLines))
|
|
||||||
}
|
|
||||||
|
|
||||||
return hunksList
|
|
||||||
}
|
|
||||||
|
|
||||||
fun stageHunk(diffEntry: DiffEntry, hunk: Hunk) = tabState.runOperation(
|
fun stageHunk(diffEntry: DiffEntry, hunk: Hunk) = tabState.runOperation(
|
||||||
refreshType = RefreshType.UNCOMMITED_CHANGES,
|
refreshType = RefreshType.UNCOMMITED_CHANGES,
|
||||||
) { git ->
|
) { git ->
|
||||||
|
@ -3,13 +3,14 @@ package app.viewmodels
|
|||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
import app.exceptions.MissingDiffEntryException
|
import app.exceptions.MissingDiffEntryException
|
||||||
import app.extensions.filePath
|
import app.extensions.filePath
|
||||||
import app.git.DiffEntryType
|
import app.git.*
|
||||||
import app.git.DiffManager
|
import app.git.diff.DiffResult
|
||||||
import app.git.RefreshType
|
|
||||||
import app.git.TabState
|
|
||||||
import app.preferences.AppSettings
|
import app.preferences.AppSettings
|
||||||
|
import app.usecase.GenerateSplitHunkFromDiffResultUseCase
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.eclipse.jgit.revwalk.RevCommit
|
import org.eclipse.jgit.revwalk.RevCommit
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ class HistoryViewModel @Inject constructor(
|
|||||||
private val tabState: TabState,
|
private val tabState: TabState,
|
||||||
private val diffManager: DiffManager,
|
private val diffManager: DiffManager,
|
||||||
private val settings: AppSettings,
|
private val settings: AppSettings,
|
||||||
|
private val generateSplitHunkFromDiffResultUseCase: GenerateSplitHunkFromDiffResultUseCase,
|
||||||
) {
|
) {
|
||||||
private val _historyState = MutableStateFlow<HistoryState>(HistoryState.Loading(""))
|
private val _historyState = MutableStateFlow<HistoryState>(HistoryState.Loading(""))
|
||||||
val historyState: StateFlow<HistoryState> = _historyState
|
val historyState: StateFlow<HistoryState> = _historyState
|
||||||
@ -32,6 +34,40 @@ class HistoryViewModel @Inject constructor(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
tabState.managerScope.launch {
|
||||||
|
settings.textDiffTypeFlow.collect { diffType ->
|
||||||
|
if (filePath.isNotBlank()) {
|
||||||
|
updateDiffType(diffType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDiffType(newDiffType: TextDiffType) {
|
||||||
|
val viewDiffResult = this.viewDiffResult.value
|
||||||
|
|
||||||
|
if (viewDiffResult is ViewDiffResult.Loaded) {
|
||||||
|
val diffResult = viewDiffResult.diffResult
|
||||||
|
|
||||||
|
if (diffResult is DiffResult.Text && newDiffType == TextDiffType.SPLIT) { // Current is unified and new is split
|
||||||
|
val hunksList = generateSplitHunkFromDiffResultUseCase(diffResult)
|
||||||
|
_viewDiffResult.value = ViewDiffResult.Loaded(
|
||||||
|
diffEntryType = viewDiffResult.diffEntryType,
|
||||||
|
diffResult = DiffResult.TextSplit(diffResult.diffEntry, hunksList)
|
||||||
|
)
|
||||||
|
} else if (diffResult is DiffResult.TextSplit && newDiffType == TextDiffType.UNIFIED) { // Current is split and new is unified
|
||||||
|
val hunksList = diffResult.hunks.map { it.sourceHunk }
|
||||||
|
|
||||||
|
_viewDiffResult.value = ViewDiffResult.Loaded(
|
||||||
|
diffEntryType = viewDiffResult.diffEntryType,
|
||||||
|
diffResult = DiffResult.Text(diffResult.diffEntry, hunksList)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun fileHistory(filePath: String) = tabState.safeProcessing(
|
fun fileHistory(filePath: String) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.NONE,
|
refreshType = RefreshType.NONE,
|
||||||
) { git ->
|
) { git ->
|
||||||
@ -52,7 +88,6 @@ class HistoryViewModel @Inject constructor(
|
|||||||
) { git ->
|
) { git ->
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
val diffEntries = diffManager.commitDiffEntries(git, commit)
|
val diffEntries = diffManager.commitDiffEntries(git, commit)
|
||||||
val diffEntry = diffEntries.firstOrNull { entry ->
|
val diffEntry = diffEntries.firstOrNull { entry ->
|
||||||
entry.filePath == this.filePath
|
entry.filePath == this.filePath
|
||||||
@ -62,11 +97,18 @@ class HistoryViewModel @Inject constructor(
|
|||||||
_viewDiffResult.value = ViewDiffResult.DiffNotFound
|
_viewDiffResult.value = ViewDiffResult.DiffNotFound
|
||||||
return@runOperation
|
return@runOperation
|
||||||
}
|
}
|
||||||
|
|
||||||
val diffEntryType = DiffEntryType.CommitDiff(diffEntry)
|
val diffEntryType = DiffEntryType.CommitDiff(diffEntry)
|
||||||
|
|
||||||
val diffFormat = diffManager.diffFormat(git, diffEntryType)
|
val diffResult = diffManager.diffFormat(git, diffEntryType)
|
||||||
|
val textDiffType = settings.textDiffType
|
||||||
|
|
||||||
_viewDiffResult.value = ViewDiffResult.Loaded(diffEntryType, diffFormat)
|
val formattedDiffResult = if (textDiffType == TextDiffType.SPLIT && diffResult is DiffResult.Text) {
|
||||||
|
DiffResult.TextSplit(diffEntry, generateSplitHunkFromDiffResultUseCase(diffResult))
|
||||||
|
} else
|
||||||
|
diffResult
|
||||||
|
|
||||||
|
_viewDiffResult.value = ViewDiffResult.Loaded(diffEntryType, formattedDiffResult)
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
if (ex is MissingDiffEntryException) {
|
if (ex is MissingDiffEntryException) {
|
||||||
tabState.refreshData(refreshType = RefreshType.UNCOMMITED_CHANGES)
|
tabState.refreshData(refreshType = RefreshType.UNCOMMITED_CHANGES)
|
||||||
|
Loading…
Reference in New Issue
Block a user