mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Simplify undo of git reword & write a test for it
No need to use the complicated GitAbortRebaseProcess with a special rebase spec: enough to call `git reset --keep`.
This commit is contained in:
@@ -23,22 +23,27 @@ import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.Task
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vcs.VcsNotifier
|
||||
import com.intellij.openapi.vcs.VcsNotifier.STANDARD_NOTIFICATION
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import com.intellij.vcs.log.VcsCommitMetadata
|
||||
import git4idea.branch.GitRebaseParams
|
||||
import git4idea.commands.Git
|
||||
import git4idea.rebase.GitRebaseEntry.Action.pick
|
||||
import git4idea.rebase.GitRebaseEntry.Action.reword
|
||||
import git4idea.rebase.GitRebaseStatus.Type.SUCCESS
|
||||
import git4idea.repo.GitRepository
|
||||
import git4idea.reset.GitResetMode
|
||||
|
||||
class GitRewordOperation(private val repository: GitRepository,
|
||||
private val commit: VcsCommitMetadata,
|
||||
private val newMessage: String) {
|
||||
init {
|
||||
repository.update()
|
||||
}
|
||||
private val project = repository.project
|
||||
private val initialHeadPosition = repository.currentRevision!!
|
||||
|
||||
fun execute() {
|
||||
val project = repository.project
|
||||
val rebaseEditor = GitAutomaticRebaseEditor(project, commit.root,
|
||||
entriesEditor = { list -> injectRewordAction(list) },
|
||||
plainTextEditor = { editorText -> supplyNewMessage(editorText) })
|
||||
@@ -46,7 +51,14 @@ class GitRewordOperation(private val repository: GitRepository,
|
||||
val params = GitRebaseParams.editCommits(commit.parents.first().asString(), rebaseEditor, true)
|
||||
val indicator = ProgressManager.getInstance().progressIndicator ?: EmptyProgressIndicator()
|
||||
val spec = GitRebaseSpec.forNewRebase(project, params, listOf(repository), indicator)
|
||||
RewordProcess(project, spec).rebase()
|
||||
RewordProcess(spec).rebase()
|
||||
}
|
||||
|
||||
internal fun undo() {
|
||||
val res = Git.getInstance().reset(repository, GitResetMode.KEEP, initialHeadPosition)
|
||||
if (!res.success()) {
|
||||
VcsNotifier.getInstance(project).notifyError("Undo Reword Failed", res.errorOutputAsHtmlString)
|
||||
}
|
||||
}
|
||||
|
||||
private fun injectRewordAction(list: List<GitRebaseEntry>): List<GitRebaseEntry> {
|
||||
@@ -66,15 +78,14 @@ class GitRewordOperation(private val repository: GitRepository,
|
||||
}
|
||||
}
|
||||
|
||||
private inner class RewordProcess(val project: Project, val spec: GitRebaseSpec) : GitRebaseProcess(project, spec, null) {
|
||||
private inner class RewordProcess(spec: GitRebaseSpec) : GitRebaseProcess(project, spec, null) {
|
||||
override fun notifySuccess(successful: MutableMap<GitRepository, GitSuccessfulRebase>,
|
||||
skippedCommits: MultiMap<GitRepository, GitRebaseUtils.CommitInfo>) {
|
||||
val notification = STANDARD_NOTIFICATION.createNotification("Reworded Successfully", "", NotificationType.INFORMATION, null)
|
||||
notification.addAction(object : NotificationAction("Undo") {
|
||||
override fun actionPerformed(e: AnActionEvent, notification: Notification) {
|
||||
notification.expire()
|
||||
val specForUndo = spec.cloneWithNewStatuses(mapOf(repository to GitRebaseStatus(SUCCESS, emptyList())))
|
||||
undo(project, specForUndo)
|
||||
undoInBackground()
|
||||
}
|
||||
})
|
||||
VcsNotifier.getInstance(project).notify(notification)
|
||||
@@ -82,11 +93,10 @@ class GitRewordOperation(private val repository: GitRepository,
|
||||
|
||||
override fun shouldRefreshOnSuccess(successType: GitSuccessfulRebase.SuccessType) = false
|
||||
|
||||
private fun undo(project: Project, spec: GitRebaseSpec) {
|
||||
private fun undoInBackground() {
|
||||
ProgressManager.getInstance().run(object : Task.Backgroundable(project, "Undoing Reword") {
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
GitAbortRebaseProcess(project, null, spec.headPositionsToRollback, spec.initialBranchNames, indicator, spec.saver, false)
|
||||
.abortAndRollback()
|
||||
undo()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class GitRewordTest : GitSingleRepoTest() {
|
||||
val newMessage = "Correct message"
|
||||
GitRewordOperation(myRepo, commit, newMessage).execute()
|
||||
|
||||
assertEquals("Message reworded incorrectly", git("log HEAD --no-walk --pretty=%B"), newMessage)
|
||||
assertEquals("Message reworded incorrectly", newMessage, git("log HEAD --no-walk --pretty=%B"))
|
||||
}
|
||||
|
||||
fun `test reword previous commit`() {
|
||||
@@ -38,6 +38,16 @@ class GitRewordTest : GitSingleRepoTest() {
|
||||
val newMessage = "Correct message"
|
||||
GitRewordOperation(myRepo, commit, newMessage).execute()
|
||||
|
||||
assertEquals("Message reworded incorrectly", git("log HEAD^ --no-walk --pretty=%B"), newMessage)
|
||||
assertEquals("Message reworded incorrectly", newMessage, git("log HEAD^ --no-walk --pretty=%B"))
|
||||
}
|
||||
|
||||
fun `test undo reword`() {
|
||||
val commit = file("a").create("initial").addCommit("Wrong message").details()
|
||||
|
||||
val operation = GitRewordOperation(myRepo, commit, "Correct message")
|
||||
operation.execute()
|
||||
operation.undo()
|
||||
|
||||
assertEquals("Message reworded incorrectly", "Wrong message", git("log HEAD --no-walk --pretty=%B"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user