Refactored rebase interactive to make it easier to implement additional features
This commit is contained in:
parent
15507afd4c
commit
1e012d759b
@ -16,8 +16,14 @@ class ResumeRebaseInteractiveUseCase @Inject constructor() {
|
|||||||
.setOperation(RebaseCommand.Operation.PROCESS_STEPS)
|
.setOperation(RebaseCommand.Operation.PROCESS_STEPS)
|
||||||
.call()
|
.call()
|
||||||
|
|
||||||
if (rebaseResult.status == RebaseResult.Status.FAILED) {
|
|
||||||
throw UncommitedChangesDetectedException("Rebase interactive failed.")
|
when (rebaseResult.status) {
|
||||||
|
RebaseResult.Status.FAILED -> throw UncommitedChangesDetectedException("Rebase interactive failed.")
|
||||||
|
RebaseResult.Status.UNCOMMITTED_CHANGES, RebaseResult.Status.CONFLICTS -> throw UncommitedChangesDetectedException(
|
||||||
|
"You can't have uncommited changes before starting a rebase interactive"
|
||||||
|
)
|
||||||
|
|
||||||
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,19 +1,30 @@
|
|||||||
package com.jetpackduba.gitnuro.git.rebase
|
package com.jetpackduba.gitnuro.git.rebase
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.exceptions.UncommitedChangesDetectedException
|
import com.jetpackduba.gitnuro.exceptions.UncommitedChangesDetectedException
|
||||||
|
import com.jetpackduba.gitnuro.logging.printDebug
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.api.RebaseCommand
|
import org.eclipse.jgit.api.RebaseCommand
|
||||||
import org.eclipse.jgit.api.RebaseResult
|
import org.eclipse.jgit.api.RebaseResult
|
||||||
|
import org.eclipse.jgit.lib.RebaseTodoLine
|
||||||
import org.eclipse.jgit.revwalk.RevCommit
|
import org.eclipse.jgit.revwalk.RevCommit
|
||||||
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
private const val GIT_REBASE_TODO = "git-rebase-todo"
|
||||||
|
private const val TAG = "StartRebaseInteractiveU"
|
||||||
|
|
||||||
class StartRebaseInteractiveUseCase @Inject constructor() {
|
class StartRebaseInteractiveUseCase @Inject constructor() {
|
||||||
suspend operator fun invoke(git: Git, interactiveHandler: RebaseCommand.InteractiveHandler, commit: RevCommit) =
|
suspend operator fun invoke(
|
||||||
|
git: Git,
|
||||||
|
interactiveHandler: RebaseCommand.InteractiveHandler,
|
||||||
|
commit: RevCommit,
|
||||||
|
stop: Boolean
|
||||||
|
): List<RebaseTodoLine> =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val rebaseResult = git.rebase()
|
val rebaseResult = git.rebase()
|
||||||
.runInteractively(interactiveHandler)
|
.runInteractively(interactiveHandler, stop)
|
||||||
.setOperation(RebaseCommand.Operation.BEGIN)
|
.setOperation(RebaseCommand.Operation.BEGIN)
|
||||||
.setUpstream(commit)
|
.setUpstream(commit)
|
||||||
.call()
|
.call()
|
||||||
@ -26,5 +37,12 @@ class StartRebaseInteractiveUseCase @Inject constructor() {
|
|||||||
|
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val repository = git.repository
|
||||||
|
val lines = repository.readRebaseTodo("${RebaseCommand.REBASE_MERGE}/$GIT_REBASE_TODO", false)
|
||||||
|
|
||||||
|
printDebug(TAG, "There are ${lines.count()} lines")
|
||||||
|
|
||||||
|
return@withContext lines
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,8 +15,10 @@ import com.jetpackduba.gitnuro.AppIcons
|
|||||||
import com.jetpackduba.gitnuro.ui.components.AdjustableOutlinedTextField
|
import com.jetpackduba.gitnuro.ui.components.AdjustableOutlinedTextField
|
||||||
import com.jetpackduba.gitnuro.ui.components.PrimaryButton
|
import com.jetpackduba.gitnuro.ui.components.PrimaryButton
|
||||||
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
||||||
|
import com.jetpackduba.gitnuro.viewmodels.RebaseAction
|
||||||
import com.jetpackduba.gitnuro.viewmodels.RebaseInteractiveState
|
import com.jetpackduba.gitnuro.viewmodels.RebaseInteractiveState
|
||||||
import com.jetpackduba.gitnuro.viewmodels.RebaseInteractiveViewModel
|
import com.jetpackduba.gitnuro.viewmodels.RebaseInteractiveViewModel
|
||||||
|
import com.jetpackduba.gitnuro.viewmodels.RebaseLine
|
||||||
import org.eclipse.jgit.lib.RebaseTodoLine
|
import org.eclipse.jgit.lib.RebaseTodoLine
|
||||||
import org.eclipse.jgit.lib.RebaseTodoLine.Action
|
import org.eclipse.jgit.lib.RebaseTodoLine.Action
|
||||||
|
|
||||||
@ -99,7 +101,7 @@ fun RebaseStateLoaded(
|
|||||||
)
|
)
|
||||||
PrimaryButton(
|
PrimaryButton(
|
||||||
modifier = Modifier.padding(end = 16.dp),
|
modifier = Modifier.padding(end = 16.dp),
|
||||||
enabled = stepsList.any { it.action != Action.PICK },
|
enabled = stepsList.any { it.rebaseAction != RebaseAction.PICK },
|
||||||
onClick = {
|
onClick = {
|
||||||
rebaseInteractiveViewModel.continueRebaseInteractive()
|
rebaseInteractiveViewModel.continueRebaseInteractive()
|
||||||
},
|
},
|
||||||
@ -111,15 +113,15 @@ fun RebaseStateLoaded(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RebaseCommit(
|
fun RebaseCommit(
|
||||||
rebaseLine: RebaseTodoLine,
|
rebaseLine: RebaseLine,
|
||||||
isFirst: Boolean,
|
isFirst: Boolean,
|
||||||
message: String?,
|
message: String?,
|
||||||
onActionChanged: (Action) -> Unit,
|
onActionChanged: (RebaseAction) -> Unit,
|
||||||
onMessageChanged: (String) -> Unit,
|
onMessageChanged: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
val action = rebaseLine.action
|
val action = rebaseLine.rebaseAction
|
||||||
var newMessage by remember(rebaseLine.commit.name(), action) {
|
var newMessage by remember(rebaseLine.commit.name(), action) {
|
||||||
if (action == Action.REWORD) {
|
if (action == RebaseAction.REWORD) {
|
||||||
mutableStateOf(message ?: rebaseLine.shortMessage) /* if reword, use the value from the map (if possible)*/
|
mutableStateOf(message ?: rebaseLine.shortMessage) /* if reword, use the value from the map (if possible)*/
|
||||||
} else
|
} else
|
||||||
mutableStateOf(rebaseLine.shortMessage) // If it's not reword, use the original shortMessage
|
mutableStateOf(rebaseLine.shortMessage) // If it's not reword, use the original shortMessage
|
||||||
@ -132,7 +134,7 @@ fun RebaseCommit(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
ActionDropdown(
|
ActionDropdown(
|
||||||
rebaseLine.action,
|
action,
|
||||||
isFirst = isFirst,
|
isFirst = isFirst,
|
||||||
onActionChanged = onActionChanged,
|
onActionChanged = onActionChanged,
|
||||||
)
|
)
|
||||||
@ -141,14 +143,14 @@ fun RebaseCommit(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.heightIn(min = 40.dp),
|
.heightIn(min = 40.dp),
|
||||||
enabled = rebaseLine.action == Action.REWORD,
|
enabled = action == RebaseAction.REWORD,
|
||||||
value = newMessage,
|
value = newMessage,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
newMessage = it
|
newMessage = it
|
||||||
onMessageChanged(it)
|
onMessageChanged(it)
|
||||||
},
|
},
|
||||||
textStyle = MaterialTheme.typography.body2,
|
textStyle = MaterialTheme.typography.body2,
|
||||||
backgroundColor = if (rebaseLine.action == Action.REWORD) {
|
backgroundColor = if (action == RebaseAction.REWORD) {
|
||||||
MaterialTheme.colors.background
|
MaterialTheme.colors.background
|
||||||
} else
|
} else
|
||||||
MaterialTheme.colors.surface
|
MaterialTheme.colors.surface
|
||||||
@ -160,9 +162,9 @@ fun RebaseCommit(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ActionDropdown(
|
fun ActionDropdown(
|
||||||
action: Action,
|
action: RebaseAction,
|
||||||
isFirst: Boolean,
|
isFirst: Boolean,
|
||||||
onActionChanged: (Action) -> Unit,
|
onActionChanged: (RebaseAction) -> Unit,
|
||||||
) {
|
) {
|
||||||
var showDropDownMenu by remember { mutableStateOf(false) }
|
var showDropDownMenu by remember { mutableStateOf(false) }
|
||||||
Box {
|
Box {
|
||||||
@ -174,7 +176,7 @@ fun ActionDropdown(
|
|||||||
.padding(end = 8.dp),
|
.padding(end = 8.dp),
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
action.toToken().replaceFirstChar { it.uppercase() },
|
action.displayName,
|
||||||
color = MaterialTheme.colors.onBackground,
|
color = MaterialTheme.colors.onBackground,
|
||||||
style = MaterialTheme.typography.body1,
|
style = MaterialTheme.typography.body1,
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
@ -206,7 +208,7 @@ fun ActionDropdown(
|
|||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = dropDownOption.toToken().replaceFirstChar { it.uppercase() },
|
text = dropDownOption.displayName,
|
||||||
style = MaterialTheme.typography.body1,
|
style = MaterialTheme.typography.body1,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -216,15 +218,15 @@ fun ActionDropdown(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val firstItemActions = listOf(
|
val firstItemActions = listOf(
|
||||||
Action.PICK,
|
RebaseAction.PICK,
|
||||||
Action.REWORD,
|
RebaseAction.REWORD,
|
||||||
)
|
)
|
||||||
|
|
||||||
val actions = listOf(
|
val actions = listOf(
|
||||||
Action.PICK,
|
RebaseAction.PICK,
|
||||||
Action.REWORD,
|
RebaseAction.REWORD,
|
||||||
Action.SQUASH,
|
RebaseAction.SQUASH,
|
||||||
Action.FIXUP,
|
RebaseAction.FIXUP,
|
||||||
)
|
RebaseAction.EDIT,
|
||||||
|
RebaseAction.DROP,
|
||||||
|
)
|
@ -10,8 +10,6 @@ import com.jetpackduba.gitnuro.git.rebase.ResumeRebaseInteractiveUseCase
|
|||||||
import com.jetpackduba.gitnuro.git.rebase.StartRebaseInteractiveUseCase
|
import com.jetpackduba.gitnuro.git.rebase.StartRebaseInteractiveUseCase
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import org.eclipse.jgit.api.RebaseCommand.InteractiveHandler
|
import org.eclipse.jgit.api.RebaseCommand.InteractiveHandler
|
||||||
import org.eclipse.jgit.lib.AbbreviatedObjectId
|
import org.eclipse.jgit.lib.AbbreviatedObjectId
|
||||||
import org.eclipse.jgit.lib.RebaseTodoLine
|
import org.eclipse.jgit.lib.RebaseTodoLine
|
||||||
@ -28,64 +26,69 @@ class RebaseInteractiveViewModel @Inject constructor(
|
|||||||
private val abortRebaseUseCase: AbortRebaseUseCase,
|
private val abortRebaseUseCase: AbortRebaseUseCase,
|
||||||
private val resumeRebaseInteractiveUseCase: ResumeRebaseInteractiveUseCase,
|
private val resumeRebaseInteractiveUseCase: ResumeRebaseInteractiveUseCase,
|
||||||
) {
|
) {
|
||||||
private val rebaseInteractiveMutex = Mutex(true)
|
private lateinit var commit: RevCommit
|
||||||
private val _rebaseState = MutableStateFlow<RebaseInteractiveState>(RebaseInteractiveState.Loading)
|
private val _rebaseState = MutableStateFlow<RebaseInteractiveState>(RebaseInteractiveState.Loading)
|
||||||
val rebaseState: StateFlow<RebaseInteractiveState> = _rebaseState
|
val rebaseState: StateFlow<RebaseInteractiveState> = _rebaseState
|
||||||
var rewordSteps = ArrayDeque<RebaseTodoLine>()
|
var rewordSteps = ArrayDeque<RebaseLine>()
|
||||||
|
|
||||||
private var cancelled = false
|
var onRebaseComplete: () -> Unit = {}
|
||||||
private var completed = false
|
|
||||||
|
|
||||||
private var interactiveHandler = object : InteractiveHandler {
|
|
||||||
override fun prepareSteps(steps: MutableList<RebaseTodoLine>) = runBlocking {
|
|
||||||
println("prepareSteps started")
|
|
||||||
tabState.refreshData(RefreshType.REPO_STATE)
|
|
||||||
|
|
||||||
val messages = getRebaseLinesFullMessageUseCase(tabState.git, steps)
|
|
||||||
|
|
||||||
_rebaseState.value = RebaseInteractiveState.Loaded(steps, messages)
|
|
||||||
|
|
||||||
println("prepareSteps mutex lock")
|
|
||||||
rebaseInteractiveMutex.lock()
|
|
||||||
|
|
||||||
if (cancelled) {
|
|
||||||
throw RebaseCancelledException("Rebase cancelled due to user request")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private var interactiveHandlerContinue = object : InteractiveHandler {
|
||||||
|
override fun prepareSteps(steps: MutableList<RebaseTodoLine>) {
|
||||||
val rebaseState = _rebaseState.value
|
val rebaseState = _rebaseState.value
|
||||||
if (rebaseState !is RebaseInteractiveState.Loaded) {
|
if (rebaseState !is RebaseInteractiveState.Loaded) {
|
||||||
throw Exception("prepareSteps called when rebaseState is not Loaded") // Should never happen, just in case
|
throw Exception("prepareSteps called when rebaseState is not Loaded") // Should never happen, just in case
|
||||||
}
|
}
|
||||||
|
|
||||||
val newSteps = rebaseState.stepsList
|
val newSteps = rebaseState.stepsList.toMutableList()
|
||||||
rewordSteps = ArrayDeque(newSteps.filter { it.action == Action.REWORD })
|
rewordSteps = ArrayDeque(newSteps.filter { it.rebaseAction == RebaseAction.REWORD })
|
||||||
|
|
||||||
|
val newRebaseTodoLines = newSteps
|
||||||
|
.filter { it.rebaseAction != RebaseAction.DROP } // Remove dropped lines
|
||||||
|
.map { it.toRebaseTodoLine() }
|
||||||
|
|
||||||
steps.clear()
|
steps.clear()
|
||||||
steps.addAll(newSteps)
|
steps.addAll(newRebaseTodoLines)
|
||||||
println("prepareSteps finished")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun modifyCommitMessage(commit: String): String = runBlocking {
|
override fun modifyCommitMessage(commit: String): String {
|
||||||
// This can be called when there aren't any reword steps if squash is used.
|
// This can be called when there aren't any reword steps if squash is used.
|
||||||
val step = rewordSteps.removeLastOrNull() ?: return@runBlocking commit
|
val step = rewordSteps.removeLastOrNull() ?: return commit
|
||||||
|
|
||||||
val rebaseState = _rebaseState.value
|
val rebaseState = _rebaseState.value
|
||||||
if (rebaseState !is RebaseInteractiveState.Loaded) {
|
if (rebaseState !is RebaseInteractiveState.Loaded) {
|
||||||
throw Exception("modifyCommitMessage called when rebaseState is not Loaded") // Should never happen, just in case
|
throw Exception("modifyCommitMessage called when rebaseState is not Loaded") // Should never happen, just in case
|
||||||
}
|
}
|
||||||
|
|
||||||
return@runBlocking rebaseState.messages[step.commit.name()]
|
return rebaseState.messages[step.commit.name()]
|
||||||
?: throw InvalidMessageException("Message for commit $commit is unexpectedly null")
|
?: throw InvalidMessageException("Message for commit $commit is unexpectedly null")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun startRebaseInteractive(revCommit: RevCommit) = tabState.runOperation(
|
suspend fun startRebaseInteractive(revCommit: RevCommit) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
showError = true
|
showError = true
|
||||||
) { git ->
|
) { git ->
|
||||||
|
this@RebaseInteractiveViewModel.commit = revCommit
|
||||||
|
|
||||||
|
val interactiveHandler = object : InteractiveHandler {
|
||||||
|
override fun prepareSteps(steps: MutableList<RebaseTodoLine>?) {}
|
||||||
|
override fun modifyCommitMessage(message: String?): String = ""
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
startRebaseInteractiveUseCase(git, interactiveHandler, revCommit)
|
val lines = startRebaseInteractiveUseCase(git, interactiveHandler, revCommit, true)
|
||||||
completed = true
|
val messages = getRebaseLinesFullMessageUseCase(tabState.git, lines)
|
||||||
|
val rebaseLines = lines.map {
|
||||||
|
RebaseLine(
|
||||||
|
it.action.toRebaseAction(),
|
||||||
|
it.commit,
|
||||||
|
it.shortMessage,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_rebaseState.value = RebaseInteractiveState.Loaded(rebaseLines, messages)
|
||||||
|
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
if (ex is RebaseCancelledException) {
|
if (ex is RebaseCancelledException) {
|
||||||
println("Rebase cancelled")
|
println("Rebase cancelled")
|
||||||
@ -96,10 +99,14 @@ class RebaseInteractiveViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun continueRebaseInteractive() = tabState.runOperation(
|
fun continueRebaseInteractive() = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ONLY_LOG,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
) {
|
) { git ->
|
||||||
rebaseInteractiveMutex.unlock()
|
try {
|
||||||
|
resumeRebaseInteractiveUseCase(git, interactiveHandlerContinue)
|
||||||
|
} finally {
|
||||||
|
onRebaseComplete()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onCommitMessageChanged(commit: AbbreviatedObjectId, message: String) {
|
fun onCommitMessageChanged(commit: AbbreviatedObjectId, message: String) {
|
||||||
@ -114,7 +121,7 @@ class RebaseInteractiveViewModel @Inject constructor(
|
|||||||
_rebaseState.value = rebaseState.copy(messages = messagesMap)
|
_rebaseState.value = rebaseState.copy(messages = messagesMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onCommitActionChanged(commit: AbbreviatedObjectId, action: Action) {
|
fun onCommitActionChanged(commit: AbbreviatedObjectId, rebaseAction: RebaseAction) {
|
||||||
val rebaseState = _rebaseState.value
|
val rebaseState = _rebaseState.value
|
||||||
|
|
||||||
if (rebaseState !is RebaseInteractiveState.Loaded)
|
if (rebaseState !is RebaseInteractiveState.Loaded)
|
||||||
@ -129,7 +136,12 @@ class RebaseInteractiveViewModel @Inject constructor(
|
|||||||
|
|
||||||
if (stepIndex >= 0) {
|
if (stepIndex >= 0) {
|
||||||
val step = newStepsList[stepIndex]
|
val step = newStepsList[stepIndex]
|
||||||
val newTodoLine = RebaseTodoLine(action, step.commit, step.shortMessage)
|
val newTodoLine = RebaseLine(
|
||||||
|
rebaseAction,
|
||||||
|
step.commit,
|
||||||
|
step.shortMessage
|
||||||
|
)
|
||||||
|
|
||||||
newStepsList[stepIndex] = newTodoLine
|
newStepsList[stepIndex] = newTodoLine
|
||||||
|
|
||||||
_rebaseState.value = rebaseState.copy(stepsList = newStepsList)
|
_rebaseState.value = rebaseState.copy(stepsList = newStepsList)
|
||||||
@ -139,36 +151,60 @@ class RebaseInteractiveViewModel @Inject constructor(
|
|||||||
fun cancel() = tabState.runOperation(
|
fun cancel() = tabState.runOperation(
|
||||||
refreshType = RefreshType.REPO_STATE
|
refreshType = RefreshType.REPO_STATE
|
||||||
) { git ->
|
) { git ->
|
||||||
if (!cancelled && !completed) {
|
abortRebaseUseCase(git)
|
||||||
abortRebaseUseCase(git)
|
|
||||||
|
|
||||||
cancelled = true
|
|
||||||
|
|
||||||
rebaseInteractiveMutex.unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun resumeRebase() = tabState.runOperation(
|
|
||||||
showError = true,
|
|
||||||
refreshType = RefreshType.NONE,
|
|
||||||
) { git ->
|
|
||||||
try {
|
|
||||||
resumeRebaseInteractiveUseCase(git, interactiveHandler)
|
|
||||||
completed = true
|
|
||||||
} catch (ex: Exception) {
|
|
||||||
if (ex is RebaseCancelledException) {
|
|
||||||
println("Rebase cancelled")
|
|
||||||
} else {
|
|
||||||
cancel()
|
|
||||||
throw ex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sealed interface RebaseInteractiveState {
|
sealed interface RebaseInteractiveState {
|
||||||
object Loading : RebaseInteractiveState
|
object Loading : RebaseInteractiveState
|
||||||
data class Loaded(val stepsList: List<RebaseTodoLine>, val messages: Map<String, String>) : RebaseInteractiveState
|
data class Loaded(val stepsList: List<RebaseLine>, val messages: Map<String, String>) : RebaseInteractiveState
|
||||||
data class Failed(val error: String) : RebaseInteractiveState
|
data class Failed(val error: String) : RebaseInteractiveState
|
||||||
|
}
|
||||||
|
|
||||||
|
data class RebaseLine(
|
||||||
|
val rebaseAction: RebaseAction,
|
||||||
|
val commit: AbbreviatedObjectId,
|
||||||
|
val shortMessage: String
|
||||||
|
) {
|
||||||
|
fun toRebaseTodoLine(): RebaseTodoLine {
|
||||||
|
return RebaseTodoLine(
|
||||||
|
rebaseAction.toAction(),
|
||||||
|
commit,
|
||||||
|
shortMessage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class RebaseAction(val displayName: String) {
|
||||||
|
PICK("Pick"),
|
||||||
|
REWORD("Reword"),
|
||||||
|
SQUASH("Squash"),
|
||||||
|
FIXUP("Fixup"),
|
||||||
|
EDIT("Edit"),
|
||||||
|
DROP("Drop"),
|
||||||
|
COMMENT("Comment");
|
||||||
|
|
||||||
|
fun toAction(): Action {
|
||||||
|
return when (this) {
|
||||||
|
PICK -> Action.PICK
|
||||||
|
REWORD -> Action.REWORD
|
||||||
|
SQUASH -> Action.SQUASH
|
||||||
|
FIXUP -> Action.FIXUP
|
||||||
|
EDIT -> Action.EDIT
|
||||||
|
COMMENT -> Action.COMMENT
|
||||||
|
DROP -> throw NotImplementedError("To action should not be called when the RebaseAction is DROP")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Action.toRebaseAction(): RebaseAction {
|
||||||
|
return when (this) {
|
||||||
|
Action.PICK -> RebaseAction.PICK
|
||||||
|
Action.REWORD -> RebaseAction.REWORD
|
||||||
|
Action.EDIT -> RebaseAction.EDIT
|
||||||
|
Action.SQUASH -> RebaseAction.SQUASH
|
||||||
|
Action.FIXUP -> RebaseAction.FIXUP
|
||||||
|
Action.COMMENT -> RebaseAction.COMMENT
|
||||||
|
}
|
||||||
}
|
}
|
@ -165,6 +165,9 @@ class TabViewModel @Inject constructor(
|
|||||||
private suspend fun onRebaseInteractive(taskEvent: TaskEvent.RebaseInteractive) {
|
private suspend fun onRebaseInteractive(taskEvent: TaskEvent.RebaseInteractive) {
|
||||||
rebaseInteractiveViewModel = rebaseInteractiveViewModelProvider.get()
|
rebaseInteractiveViewModel = rebaseInteractiveViewModelProvider.get()
|
||||||
rebaseInteractiveViewModel?.startRebaseInteractive(taskEvent.revCommit)
|
rebaseInteractiveViewModel?.startRebaseInteractive(taskEvent.revCommit)
|
||||||
|
rebaseInteractiveViewModel?.onRebaseComplete = {
|
||||||
|
rebaseInteractiveViewModel = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user