Added option to discard hunks
This commit is contained in:
parent
1835ff748d
commit
15827d119a
@ -29,3 +29,14 @@ val String.dirPath: String
|
|||||||
} else
|
} else
|
||||||
this
|
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.ObjectInserter
|
||||||
import org.eclipse.jgit.lib.Repository
|
import org.eclipse.jgit.lib.Repository
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileWriter
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@ -145,6 +147,10 @@ class StatusManager @Inject constructor(
|
|||||||
val content = rawFile.rawContent.toString(Charsets.UTF_8)//.removeSuffix(rawFile.lineDelimiter)
|
val content = rawFile.rawContent.toString(Charsets.UTF_8)//.removeSuffix(rawFile.lineDelimiter)
|
||||||
val lineDelimiter: String? = 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) {
|
var splitted: List<String> = if (lineDelimiter != null) {
|
||||||
content.split(lineDelimiter).toMutableList().apply {
|
content.split(lineDelimiter).toMutableList().apply {
|
||||||
if (this.last() == "")
|
if (this.last() == "")
|
||||||
@ -344,6 +350,52 @@ class StatusManager @Inject constructor(
|
|||||||
addCommand.call()
|
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 ->
|
onUnstageHunk = { entry, hunk ->
|
||||||
diffViewModel.unstageHunk(entry, hunk)
|
diffViewModel.unstageHunk(entry, hunk)
|
||||||
},
|
},
|
||||||
) { entry, hunk ->
|
onStageHunk = { entry, hunk ->
|
||||||
diffViewModel.stageHunk(entry, hunk)
|
diffViewModel.stageHunk(entry, hunk)
|
||||||
}
|
},
|
||||||
|
onResetHunk = { entry, hunk ->
|
||||||
|
diffViewModel.resetHunk(entry, hunk)
|
||||||
|
}
|
||||||
|
)
|
||||||
} else if (diffResult is DiffResult.NonText) {
|
} else if (diffResult is DiffResult.NonText) {
|
||||||
NonTextDiff(diffResult)
|
NonTextDiff(diffResult)
|
||||||
}
|
}
|
||||||
@ -220,6 +224,7 @@ fun TextDiff(
|
|||||||
diffResult: DiffResult.Text,
|
diffResult: DiffResult.Text,
|
||||||
onUnstageHunk: (DiffEntry, Hunk) -> Unit,
|
onUnstageHunk: (DiffEntry, Hunk) -> Unit,
|
||||||
onStageHunk: (DiffEntry, Hunk) -> Unit,
|
onStageHunk: (DiffEntry, Hunk) -> Unit,
|
||||||
|
onResetHunk: (DiffEntry, Hunk) -> Unit,
|
||||||
) {
|
) {
|
||||||
val hunks = diffResult.hunks
|
val hunks = diffResult.hunks
|
||||||
|
|
||||||
@ -237,6 +242,7 @@ fun TextDiff(
|
|||||||
diffEntryType = diffEntryType,
|
diffEntryType = diffEntryType,
|
||||||
onUnstageHunk = { onUnstageHunk(diffResult.diffEntry, hunk) },
|
onUnstageHunk = { onUnstageHunk(diffResult.diffEntry, hunk) },
|
||||||
onStageHunk = { onStageHunk(diffResult.diffEntry, hunk) },
|
onStageHunk = { onStageHunk(diffResult.diffEntry, hunk) },
|
||||||
|
onResetHunk = { onResetHunk(diffResult.diffEntry, hunk) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,6 +267,7 @@ fun HunkHeader(
|
|||||||
diffEntryType: DiffEntryType,
|
diffEntryType: DiffEntryType,
|
||||||
onUnstageHunk: () -> Unit,
|
onUnstageHunk: () -> Unit,
|
||||||
onStageHunk: () -> Unit,
|
onStageHunk: () -> Unit,
|
||||||
|
onResetHunk: () -> Unit,
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@ -293,6 +300,14 @@ fun HunkHeader(
|
|||||||
color = MaterialTheme.colors.stageButton
|
color = MaterialTheme.colors.stageButton
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(diffEntryType is DiffEntryType.UnstagedDiff) {
|
||||||
|
SecondaryButton(
|
||||||
|
text = "Discard hunk",
|
||||||
|
backgroundButton = MaterialTheme.colors.error,
|
||||||
|
onClick = onResetHunk
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
SecondaryButton(
|
SecondaryButton(
|
||||||
text = buttonText,
|
text = buttonText,
|
||||||
backgroundButton = color,
|
backgroundButton = color,
|
||||||
|
@ -173,7 +173,8 @@ fun HistoryContentLoaded(
|
|||||||
scrollState = scrollState,
|
scrollState = scrollState,
|
||||||
diffResult = diffResult,
|
diffResult = diffResult,
|
||||||
onUnstageHunk = { _, _ -> },
|
onUnstageHunk = { _, _ -> },
|
||||||
onStageHunk = { _, _ -> }
|
onStageHunk = { _, _ -> },
|
||||||
|
onResetHunk = { _, _ -> },
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Box(
|
Box(
|
||||||
|
@ -73,6 +73,13 @@ class DiffViewModel @Inject constructor(
|
|||||||
statusManager.stageHunk(git, diffEntry, hunk)
|
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(
|
fun unstageHunk(diffEntry: DiffEntry, hunk: Hunk) = tabState.runOperation(
|
||||||
refreshType = RefreshType.UNCOMMITED_CHANGES,
|
refreshType = RefreshType.UNCOMMITED_CHANGES,
|
||||||
) { git ->
|
) { git ->
|
||||||
|
Loading…
Reference in New Issue
Block a user