diff --git a/src/main/kotlin/app/extensions/RevCommitExtensions.kt b/src/main/kotlin/app/extensions/RevCommitExtensions.kt new file mode 100644 index 0000000..6514bf8 --- /dev/null +++ b/src/main/kotlin/app/extensions/RevCommitExtensions.kt @@ -0,0 +1,11 @@ +package app.extensions + +import org.eclipse.jgit.lib.Repository +import org.eclipse.jgit.revwalk.RevCommit + +fun RevCommit.fullData(repository: Repository): RevCommit? { + return if(this.tree == null) + repository.parseCommit(this) + else + this +} \ No newline at end of file diff --git a/src/main/kotlin/app/git/DiffManager.kt b/src/main/kotlin/app/git/DiffManager.kt index 18d02dd..e747a04 100644 --- a/src/main/kotlin/app/git/DiffManager.kt +++ b/src/main/kotlin/app/git/DiffManager.kt @@ -1,16 +1,13 @@ package app.git +import app.extensions.fullData import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.eclipse.jgit.api.Git import org.eclipse.jgit.diff.DiffEntry import org.eclipse.jgit.diff.DiffFormatter -import org.eclipse.jgit.diff.EditList import org.eclipse.jgit.dircache.DirCacheIterator import org.eclipse.jgit.lib.Repository -import org.eclipse.jgit.patch.HunkHeader -import org.eclipse.jgit.revplot.PlotCommit -import org.eclipse.jgit.revplot.PlotCommitList import org.eclipse.jgit.revwalk.RevCommit import org.eclipse.jgit.revwalk.RevTree import org.eclipse.jgit.revwalk.RevWalk @@ -60,11 +57,14 @@ class DiffManager @Inject constructor() { suspend fun commitDiffEntries(git: Git, commit: RevCommit): List = withContext(Dispatchers.IO) { + val fullCommit = commit.fullData(git.repository) ?: return@withContext emptyList() + val repository = git.repository - val parent = if (commit.parentCount == 0) { + + val parent = if (fullCommit.parentCount == 0) { null } else - commit.parents.first() + fullCommit.parents.first().fullData(git.repository) val oldTreeParser = if (parent != null) prepareTreeParser(repository, parent) @@ -72,7 +72,7 @@ class DiffManager @Inject constructor() { CanonicalTreeParser() } - val newTreeParser = prepareTreeParser(repository, commit) + val newTreeParser = prepareTreeParser(repository, fullCommit) return@withContext git.diff() .setNewTree(newTreeParser) diff --git a/src/main/kotlin/app/git/StashManager.kt b/src/main/kotlin/app/git/StashManager.kt index 022dde5..8417b5a 100644 --- a/src/main/kotlin/app/git/StashManager.kt +++ b/src/main/kotlin/app/git/StashManager.kt @@ -23,7 +23,6 @@ class StashManager @Inject constructor() { } suspend fun popStash(git: Git) = withContext(Dispatchers.IO) { - git .stashApply() .call() diff --git a/src/main/kotlin/app/ui/RepositoryOpen.kt b/src/main/kotlin/app/ui/RepositoryOpen.kt index b17a020..256754a 100644 --- a/src/main/kotlin/app/ui/RepositoryOpen.kt +++ b/src/main/kotlin/app/ui/RepositoryOpen.kt @@ -26,20 +26,13 @@ import java.awt.Cursor @OptIn(ExperimentalSplitPaneApi::class, androidx.compose.ui.ExperimentalComposeUiApi::class) @Composable fun RepositoryOpenPage(gitManager: GitManager) { - var selectedRevCommit by remember { - mutableStateOf(null) - } - var diffSelected by remember { mutableStateOf(null) } - var uncommitedChangesSelected by remember { - mutableStateOf(false) - } var showNewBranchDialog by remember { mutableStateOf(false) } - val selectedIndexCommitLog = remember { mutableStateOf(-1) } + var (selectedItem, setSelectedItem) = remember { mutableStateOf(SelectedItem.None) } if(showNewBranchDialog) { NewBranchDialog( @@ -76,7 +69,12 @@ fun RepositoryOpenPage(gitManager: GitManager) { ) { Branches(gitManager = gitManager) Tags(gitManager = gitManager) - Stashes(gitManager = gitManager) + Stashes( + gitManager = gitManager, + onStashSelected = { stash -> + setSelectedItem(SelectedItem.Stash(stash)) + } + ) } } @@ -104,7 +102,7 @@ fun RepositoryOpenPage(gitManager: GitManager) { HorizontalSplitPane( splitPaneState = rememberSplitPaneState(0.9f) ) { - first() { + first { Box( modifier = Modifier .fillMaxSize() @@ -114,14 +112,9 @@ fun RepositoryOpenPage(gitManager: GitManager) { null -> { Log( gitManager = gitManager, - selectedIndex = selectedIndexCommitLog, - onRevCommitSelected = { commit -> - selectedRevCommit = commit - uncommitedChangesSelected = false - }, - onUncommitedChangesSelected = { - gitManager.statusShouldBeUpdated() - uncommitedChangesSelected = true + selectedItem = selectedItem, + onItemSelected = { + setSelectedItem(it) }, ) } @@ -160,7 +153,7 @@ fun RepositoryOpenPage(gitManager: GitManager) { modifier = Modifier .fillMaxHeight() ) { - if (uncommitedChangesSelected) { + if (selectedItem == SelectedItem.UncommitedChanges) { UncommitedChanges( gitManager = gitManager, onStagedDiffEntrySelected = { diffEntry -> @@ -173,16 +166,14 @@ fun RepositoryOpenPage(gitManager: GitManager) { diffSelected = DiffEntryType.UnstagedDiff(diffEntry) } ) - } else { - selectedRevCommit?.let { - CommitChanges( - gitManager = gitManager, - commit = it, - onDiffSelected = { diffEntry -> - diffSelected = DiffEntryType.CommitDiff(diffEntry) - } - ) - } + } else if(selectedItem is SelectedItem.CommitBasedItem) { + CommitChanges( + gitManager = gitManager, + commit = selectedItem.revCommit, + onDiffSelected = { diffEntry -> + diffSelected = DiffEntryType.CommitDiff(diffEntry) + } + ) } } } @@ -191,4 +182,12 @@ fun RepositoryOpenPage(gitManager: GitManager) { } } } +} + +sealed class SelectedItem { + object None : SelectedItem() + object UncommitedChanges : SelectedItem() + sealed class CommitBasedItem(val revCommit: RevCommit) : SelectedItem() + class Commit(revCommit: RevCommit) : CommitBasedItem(revCommit) + class Stash(revCommit: RevCommit) : CommitBasedItem(revCommit) } \ No newline at end of file diff --git a/src/main/kotlin/app/ui/Stashes.kt b/src/main/kotlin/app/ui/Stashes.kt index 475064b..36ec69f 100644 --- a/src/main/kotlin/app/ui/Stashes.kt +++ b/src/main/kotlin/app/ui/Stashes.kt @@ -1,31 +1,23 @@ package app.ui -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.lazy.items -import androidx.compose.material.* import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import app.ui.components.ScrollableLazyColumn import app.git.GitManager import app.git.StashStatus -import org.eclipse.jgit.revwalk.RevCommit -import app.theme.headerBackground -import app.theme.headerText +import app.ui.components.ScrollableLazyColumn import app.ui.components.SideMenuEntry import app.ui.components.SideMenuSubentry +import org.eclipse.jgit.revwalk.RevCommit @Composable -fun Stashes(gitManager: GitManager) { +fun Stashes( + gitManager: GitManager, + onStashSelected: (commit: RevCommit) -> Unit, +) { val stashStatusState = gitManager.stashStatus.collectAsState() val stashStatus = stashStatusState.value @@ -44,8 +36,10 @@ fun Stashes(gitManager: GitManager) { items(items = stashList) { stash -> StashRow( stash = stash, + onClick = { + onStashSelected(stash) + } ) - } } } @@ -53,9 +47,10 @@ fun Stashes(gitManager: GitManager) { } @Composable -private fun StashRow(stash: RevCommit) { +private fun StashRow(stash: RevCommit, onClick: () -> Unit) { SideMenuSubentry( text = stash.name, iconResourcePath = "stash.svg", + onClick = onClick, ) } \ No newline at end of file diff --git a/src/main/kotlin/app/ui/components/SideMenuSubentry.kt b/src/main/kotlin/app/ui/components/SideMenuSubentry.kt index 5b66c44..ee1a84f 100644 --- a/src/main/kotlin/app/ui/components/SideMenuSubentry.kt +++ b/src/main/kotlin/app/ui/components/SideMenuSubentry.kt @@ -23,13 +23,14 @@ fun SideMenuSubentry( text: String, iconResourcePath: String, bold: Boolean = false, + onClick: () -> Unit = {}, additionalInfo: @Composable () -> Unit = {} ) { Row( modifier = Modifier .height(40.dp) .fillMaxWidth() - .clickable(onClick = {}), + .clickable(onClick = onClick), verticalAlignment = Alignment.CenterVertically, ) { Icon( diff --git a/src/main/kotlin/app/ui/log/Log.kt b/src/main/kotlin/app/ui/log/Log.kt index 19b7a2b..4a03a59 100644 --- a/src/main/kotlin/app/ui/log/Log.kt +++ b/src/main/kotlin/app/ui/log/Log.kt @@ -9,7 +9,7 @@ import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.draggable import androidx.compose.foundation.gestures.rememberDraggableState import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Icon @@ -40,6 +40,7 @@ import app.theme.headerBackground import app.theme.headerText import app.theme.primaryTextColor import app.theme.secondaryTextColor +import app.ui.SelectedItem import app.ui.components.ScrollableLazyColumn import app.ui.dialogs.MergeDialog import app.ui.dialogs.NewBranchDialog @@ -69,16 +70,19 @@ private const val CANVAS_MIN_WIDTH = 100 @Composable fun Log( gitManager: GitManager, - onRevCommitSelected: (RevCommit) -> Unit, - onUncommitedChangesSelected: () -> Unit, - selectedIndex: MutableState = remember { mutableStateOf(-1) } + selectedItem: SelectedItem, + onItemSelected: (SelectedItem) -> Unit, ) { val logStatusState = gitManager.logStatus.collectAsState() val logStatus = logStatusState.value - val selectedUncommited = remember { mutableStateOf(false) } val showLogDialog = remember { mutableStateOf(LogDialog.None) } + val selectedCommit = if (selectedItem is SelectedItem.Commit) { + selectedItem.revCommit + } else { + null + } if (logStatus is LogStatus.Loaded) { val commitList = logStatus.plotCommitList @@ -115,23 +119,20 @@ fun Log( if (hasUncommitedChanges) item { UncommitedChangesLine( - selected = selectedUncommited.value, + selected = selectedItem == SelectedItem.UncommitedChanges, hasPreviousCommits = commitList.count() > 0, graphWidth = graphWidth, weightMod = weightMod, onUncommitedChangesSelected = { - selectedIndex.value = -1 - selectedUncommited.value = true - onUncommitedChangesSelected() + onItemSelected(SelectedItem.UncommitedChanges) } ) } - - itemsIndexed(items = commitList) { index, graphNode -> + items(items = commitList) { graphNode -> CommitLine( gitManager = gitManager, graphNode = graphNode, - selected = selectedIndex.value == index, + selected = selectedCommit?.name == graphNode.name, weightMod = weightMod, graphWidth = graphWidth, currentBranch = logStatus.currentBranch, @@ -140,9 +141,7 @@ fun Log( resetBranch = { showLogDialog.value = LogDialog.ResetBranch(graphNode) }, onMergeBranch = { ref -> showLogDialog.value = LogDialog.MergeBranch(ref) }, onRevCommitSelected = { - selectedIndex.value = index - selectedUncommited.value = false - onRevCommitSelected(it) + onItemSelected(SelectedItem.Commit(graphNode)) } ) } @@ -197,7 +196,8 @@ fun LogDialogs( onResetShowLogDialog() } ) - LogDialog.None -> {} + LogDialog.None -> { + } } }