Uncommited changes line now show if merging/rebasing

This commit starts not only the rebase support but also manage merges when conflicts appear [WIP]
This commit is contained in:
Abdelilah El Aissaoui 2021-12-18 04:15:21 +01:00
parent d81c81de87
commit 3ed5f0cc1e
5 changed files with 58 additions and 12 deletions

View File

@ -0,0 +1,6 @@
package app.extensions
import org.eclipse.jgit.lib.RepositoryState
val RepositoryState.isMerging
get() = this == RepositoryState.MERGING || this == RepositoryState.MERGING_RESOLVED

View File

@ -14,6 +14,7 @@ import org.eclipse.jgit.diff.DiffEntry
import org.eclipse.jgit.lib.ObjectId import org.eclipse.jgit.lib.ObjectId
import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.lib.Repository import org.eclipse.jgit.lib.Repository
import org.eclipse.jgit.lib.RepositoryState
import org.eclipse.jgit.revwalk.RevCommit import org.eclipse.jgit.revwalk.RevCommit
import org.eclipse.jgit.storage.file.FileRepositoryBuilder import org.eclipse.jgit.storage.file.FileRepositoryBuilder
import java.io.File import java.io.File
@ -53,6 +54,7 @@ class GitManager @Inject constructor(
get() = _lastTimeChecked get() = _lastTimeChecked
val stageStatus: StateFlow<StageStatus> = statusManager.stageStatus val stageStatus: StateFlow<StageStatus> = statusManager.stageStatus
val repositoryState: StateFlow<RepositoryState> = statusManager.repositoryState
val logStatus: StateFlow<LogStatus> = logManager.logStatus val logStatus: StateFlow<LogStatus> = logManager.logStatus
val branches: StateFlow<List<Ref>> = branchesManager.branches val branches: StateFlow<List<Ref>> = branchesManager.branches
val tags: StateFlow<List<Ref>> = tagsManager.tags val tags: StateFlow<List<Ref>> = tagsManager.tags
@ -211,6 +213,7 @@ class GitManager @Inject constructor(
} }
private suspend fun refreshRepositoryInfo() { private suspend fun refreshRepositoryInfo() {
statusManager.loadRepositoryStatus(safeGit)
statusManager.loadHasUncommitedChanges(safeGit) statusManager.loadHasUncommitedChanges(safeGit)
branchesManager.loadBranches(safeGit) branchesManager.loadBranches(safeGit)
remotesManager.loadRemotes(safeGit, branchesManager.remoteBranches(safeGit)) remotesManager.loadRemotes(safeGit, branchesManager.remoteBranches(safeGit))

View File

@ -1,6 +1,7 @@
package app.git package app.git
import app.extensions.isBranch import app.extensions.isBranch
import app.extensions.isMerging
import app.extensions.simpleName import app.extensions.simpleName
import app.git.graph.GraphCommitList import app.git.graph.GraphCommitList
import app.git.graph.GraphWalk import app.git.graph.GraphWalk
@ -32,8 +33,9 @@ class LogManager @Inject constructor(
val currentBranch = branchesManager.currentBranchRef(git) val currentBranch = branchesManager.currentBranchRef(git)
val commitList = GraphCommitList() 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 logList = git.log().setMaxCount(2).call().toList()
val walk = GraphWalk(git.repository) val walk = GraphWalk(git.repository)

View File

@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.StateFlow
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.dircache.DirCacheIterator import org.eclipse.jgit.lib.RepositoryState
import org.eclipse.jgit.treewalk.EmptyTreeIterator import org.eclipse.jgit.treewalk.EmptyTreeIterator
import javax.inject.Inject import javax.inject.Inject
@ -17,9 +17,10 @@ class StatusManager @Inject constructor(
private val branchesManager: BranchesManager, private val branchesManager: BranchesManager,
) { ) {
private val _stageStatus = MutableStateFlow<StageStatus>(StageStatus.Loaded(listOf(), listOf())) private val _stageStatus = MutableStateFlow<StageStatus>(StageStatus.Loaded(listOf(), listOf()))
val stageStatus: StateFlow<StageStatus> = _stageStatus
val stageStatus: StateFlow<StageStatus> private val _repositoryState = MutableStateFlow(RepositoryState.SAFE)
get() = _stageStatus val repositoryState: StateFlow<RepositoryState> = _repositoryState
private val _hasUncommitedChanges = MutableStateFlow<Boolean>(false) private val _hasUncommitedChanges = MutableStateFlow<Boolean>(false)
val hasUncommitedChanges: StateFlow<Boolean> val hasUncommitedChanges: StateFlow<Boolean>
@ -37,26 +38,52 @@ class StatusManager @Inject constructor(
return@withContext status.hasUncommittedChanges() || status.hasUntrackedChanges() 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) { suspend fun loadStatus(git: Git) = withContext(Dispatchers.IO) {
val previousStatus = _stageStatus.value val previousStatus = _stageStatus.value
_stageStatus.value = StageStatus.Loading _stageStatus.value = StageStatus.Loading
try { try {
loadRepositoryStatus(git)
loadHasUncommitedChanges(git) loadHasUncommitedChanges(git)
val currentBranch = branchesManager.currentBranchRef(git) val currentBranch = branchesManager.currentBranchRef(git)
val repositoryState = git.repository.repositoryState
val staged = git.diff().apply { val staged = git.diff().apply {
if(currentBranch == null) if(currentBranch == null && repositoryState != RepositoryState.MERGING && !repositoryState.isRebasing )
setOldTree(EmptyTreeIterator()) // Required if the repository is empty setOldTree(EmptyTreeIterator()) // Required if the repository is empty
setCached(true) 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() ensureActive()
val unstaged = git val unstaged = git
.diff() .diff()
.call() .call()
.groupBy { it.oldPath }
.map {
val entries = it.value
if(entries.count() > 1)
entries.filter { it.newPath != "/dev/null" }
else
entries
}.flatten()
ensureActive() ensureActive()
_stageStatus.value = StageStatus.Loaded(staged, unstaged) _stageStatus.value = StageStatus.Loaded(staged, unstaged)

View File

@ -48,6 +48,7 @@ import app.ui.dialogs.NewBranchDialog
import app.ui.dialogs.NewTagDialog import app.ui.dialogs.NewTagDialog
import app.ui.dialogs.ResetBranchDialog import app.ui.dialogs.ResetBranchDialog
import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.lib.RepositoryState
import org.eclipse.jgit.revwalk.RevCommit import org.eclipse.jgit.revwalk.RevCommit
private val colors = listOf( private val colors = listOf(
@ -75,7 +76,7 @@ fun Log(
) { ) {
val logStatusState = gitManager.logStatus.collectAsState() val logStatusState = gitManager.logStatus.collectAsState()
val logStatus = logStatusState.value val logStatus = logStatusState.value
val repositoryState by gitManager.repositoryState.collectAsState()
val showLogDialog = remember { mutableStateOf<LogDialog>(LogDialog.None) } val showLogDialog = remember { mutableStateOf<LogDialog>(LogDialog.None) }
val selectedCommit = if (selectedItem is SelectedItem.CommitBasedItem) { val selectedCommit = if (selectedItem is SelectedItem.CommitBasedItem) {
@ -137,6 +138,7 @@ fun Log(
hasPreviousCommits = commitList.count() > 0, hasPreviousCommits = commitList.count() > 0,
graphWidth = graphWidth, graphWidth = graphWidth,
weightMod = weightMod, weightMod = weightMod,
repositoryState = repositoryState,
onUncommitedChangesSelected = { onUncommitedChangesSelected = {
onItemSelected(SelectedItem.UncommitedChanges) onItemSelected(SelectedItem.UncommitedChanges)
} }
@ -263,7 +265,8 @@ fun UncommitedChangesLine(
hasPreviousCommits: Boolean, hasPreviousCommits: Boolean,
graphWidth: Dp, graphWidth: Dp,
weightMod: MutableState<Float>, weightMod: MutableState<Float>,
onUncommitedChangesSelected: () -> Unit onUncommitedChangesSelected: () -> Unit,
repositoryState: RepositoryState
) { ) {
val textColor = if (selected) { val textColor = if (selected) {
MaterialTheme.colors.primary MaterialTheme.colors.primary
@ -295,13 +298,19 @@ fun UncommitedChangesLine(
) )
Column( Column(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxHeight(),
verticalArrangement = Arrangement.Center, verticalArrangement = Arrangement.Center,
) { ) {
Spacer(modifier = Modifier.weight(2f)) 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(
text = "Uncommited changes", text = text,
fontStyle = FontStyle.Italic, fontStyle = FontStyle.Italic,
modifier = Modifier.padding(start = 16.dp), modifier = Modifier.padding(start = 16.dp),
fontSize = 14.sp, fontSize = 14.sp,
@ -748,5 +757,4 @@ fun RefChip(
} }
} }
} }
} }