diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/git/workspace/StageHunkLineUseCase.kt b/src/main/kotlin/com/jetpackduba/gitnuro/git/workspace/StageHunkLineUseCase.kt index 4dc2d3d..0421698 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/git/workspace/StageHunkLineUseCase.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/git/workspace/StageHunkLineUseCase.kt @@ -16,7 +16,7 @@ class StageHunkLineUseCase @Inject constructor( private val rawFileManager: RawFileManager, private val getLinesFromRawTextUseCase: GetLinesFromRawTextUseCase, ) { - suspend operator fun invoke(git: Git, diffEntry: DiffEntry, hunk: Hunk, lineToStage: Line) = + suspend operator fun invoke(git: Git, diffEntry: DiffEntry, hunk: Hunk, line: Line) = withContext(Dispatchers.IO) { val repository = git.repository val dirCache = repository.lockDirCache() @@ -37,20 +37,19 @@ class StageHunkLineUseCase @Inject constructor( val textLines = getLinesFromRawTextUseCase(entryContent.rawText).toMutableList() - - when (lineToStage.lineType) { + when (line.lineType) { LineType.ADDED -> { val previousContextLine = hunk.lines - .takeWhile { it != lineToStage } + .takeWhile { it != line } .lastOrNull { it.lineType == LineType.CONTEXT } val startingIndex = previousContextLine?.oldLineNumber ?: -1 - textLines.add(startingIndex + 1, lineToStage.text) + textLines.add(startingIndex + 1, line.text) } LineType.REMOVED -> { - textLines.removeAt(lineToStage.oldLineNumber) + textLines.removeAt(line.oldLineNumber) } else -> {} diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/git/workspace/UnstageHunkLineUseCase.kt b/src/main/kotlin/com/jetpackduba/gitnuro/git/workspace/UnstageHunkLineUseCase.kt new file mode 100644 index 0000000..a474806 --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/git/workspace/UnstageHunkLineUseCase.kt @@ -0,0 +1,75 @@ +package com.jetpackduba.gitnuro.git.workspace + +import com.jetpackduba.gitnuro.git.EntryContent +import com.jetpackduba.gitnuro.git.RawFileManager +import com.jetpackduba.gitnuro.git.diff.Hunk +import com.jetpackduba.gitnuro.git.diff.Line +import com.jetpackduba.gitnuro.git.diff.LineType +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.diff.DiffEntry +import java.nio.ByteBuffer +import javax.inject.Inject + +class UnstageHunkLineUseCase @Inject constructor( + private val rawFileManager: RawFileManager, + private val getLinesFromRawTextUseCase: GetLinesFromRawTextUseCase, +) { + suspend operator fun invoke(git: Git, diffEntry: DiffEntry, hunk: Hunk, line: Line) = + withContext(Dispatchers.IO) { + val repository = git.repository + val dirCache = repository.lockDirCache() + val dirCacheEditor = dirCache.editor() + var completedWithErrors = true + + try { + val entryContent = rawFileManager.getRawContent( + repository = repository, + side = DiffEntry.Side.NEW, + entry = diffEntry, + oldTreeIterator = null, + newTreeIterator = null + ) + + if (entryContent !is EntryContent.Text) + return@withContext + + val textLines = getLinesFromRawTextUseCase(entryContent.rawText).toMutableList() + + when (line.lineType) { + LineType.REMOVED -> { + val previousContextLine = hunk.lines + .takeWhile { it != line } + .lastOrNull { it.lineType != LineType.REMOVED } + + val startingIndex = previousContextLine?.newLineNumber ?: -1 + + textLines.add(startingIndex + 1, line.text) + } + + LineType.ADDED -> { + textLines.removeAt(line.newLineNumber) + } + + else -> {} + } + + val stagedFileText = textLines.joinToString("") + dirCacheEditor.add( + HunkEdit( + diffEntry.newPath, + repository, + ByteBuffer.wrap(stagedFileText.toByteArray()) + ) + ) + dirCacheEditor.commit() + + completedWithErrors = false + } finally { + if (completedWithErrors) + dirCache.unlock() + } + } +} + diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/DiffViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/DiffViewModel.kt index 1aac8bf..a0a397f 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/DiffViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/DiffViewModel.kt @@ -25,6 +25,7 @@ class DiffViewModel @Inject constructor( private val stageHunkUseCase: StageHunkUseCase, private val unstageHunkUseCase: UnstageHunkUseCase, private val stageHunkLineUseCase: StageHunkLineUseCase, + private val unstageHunkLineUseCase: UnstageHunkLineUseCase, private val resetHunkUseCase: ResetHunkUseCase, private val stageEntryUseCase: StageEntryUseCase, private val unstageEntryUseCase: UnstageEntryUseCase, @@ -169,7 +170,7 @@ class DiffViewModel @Inject constructor( refreshType = RefreshType.UNCOMMITED_CHANGES, showError = true, ) { git -> - throw NotImplementedError() + unstageHunkLineUseCase(git, entry, hunk, line) } }