Improved git diff performance by using coroutines
This commit is contained in:
parent
54092ba112
commit
fe915f68d1
3 changed files with 53 additions and 31 deletions
|
@ -5,9 +5,13 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -19,10 +23,13 @@ import theme.primaryTextColor
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Diff(gitManager: GitManager, diffEntryType: DiffEntryType, onCloseDiffView: () -> Unit) {
|
fun Diff(gitManager: GitManager, diffEntryType: DiffEntryType, onCloseDiffView: () -> Unit) {
|
||||||
val text = remember(diffEntryType.diffEntry) {
|
var text by remember { mutableStateOf(listOf<String>()) }
|
||||||
gitManager.diffFormat(diffEntryType)
|
|
||||||
|
LaunchedEffect(diffEntryType.diffEntry) {
|
||||||
|
text = gitManager.diffFormat(diffEntryType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
import git.*
|
import git.*
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
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
|
||||||
|
@ -24,6 +21,7 @@ class GitManager {
|
||||||
private val remoteOperationsManager = RemoteOperationsManager()
|
private val remoteOperationsManager = RemoteOperationsManager()
|
||||||
private val branchesManager = BranchesManager()
|
private val branchesManager = BranchesManager()
|
||||||
private val stashManager = StashManager()
|
private val stashManager = StashManager()
|
||||||
|
private val diffManager = DiffManager()
|
||||||
|
|
||||||
private val managerScope = CoroutineScope(SupervisorJob())
|
private val managerScope = CoroutineScope(SupervisorJob())
|
||||||
|
|
||||||
|
@ -126,31 +124,8 @@ class GitManager {
|
||||||
val hasUncommitedChanges: StateFlow<Boolean>
|
val hasUncommitedChanges: StateFlow<Boolean>
|
||||||
get() = statusManager.hasUncommitedChanges
|
get() = statusManager.hasUncommitedChanges
|
||||||
|
|
||||||
fun diffFormat(diffEntryType: DiffEntryType): List<String> {
|
suspend fun diffFormat(diffEntryType: DiffEntryType): List<String> {
|
||||||
val diffEntry = diffEntryType.diffEntry
|
return diffManager.diffFormat(safeGit, diffEntryType)
|
||||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
|
||||||
|
|
||||||
DiffFormatter(byteArrayOutputStream).use { formatter ->
|
|
||||||
val repo = safeGit.repository
|
|
||||||
formatter.setRepository(repo)
|
|
||||||
|
|
||||||
val oldTree = DirCacheIterator(repo.readDirCache())
|
|
||||||
val newTree = FileTreeIterator(repo)
|
|
||||||
|
|
||||||
if (diffEntryType is DiffEntryType.UnstagedDiff)
|
|
||||||
formatter.scan(oldTree, newTree)
|
|
||||||
|
|
||||||
formatter.format(diffEntry)
|
|
||||||
formatter.flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
val diff = byteArrayOutputStream.toString(Charsets.UTF_8)
|
|
||||||
|
|
||||||
// TODO This is just a workaround, try to find properly which lines have to be displayed by using a custom diff
|
|
||||||
|
|
||||||
return diff.split("\n", "\r\n").filterNot {
|
|
||||||
it.startsWith("diff --git")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun pull() = managerScope.launch {
|
fun pull() = managerScope.launch {
|
||||||
|
|
40
src/main/kotlin/git/DiffManager.kt
Normal file
40
src/main/kotlin/git/DiffManager.kt
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
package git
|
||||||
|
|
||||||
|
import DiffEntryType
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.eclipse.jgit.api.Git
|
||||||
|
import org.eclipse.jgit.diff.DiffFormatter
|
||||||
|
import org.eclipse.jgit.dircache.DirCacheIterator
|
||||||
|
import org.eclipse.jgit.treewalk.FileTreeIterator
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
|
class DiffManager {
|
||||||
|
suspend fun diffFormat(git: Git, diffEntryType: DiffEntryType): List<String> = withContext(Dispatchers.IO) {
|
||||||
|
val diffEntry = diffEntryType.diffEntry
|
||||||
|
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||||
|
|
||||||
|
DiffFormatter(byteArrayOutputStream).use { formatter ->
|
||||||
|
val repo = git.repository
|
||||||
|
formatter.setRepository(repo)
|
||||||
|
|
||||||
|
val oldTree = DirCacheIterator(repo.readDirCache())
|
||||||
|
val newTree = FileTreeIterator(repo)
|
||||||
|
|
||||||
|
if (diffEntryType is DiffEntryType.UnstagedDiff)
|
||||||
|
formatter.scan(oldTree, newTree)
|
||||||
|
|
||||||
|
formatter.format(diffEntry)
|
||||||
|
formatter.flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
val diff = byteArrayOutputStream.toString(Charsets.UTF_8)
|
||||||
|
|
||||||
|
// TODO This is just a workaround, try to find properly which lines have to be displayed by using a custom diff
|
||||||
|
|
||||||
|
return@withContext diff.split("\n", "\r\n").filterNot {
|
||||||
|
it.startsWith("diff --git")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue