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
src/main/kotlin
|
@ -5,9 +5,13 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
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.material.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
@ -19,10 +23,13 @@ import theme.primaryTextColor
|
|||
|
||||
@Composable
|
||||
fun Diff(gitManager: GitManager, diffEntryType: DiffEntryType, onCloseDiffView: () -> Unit) {
|
||||
val text = remember(diffEntryType.diffEntry) {
|
||||
gitManager.diffFormat(diffEntryType)
|
||||
var text by remember { mutableStateOf(listOf<String>()) }
|
||||
|
||||
LaunchedEffect(diffEntryType.diffEntry) {
|
||||
text = gitManager.diffFormat(diffEntryType)
|
||||
}
|
||||
|
||||
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import git.*
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.diff.DiffEntry
|
||||
import org.eclipse.jgit.diff.DiffFormatter
|
||||
|
@ -24,6 +21,7 @@ class GitManager {
|
|||
private val remoteOperationsManager = RemoteOperationsManager()
|
||||
private val branchesManager = BranchesManager()
|
||||
private val stashManager = StashManager()
|
||||
private val diffManager = DiffManager()
|
||||
|
||||
private val managerScope = CoroutineScope(SupervisorJob())
|
||||
|
||||
|
@ -126,31 +124,8 @@ class GitManager {
|
|||
val hasUncommitedChanges: StateFlow<Boolean>
|
||||
get() = statusManager.hasUncommitedChanges
|
||||
|
||||
fun diffFormat(diffEntryType: DiffEntryType): List<String> {
|
||||
val diffEntry = diffEntryType.diffEntry
|
||||
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")
|
||||
}
|
||||
suspend fun diffFormat(diffEntryType: DiffEntryType): List<String> {
|
||||
return diffManager.diffFormat(safeGit, diffEntryType)
|
||||
}
|
||||
|
||||
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