Added option to discard hunks
This commit is contained in:
parent
1835ff748d
commit
15827d119a
@ -29,3 +29,14 @@ val String.dirPath: String
|
||||
} else
|
||||
this
|
||||
}
|
||||
|
||||
|
||||
val String.lineDelimiter: String?
|
||||
get() {
|
||||
return if (this.contains("\r\n"))
|
||||
"\r\n"
|
||||
else if (this.contains("\n"))
|
||||
"\n"
|
||||
else
|
||||
null
|
||||
}
|
@ -20,6 +20,8 @@ import org.eclipse.jgit.lib.FileMode
|
||||
import org.eclipse.jgit.lib.ObjectInserter
|
||||
import org.eclipse.jgit.lib.Repository
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.File
|
||||
import java.io.FileWriter
|
||||
import java.io.IOException
|
||||
import java.nio.ByteBuffer
|
||||
import java.time.Instant
|
||||
@ -145,6 +147,10 @@ class StatusManager @Inject constructor(
|
||||
val content = rawFile.rawContent.toString(Charsets.UTF_8)//.removeSuffix(rawFile.lineDelimiter)
|
||||
val lineDelimiter: String? = rawFile.lineDelimiter
|
||||
|
||||
return getTextLines(content, lineDelimiter)
|
||||
}
|
||||
|
||||
private fun getTextLines(content: String, lineDelimiter: String?): List<String> {
|
||||
var splitted: List<String> = if (lineDelimiter != null) {
|
||||
content.split(lineDelimiter).toMutableList().apply {
|
||||
if (this.last() == "")
|
||||
@ -344,6 +350,52 @@ class StatusManager @Inject constructor(
|
||||
addCommand.call()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun resetHunk(git: Git, diffEntry: DiffEntry, hunk: Hunk) = withContext(Dispatchers.IO) {
|
||||
val repository = git.repository
|
||||
|
||||
try {
|
||||
val file = File(repository.directory.parent, diffEntry.oldPath)
|
||||
|
||||
val content = file.readText()
|
||||
val textLines = getTextLines(content, content.lineDelimiter).toMutableList()
|
||||
val hunkLines = hunk.lines.filter { it.lineType != LineType.CONTEXT }
|
||||
|
||||
val addedLines = hunkLines
|
||||
.filter { it.lineType == LineType.ADDED }
|
||||
.sortedBy { it.newLineNumber }
|
||||
val removedLines = hunkLines
|
||||
.filter { it.lineType == LineType.REMOVED }
|
||||
.sortedBy { it.newLineNumber }
|
||||
|
||||
var linesRemoved = 0
|
||||
|
||||
// Start by removing the added lines to the index
|
||||
for (line in addedLines) {
|
||||
textLines.removeAt(line.newLineNumber + linesRemoved)
|
||||
linesRemoved--
|
||||
}
|
||||
|
||||
var linesAdded = 0
|
||||
|
||||
// Restore previously removed lines to the index
|
||||
for (line in removedLines) {
|
||||
// Check how many lines before this one have been deleted
|
||||
val previouslyRemovedLines = addedLines.count { it.newLineNumber < line.newLineNumber }
|
||||
textLines.add(line.newLineNumber + linesAdded - previouslyRemovedLines, line.text)
|
||||
linesAdded++
|
||||
}
|
||||
|
||||
val stagedFileText = textLines.joinToString("")
|
||||
|
||||
|
||||
FileWriter(file).use { fw ->
|
||||
fw.write(stagedFileText)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
throw Exception("Discard hunk failed. Check if the file still exists and has the write permissions set", ex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,9 +105,13 @@ fun Diff(
|
||||
onUnstageHunk = { entry, hunk ->
|
||||
diffViewModel.unstageHunk(entry, hunk)
|
||||
},
|
||||
) { entry, hunk ->
|
||||
diffViewModel.stageHunk(entry, hunk)
|
||||
}
|
||||
onStageHunk = { entry, hunk ->
|
||||
diffViewModel.stageHunk(entry, hunk)
|
||||
},
|
||||
onResetHunk = { entry, hunk ->
|
||||
diffViewModel.resetHunk(entry, hunk)
|
||||
}
|
||||
)
|
||||
} else if (diffResult is DiffResult.NonText) {
|
||||
NonTextDiff(diffResult)
|
||||
}
|
||||
@ -220,6 +224,7 @@ fun TextDiff(
|
||||
diffResult: DiffResult.Text,
|
||||
onUnstageHunk: (DiffEntry, Hunk) -> Unit,
|
||||
onStageHunk: (DiffEntry, Hunk) -> Unit,
|
||||
onResetHunk: (DiffEntry, Hunk) -> Unit,
|
||||
) {
|
||||
val hunks = diffResult.hunks
|
||||
|
||||
@ -237,6 +242,7 @@ fun TextDiff(
|
||||
diffEntryType = diffEntryType,
|
||||
onUnstageHunk = { onUnstageHunk(diffResult.diffEntry, hunk) },
|
||||
onStageHunk = { onStageHunk(diffResult.diffEntry, hunk) },
|
||||
onResetHunk = { onResetHunk(diffResult.diffEntry, hunk) },
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -261,6 +267,7 @@ fun HunkHeader(
|
||||
diffEntryType: DiffEntryType,
|
||||
onUnstageHunk: () -> Unit,
|
||||
onStageHunk: () -> Unit,
|
||||
onResetHunk: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@ -293,6 +300,14 @@ fun HunkHeader(
|
||||
color = MaterialTheme.colors.stageButton
|
||||
}
|
||||
|
||||
if(diffEntryType is DiffEntryType.UnstagedDiff) {
|
||||
SecondaryButton(
|
||||
text = "Discard hunk",
|
||||
backgroundButton = MaterialTheme.colors.error,
|
||||
onClick = onResetHunk
|
||||
)
|
||||
}
|
||||
|
||||
SecondaryButton(
|
||||
text = buttonText,
|
||||
backgroundButton = color,
|
||||
|
@ -173,7 +173,8 @@ fun HistoryContentLoaded(
|
||||
scrollState = scrollState,
|
||||
diffResult = diffResult,
|
||||
onUnstageHunk = { _, _ -> },
|
||||
onStageHunk = { _, _ -> }
|
||||
onStageHunk = { _, _ -> },
|
||||
onResetHunk = { _, _ -> },
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
|
@ -73,6 +73,13 @@ class DiffViewModel @Inject constructor(
|
||||
statusManager.stageHunk(git, diffEntry, hunk)
|
||||
}
|
||||
|
||||
fun resetHunk(diffEntry: DiffEntry, hunk: Hunk) = tabState.runOperation(
|
||||
refreshType = RefreshType.UNCOMMITED_CHANGES,
|
||||
showError = true,
|
||||
) { git ->
|
||||
statusManager.resetHunk(git, diffEntry, hunk)
|
||||
}
|
||||
|
||||
fun unstageHunk(diffEntry: DiffEntry, hunk: Hunk) = tabState.runOperation(
|
||||
refreshType = RefreshType.UNCOMMITED_CHANGES,
|
||||
) { git ->
|
||||
|
Loading…
Reference in New Issue
Block a user