diff --git a/src/main/kotlin/app/extensions/RepositoryStateExtensions.kt b/src/main/kotlin/app/extensions/RepositoryStateExtensions.kt new file mode 100644 index 0000000..77039b9 --- /dev/null +++ b/src/main/kotlin/app/extensions/RepositoryStateExtensions.kt @@ -0,0 +1,6 @@ +package app.extensions + +import org.eclipse.jgit.lib.RepositoryState + +val RepositoryState.isMerging + get() = this == RepositoryState.MERGING || this == RepositoryState.MERGING_RESOLVED \ No newline at end of file diff --git a/src/main/kotlin/app/git/GitManager.kt b/src/main/kotlin/app/git/GitManager.kt index c4d757a..455765e 100644 --- a/src/main/kotlin/app/git/GitManager.kt +++ b/src/main/kotlin/app/git/GitManager.kt @@ -14,6 +14,7 @@ import org.eclipse.jgit.diff.DiffEntry import org.eclipse.jgit.lib.ObjectId import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.lib.Repository +import org.eclipse.jgit.lib.RepositoryState import org.eclipse.jgit.revwalk.RevCommit import org.eclipse.jgit.storage.file.FileRepositoryBuilder import java.io.File @@ -53,6 +54,7 @@ class GitManager @Inject constructor( get() = _lastTimeChecked val stageStatus: StateFlow = statusManager.stageStatus + val repositoryState: StateFlow = statusManager.repositoryState val logStatus: StateFlow = logManager.logStatus val branches: StateFlow> = branchesManager.branches val tags: StateFlow> = tagsManager.tags @@ -211,6 +213,7 @@ class GitManager @Inject constructor( } private suspend fun refreshRepositoryInfo() { + statusManager.loadRepositoryStatus(safeGit) statusManager.loadHasUncommitedChanges(safeGit) branchesManager.loadBranches(safeGit) remotesManager.loadRemotes(safeGit, branchesManager.remoteBranches(safeGit)) diff --git a/src/main/kotlin/app/git/LogManager.kt b/src/main/kotlin/app/git/LogManager.kt index e2d540b..9bdb025 100644 --- a/src/main/kotlin/app/git/LogManager.kt +++ b/src/main/kotlin/app/git/LogManager.kt @@ -1,6 +1,7 @@ package app.git import app.extensions.isBranch +import app.extensions.isMerging import app.extensions.simpleName import app.git.graph.GraphCommitList import app.git.graph.GraphWalk @@ -32,8 +33,9 @@ class LogManager @Inject constructor( val currentBranch = branchesManager.currentBranchRef(git) val commitList = GraphCommitList() + val repositoryState = git.repository.repositoryState - if(currentBranch != null) { // Current branch is null when there is no log (new repo) + if(currentBranch != null || repositoryState.isRebasing) { // Current branch is null when there is no log (new repo) or rebasing val logList = git.log().setMaxCount(2).call().toList() val walk = GraphWalk(git.repository) diff --git a/src/main/kotlin/app/git/StatusManager.kt b/src/main/kotlin/app/git/StatusManager.kt index 9853833..58ea08f 100644 --- a/src/main/kotlin/app/git/StatusManager.kt +++ b/src/main/kotlin/app/git/StatusManager.kt @@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.withContext import org.eclipse.jgit.api.Git import org.eclipse.jgit.diff.DiffEntry -import org.eclipse.jgit.dircache.DirCacheIterator +import org.eclipse.jgit.lib.RepositoryState import org.eclipse.jgit.treewalk.EmptyTreeIterator import javax.inject.Inject @@ -17,9 +17,10 @@ class StatusManager @Inject constructor( private val branchesManager: BranchesManager, ) { private val _stageStatus = MutableStateFlow(StageStatus.Loaded(listOf(), listOf())) + val stageStatus: StateFlow = _stageStatus - val stageStatus: StateFlow - get() = _stageStatus + private val _repositoryState = MutableStateFlow(RepositoryState.SAFE) + val repositoryState: StateFlow = _repositoryState private val _hasUncommitedChanges = MutableStateFlow(false) val hasUncommitedChanges: StateFlow @@ -37,26 +38,52 @@ class StatusManager @Inject constructor( return@withContext status.hasUncommittedChanges() || status.hasUntrackedChanges() } + suspend fun loadRepositoryStatus(git: Git) = withContext(Dispatchers.IO) { + _repositoryState.value = git.repository.repositoryState + } + suspend fun loadStatus(git: Git) = withContext(Dispatchers.IO) { val previousStatus = _stageStatus.value _stageStatus.value = StageStatus.Loading try { + loadRepositoryStatus(git) + loadHasUncommitedChanges(git) val currentBranch = branchesManager.currentBranchRef(git) - + val repositoryState = git.repository.repositoryState val staged = git.diff().apply { - if(currentBranch == null) + if(currentBranch == null && repositoryState != RepositoryState.MERGING && !repositoryState.isRebasing ) setOldTree(EmptyTreeIterator()) // Required if the repository is empty setCached(true) - }.call() + } + .call() + // TODO: Grouping and fitlering allows us to remove duplicates when conflicts appear, requires more testing (what happens in windows? /dev/null is a unix thing) + .groupBy { it.oldPath } + .map { + val entries = it.value + + if(entries.count() > 1) + entries.filter { it.oldPath != "/dev/null" } + else + entries + }.flatten() ensureActive() val unstaged = git .diff() .call() + .groupBy { it.oldPath } + .map { + val entries = it.value + + if(entries.count() > 1) + entries.filter { it.newPath != "/dev/null" } + else + entries + }.flatten() ensureActive() _stageStatus.value = StageStatus.Loaded(staged, unstaged) diff --git a/src/main/kotlin/app/ui/log/Log.kt b/src/main/kotlin/app/ui/log/Log.kt index 6210881..7f9425e 100644 --- a/src/main/kotlin/app/ui/log/Log.kt +++ b/src/main/kotlin/app/ui/log/Log.kt @@ -48,6 +48,7 @@ import app.ui.dialogs.NewBranchDialog import app.ui.dialogs.NewTagDialog import app.ui.dialogs.ResetBranchDialog import org.eclipse.jgit.lib.Ref +import org.eclipse.jgit.lib.RepositoryState import org.eclipse.jgit.revwalk.RevCommit private val colors = listOf( @@ -75,7 +76,7 @@ fun Log( ) { val logStatusState = gitManager.logStatus.collectAsState() val logStatus = logStatusState.value - + val repositoryState by gitManager.repositoryState.collectAsState() val showLogDialog = remember { mutableStateOf(LogDialog.None) } val selectedCommit = if (selectedItem is SelectedItem.CommitBasedItem) { @@ -137,6 +138,7 @@ fun Log( hasPreviousCommits = commitList.count() > 0, graphWidth = graphWidth, weightMod = weightMod, + repositoryState = repositoryState, onUncommitedChangesSelected = { onItemSelected(SelectedItem.UncommitedChanges) } @@ -263,7 +265,8 @@ fun UncommitedChangesLine( hasPreviousCommits: Boolean, graphWidth: Dp, weightMod: MutableState, - onUncommitedChangesSelected: () -> Unit + onUncommitedChangesSelected: () -> Unit, + repositoryState: RepositoryState ) { val textColor = if (selected) { MaterialTheme.colors.primary @@ -295,13 +298,19 @@ fun UncommitedChangesLine( ) Column( - modifier = Modifier.fillMaxSize(), + modifier = Modifier.fillMaxHeight(), verticalArrangement = Arrangement.Center, ) { Spacer(modifier = Modifier.weight(2f)) + val text = when { + repositoryState.isRebasing -> "Pending changes to rebase" + repositoryState.isMerging -> "Pending changes to merge" + else -> "Uncommited changes" + } + Text( - text = "Uncommited changes", + text = text, fontStyle = FontStyle.Italic, modifier = Modifier.padding(start = 16.dp), fontSize = 14.sp, @@ -748,5 +757,4 @@ fun RefChip( } } } - } \ No newline at end of file