Clicking on a submodule in (un)commited changes shows an informative screen
This commit is contained in:
parent
f8a6884098
commit
5f2180f1a3
@ -43,6 +43,7 @@ class RawFileManager @Inject constructor(
|
|||||||
newTreeIterator: AbstractTreeIterator?,
|
newTreeIterator: AbstractTreeIterator?,
|
||||||
): EntryContent {
|
): EntryContent {
|
||||||
if (entry.getMode(side) === FileMode.MISSING) return EntryContent.Missing
|
if (entry.getMode(side) === FileMode.MISSING) return EntryContent.Missing
|
||||||
|
if (entry.getMode(side).objectType == Constants.OBJ_COMMIT) return EntryContent.Submodule
|
||||||
if (entry.getMode(side).objectType != Constants.OBJ_BLOB) return EntryContent.InvalidObjectBlob
|
if (entry.getMode(side).objectType != Constants.OBJ_BLOB) return EntryContent.InvalidObjectBlob
|
||||||
|
|
||||||
val reader: ObjectReader = repository.newObjectReader()
|
val reader: ObjectReader = repository.newObjectReader()
|
||||||
@ -111,6 +112,7 @@ sealed class EntryContent {
|
|||||||
object Missing : EntryContent()
|
object Missing : EntryContent()
|
||||||
object InvalidObjectBlob : EntryContent()
|
object InvalidObjectBlob : EntryContent()
|
||||||
data class Text(val rawText: RawText) : EntryContent()
|
data class Text(val rawText: RawText) : EntryContent()
|
||||||
|
object Submodule : EntryContent()
|
||||||
sealed class BinaryContent : EntryContent()
|
sealed class BinaryContent : EntryContent()
|
||||||
data class ImageBinary(val imagePath: String, val contentType: String) : BinaryContent()
|
data class ImageBinary(val imagePath: String, val contentType: String) : BinaryContent()
|
||||||
object Binary : BinaryContent()
|
object Binary : BinaryContent()
|
||||||
|
@ -2,6 +2,7 @@ package com.jetpackduba.gitnuro.git.diff
|
|||||||
|
|
||||||
import com.jetpackduba.gitnuro.git.EntryContent
|
import com.jetpackduba.gitnuro.git.EntryContent
|
||||||
import org.eclipse.jgit.diff.DiffEntry
|
import org.eclipse.jgit.diff.DiffEntry
|
||||||
|
import org.eclipse.jgit.submodule.SubmoduleStatus
|
||||||
|
|
||||||
sealed class DiffResult(
|
sealed class DiffResult(
|
||||||
val diffEntry: DiffEntry,
|
val diffEntry: DiffEntry,
|
||||||
@ -21,4 +22,9 @@ sealed class DiffResult(
|
|||||||
val oldBinaryContent: EntryContent,
|
val oldBinaryContent: EntryContent,
|
||||||
val newBinaryContent: EntryContent,
|
val newBinaryContent: EntryContent,
|
||||||
) : DiffResult(diffEntry)
|
) : DiffResult(diffEntry)
|
||||||
|
|
||||||
|
class Submodule(
|
||||||
|
diffEntry: DiffEntry,
|
||||||
|
val submoduleStatus: SubmoduleStatus?,
|
||||||
|
) : DiffResult(diffEntry)
|
||||||
}
|
}
|
@ -1,23 +1,28 @@
|
|||||||
package com.jetpackduba.gitnuro.git.diff
|
package com.jetpackduba.gitnuro.git.diff
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.extensions.filePath
|
||||||
import com.jetpackduba.gitnuro.git.DiffEntryType
|
import com.jetpackduba.gitnuro.git.DiffEntryType
|
||||||
import com.jetpackduba.gitnuro.git.EntryContent
|
import com.jetpackduba.gitnuro.git.EntryContent
|
||||||
|
import com.jetpackduba.gitnuro.git.submodules.GetSubmodulesUseCase
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.diff.DiffEntry
|
import org.eclipse.jgit.diff.DiffEntry
|
||||||
import org.eclipse.jgit.diff.DiffFormatter
|
import org.eclipse.jgit.diff.DiffFormatter
|
||||||
import org.eclipse.jgit.dircache.DirCacheIterator
|
import org.eclipse.jgit.dircache.DirCacheIterator
|
||||||
|
import org.eclipse.jgit.submodule.SubmoduleStatus
|
||||||
|
import org.eclipse.jgit.submodule.SubmoduleStatusType
|
||||||
import org.eclipse.jgit.treewalk.FileTreeIterator
|
import org.eclipse.jgit.treewalk.FileTreeIterator
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.InvalidObjectException
|
import java.io.InvalidObjectException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class FormatDiffUseCase @Inject constructor(
|
class FormatDiffUseCase @Inject constructor(
|
||||||
private val getDiffEntryForUncommitedDiffUseCase: GetDiffEntryForUncommitedDiffUseCase,
|
|
||||||
private val canGenerateTextDiffUseCase: CanGenerateTextDiffUseCase,
|
|
||||||
private val getDiffContentUseCase: GetDiffContentUseCase,
|
|
||||||
private val formatHunksUseCase: FormatHunksUseCase,
|
private val formatHunksUseCase: FormatHunksUseCase,
|
||||||
|
private val getDiffContentUseCase: GetDiffContentUseCase,
|
||||||
|
private val canGenerateTextDiffUseCase: CanGenerateTextDiffUseCase,
|
||||||
|
private val getDiffEntryForUncommitedDiffUseCase: GetDiffEntryForUncommitedDiffUseCase,
|
||||||
|
private val getSubmodulesUseCase: GetSubmodulesUseCase,
|
||||||
) {
|
) {
|
||||||
suspend operator fun invoke(
|
suspend operator fun invoke(
|
||||||
git: Git,
|
git: Git,
|
||||||
@ -27,6 +32,7 @@ class FormatDiffUseCase @Inject constructor(
|
|||||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||||
val repository = git.repository
|
val repository = git.repository
|
||||||
val diffEntry: DiffEntry
|
val diffEntry: DiffEntry
|
||||||
|
val submodules = getSubmodulesUseCase(git)
|
||||||
|
|
||||||
DiffFormatter(byteArrayOutputStream).use { formatter ->
|
DiffFormatter(byteArrayOutputStream).use { formatter ->
|
||||||
formatter.setRepository(repository)
|
formatter.setRepository(repository)
|
||||||
@ -51,37 +57,49 @@ class FormatDiffUseCase @Inject constructor(
|
|||||||
formatter.flush()
|
formatter.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
val oldTree: DirCacheIterator?
|
var diffResult: DiffResult
|
||||||
val newTree: FileTreeIterator?
|
val submoduleStatus = submodules[diffEntry.filePath]
|
||||||
|
|
||||||
if (diffEntryType is DiffEntryType.UnstagedDiff) {
|
if (submoduleStatus != null) {
|
||||||
oldTree = DirCacheIterator(repository.readDirCache())
|
diffResult = DiffResult.Submodule(diffEntry, submoduleStatus)
|
||||||
newTree = FileTreeIterator(repository)
|
|
||||||
} else {
|
} else {
|
||||||
oldTree = null
|
val oldTree: DirCacheIterator?
|
||||||
newTree = null
|
val newTree: FileTreeIterator?
|
||||||
}
|
|
||||||
|
|
||||||
val diffContent = getDiffContentUseCase(repository, diffEntry, oldTree, newTree)
|
if (diffEntryType is DiffEntryType.UnstagedDiff) {
|
||||||
val fileHeader = diffContent.fileHeader
|
oldTree = DirCacheIterator(repository.readDirCache())
|
||||||
|
newTree = FileTreeIterator(repository)
|
||||||
|
} else {
|
||||||
|
oldTree = null
|
||||||
|
newTree = null
|
||||||
|
}
|
||||||
|
|
||||||
val rawOld = diffContent.rawOld
|
val diffContent = getDiffContentUseCase(repository, diffEntry, oldTree, newTree)
|
||||||
val rawNew = diffContent.rawNew
|
val fileHeader = diffContent.fileHeader
|
||||||
|
|
||||||
if (rawOld == EntryContent.InvalidObjectBlob || rawNew == EntryContent.InvalidObjectBlob)
|
val rawOld = diffContent.rawOld
|
||||||
throw InvalidObjectException("Invalid object in diff format")
|
val rawNew = diffContent.rawNew
|
||||||
|
|
||||||
var diffResult: DiffResult = DiffResult.Text(diffEntry, emptyList())
|
if (rawOld == EntryContent.InvalidObjectBlob || rawNew == EntryContent.InvalidObjectBlob) {
|
||||||
|
throw InvalidObjectException("Invalid object in diff format")
|
||||||
|
} else if (rawOld == EntryContent.Submodule || rawNew == EntryContent.Submodule) {
|
||||||
|
diffResult = DiffResult.Submodule(diffEntry, null)
|
||||||
|
} else {
|
||||||
|
diffResult = DiffResult.Text(diffEntry, emptyList())
|
||||||
|
|
||||||
// If we can, generate text diff (if one of the files has never been a binary file)
|
// If we can, generate text diff (if one of the files has never been a binary file)
|
||||||
val hasGeneratedTextDiff = canGenerateTextDiffUseCase(rawOld, rawNew) { oldRawText, newRawText ->
|
val hasGeneratedTextDiff = canGenerateTextDiffUseCase(rawOld, rawNew) { oldRawText, newRawText ->
|
||||||
diffResult =
|
diffResult =
|
||||||
DiffResult.Text(diffEntry, formatHunksUseCase(fileHeader, oldRawText, newRawText, isDisplayFullFile))
|
DiffResult.Text(
|
||||||
|
diffEntry,
|
||||||
|
formatHunksUseCase(fileHeader, oldRawText, newRawText, isDisplayFullFile)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
if (!hasGeneratedTextDiff) {
|
||||||
|
diffResult = DiffResult.NonText(diffEntry, rawOld, rawNew)
|
||||||
if (!hasGeneratedTextDiff) {
|
}
|
||||||
diffResult = DiffResult.NonText(diffEntry, rawOld, rawNew)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return@withContext diffResult
|
return@withContext diffResult
|
||||||
|
@ -176,9 +176,6 @@ fun UncommitedChanges(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO After moving to compose 1.5.0 (beta and RC), the right click event stops working randomly just on
|
|
||||||
// unstaged changes. It could be related to the changes to the Popup API and the custom implementation
|
|
||||||
// that Gitnuro uses
|
|
||||||
val unstagedView: @Composable () -> Unit = {
|
val unstagedView: @Composable () -> Unit = {
|
||||||
EntriesList(
|
EntriesList(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -56,9 +56,11 @@ fun submoduleContextMenuItems(
|
|||||||
// )
|
// )
|
||||||
}
|
}
|
||||||
|
|
||||||
add(
|
if(isNotEmpty()) {
|
||||||
ContextMenuElement.ContextSeparator,
|
add(
|
||||||
)
|
ContextMenuElement.ContextSeparator,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
add(
|
add(
|
||||||
ContextMenuElement.ContextTextEntry(
|
ContextMenuElement.ContextTextEntry(
|
||||||
|
@ -35,6 +35,7 @@ import androidx.compose.ui.platform.PlatformLocalization
|
|||||||
import androidx.compose.ui.res.loadImageBitmap
|
import androidx.compose.ui.res.loadImageBitmap
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
|
import androidx.compose.ui.text.SpanStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@ -53,6 +54,7 @@ import com.jetpackduba.gitnuro.git.workspace.StatusType
|
|||||||
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
||||||
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
||||||
import com.jetpackduba.gitnuro.theme.*
|
import com.jetpackduba.gitnuro.theme.*
|
||||||
|
import com.jetpackduba.gitnuro.ui.components.PrimaryButton
|
||||||
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
||||||
import com.jetpackduba.gitnuro.ui.components.SecondaryButton
|
import com.jetpackduba.gitnuro.ui.components.SecondaryButton
|
||||||
import com.jetpackduba.gitnuro.ui.components.Tooltip
|
import com.jetpackduba.gitnuro.ui.components.Tooltip
|
||||||
@ -65,6 +67,7 @@ import com.jetpackduba.gitnuro.viewmodels.ViewDiffResult
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.eclipse.jgit.diff.DiffEntry
|
import org.eclipse.jgit.diff.DiffEntry
|
||||||
|
import org.eclipse.jgit.submodule.SubmoduleStatusType
|
||||||
import org.jetbrains.compose.animatedimage.Blank
|
import org.jetbrains.compose.animatedimage.Blank
|
||||||
import org.jetbrains.compose.animatedimage.animate
|
import org.jetbrains.compose.animatedimage.animate
|
||||||
import org.jetbrains.compose.animatedimage.loadAnimatedImage
|
import org.jetbrains.compose.animatedimage.loadAnimatedImage
|
||||||
@ -118,6 +121,7 @@ fun Diff(
|
|||||||
diffEntry = diffEntry,
|
diffEntry = diffEntry,
|
||||||
onCloseDiffView = onCloseDiffView,
|
onCloseDiffView = onCloseDiffView,
|
||||||
diffType = diffType,
|
diffType = diffType,
|
||||||
|
isTextDiff = diffResult is DiffResult.Text,
|
||||||
isDisplayFullFile = isDisplayFullFile,
|
isDisplayFullFile = isDisplayFullFile,
|
||||||
onStageFile = { diffViewModel.stageFile(it) },
|
onStageFile = { diffViewModel.stageFile(it) },
|
||||||
onUnstageFile = { diffViewModel.unstageFile(it) },
|
onUnstageFile = { diffViewModel.unstageFile(it) },
|
||||||
@ -181,6 +185,13 @@ fun Diff(
|
|||||||
diffResult,
|
diffResult,
|
||||||
onOpenFileWithExternalApp = { path -> diffViewModel.openFileWithExternalApp(path) })
|
onOpenFileWithExternalApp = { path -> diffViewModel.openFileWithExternalApp(path) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is DiffResult.Submodule -> {
|
||||||
|
SubmoduleDiff(
|
||||||
|
diffResult,
|
||||||
|
onOpenSubmodule = { diffViewModel.openSubmodule(diffResult.diffEntry.filePath) }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,6 +270,60 @@ fun NonTextDiff(diffResult: DiffResult.NonText, onOpenFileWithExternalApp: (Stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SubmoduleDiff(diffResult: DiffResult.Submodule, onOpenSubmodule: () -> Unit) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Submodule ${diffResult.diffEntry.filePath}",
|
||||||
|
style = MaterialTheme.typography.h4,
|
||||||
|
modifier = Modifier.padding(bottom = 8.dp),
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
color = MaterialTheme.colors.onBackground,
|
||||||
|
)
|
||||||
|
|
||||||
|
SelectionContainer {
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
AnnotatedString(
|
||||||
|
"Old ID: ",
|
||||||
|
SpanStyle(fontWeight = FontWeight.SemiBold)
|
||||||
|
) + AnnotatedString(diffResult.diffEntry.oldId.name()),
|
||||||
|
color = MaterialTheme.colors.onBackground,
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
AnnotatedString(
|
||||||
|
"New ID: ",
|
||||||
|
SpanStyle(fontWeight = FontWeight.SemiBold)
|
||||||
|
) + AnnotatedString(diffResult.diffEntry.newId.name()),
|
||||||
|
color = MaterialTheme.colors.onBackground,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val submoduleStatus = diffResult.submoduleStatus
|
||||||
|
|
||||||
|
if (
|
||||||
|
submoduleStatus != null &&
|
||||||
|
listOf(
|
||||||
|
SubmoduleStatusType.INITIALIZED,
|
||||||
|
SubmoduleStatusType.REV_CHECKED_OUT
|
||||||
|
).contains(submoduleStatus.type) &&
|
||||||
|
submoduleStatus.indexId == diffResult.diffEntry.newId?.toObjectId()
|
||||||
|
) {
|
||||||
|
PrimaryButton(
|
||||||
|
modifier = Modifier.padding(top = 8.dp),
|
||||||
|
text = "Open submodule",
|
||||||
|
onClick = onOpenSubmodule,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SideTitle(text: String) {
|
fun SideTitle(text: String) {
|
||||||
Text(
|
Text(
|
||||||
@ -778,6 +843,7 @@ private fun DiffHeader(
|
|||||||
diffEntry: DiffEntry,
|
diffEntry: DiffEntry,
|
||||||
diffType: TextDiffType,
|
diffType: TextDiffType,
|
||||||
isDisplayFullFile: Boolean,
|
isDisplayFullFile: Boolean,
|
||||||
|
isTextDiff: Boolean,
|
||||||
onCloseDiffView: () -> Unit,
|
onCloseDiffView: () -> Unit,
|
||||||
onStageFile: (StatusEntry) -> Unit,
|
onStageFile: (StatusEntry) -> Unit,
|
||||||
onUnstageFile: (StatusEntry) -> Unit,
|
onUnstageFile: (StatusEntry) -> Unit,
|
||||||
@ -837,7 +903,7 @@ private fun DiffHeader(
|
|||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
) {
|
) {
|
||||||
if (diffEntryType.statusType != StatusType.ADDED && diffEntryType.statusType != StatusType.REMOVED) {
|
if (diffEntryType.statusType != StatusType.ADDED && diffEntryType.statusType != StatusType.REMOVED && isTextDiff) {
|
||||||
DiffTypeButtons(
|
DiffTypeButtons(
|
||||||
diffType = diffType,
|
diffType = diffType,
|
||||||
isDisplayFullFile = isDisplayFullFile,
|
isDisplayFullFile = isDisplayFullFile,
|
||||||
@ -948,36 +1014,6 @@ fun DiffTypeButtons(
|
|||||||
onClick = { onChangeDiffType(TextDiffType.SPLIT) },
|
onClick = { onChangeDiffType(TextDiffType.SPLIT) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// Text(
|
|
||||||
// "Unified",
|
|
||||||
// color = MaterialTheme.colors.onBackground,
|
|
||||||
// style = MaterialTheme.typography.caption,
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// Switch(
|
|
||||||
// checked = diffType == TextDiffType.SPLIT,
|
|
||||||
// onCheckedChange = { checked ->
|
|
||||||
// val newType = if (checked)
|
|
||||||
// TextDiffType.SPLIT
|
|
||||||
// else
|
|
||||||
// TextDiffType.UNIFIED
|
|
||||||
//
|
|
||||||
// onChangeDiffType(newType)
|
|
||||||
// },
|
|
||||||
// colors = SwitchDefaults.colors(
|
|
||||||
// uncheckedThumbColor = MaterialTheme.colors.secondaryVariant,
|
|
||||||
// uncheckedTrackColor = MaterialTheme.colors.secondaryVariant,
|
|
||||||
// uncheckedTrackAlpha = 0.54f
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// Text(
|
|
||||||
// "Split",
|
|
||||||
// color = MaterialTheme.colors.onBackground,
|
|
||||||
//// modifier = Modifier.padding(horizontal = 4.dp),
|
|
||||||
// style = MaterialTheme.typography.caption,
|
|
||||||
// )
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import com.jetpackduba.gitnuro.git.diff.*
|
|||||||
import com.jetpackduba.gitnuro.git.workspace.*
|
import com.jetpackduba.gitnuro.git.workspace.*
|
||||||
import com.jetpackduba.gitnuro.preferences.AppSettings
|
import com.jetpackduba.gitnuro.preferences.AppSettings
|
||||||
import com.jetpackduba.gitnuro.system.OpenFileInExternalAppUseCase
|
import com.jetpackduba.gitnuro.system.OpenFileInExternalAppUseCase
|
||||||
|
import com.jetpackduba.gitnuro.ui.TabsManager
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@ -36,6 +37,7 @@ class DiffViewModel @Inject constructor(
|
|||||||
private val settings: AppSettings,
|
private val settings: AppSettings,
|
||||||
private val generateSplitHunkFromDiffResultUseCase: GenerateSplitHunkFromDiffResultUseCase,
|
private val generateSplitHunkFromDiffResultUseCase: GenerateSplitHunkFromDiffResultUseCase,
|
||||||
private val discardUnstagedHunkLineUseCase: DiscardUnstagedHunkLineUseCase,
|
private val discardUnstagedHunkLineUseCase: DiscardUnstagedHunkLineUseCase,
|
||||||
|
private val tabsManager: TabsManager,
|
||||||
tabScope: CoroutineScope,
|
tabScope: CoroutineScope,
|
||||||
) {
|
) {
|
||||||
private val _diffResult = MutableStateFlow<ViewDiffResult>(ViewDiffResult.Loading(""))
|
private val _diffResult = MutableStateFlow<ViewDiffResult>(ViewDiffResult.Loading(""))
|
||||||
@ -218,6 +220,10 @@ class DiffViewModel @Inject constructor(
|
|||||||
) { git ->
|
) { git ->
|
||||||
discardUnstagedHunkLineUseCase(git, entry, hunk, line)
|
discardUnstagedHunkLineUseCase(git, entry, hunk, line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun openSubmodule(path: String) = tabState.runOperation(refreshType = RefreshType.NONE) { git ->
|
||||||
|
tabsManager.addNewTabFromPath("${git.repository.workTree}/$path", true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class TextDiffType(val value: Int) {
|
enum class TextDiffType(val value: Int) {
|
||||||
|
Loading…
Reference in New Issue
Block a user