From be672f03726b198e140fa943a4ecc6bc6fb270d5 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 20 May 2017 15:24:49 +0300 Subject: [PATCH] Improve notification about successful Reword & support Undo --- .../rebase/GitAbortRebaseProcess.java | 15 ++++++- .../src/git4idea/rebase/GitRebaseProcess.java | 2 +- .../src/git4idea/rebase/GitRebaseUtils.java | 4 +- .../src/git4idea/rebase/GitRewordOperation.kt | 44 ++++++++++++++++--- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java b/plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java index 5948f6fc4bd3..5069c86cc92a 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java +++ b/plugins/git4idea/src/git4idea/rebase/GitAbortRebaseProcess.java @@ -59,19 +59,22 @@ class GitAbortRebaseProcess { @NotNull private final Map myInitialCurrentBranches; @NotNull private final ProgressIndicator myIndicator; @Nullable private final GitChangesSaver mySaver; + private final boolean myNotifySuccess; GitAbortRebaseProcess(@NotNull Project project, @Nullable GitRepository repositoryToAbort, @NotNull Map repositoriesToRollback, @NotNull Map initialCurrentBranches, @NotNull ProgressIndicator progressIndicator, - @Nullable GitChangesSaver changesSaver) { + @Nullable GitChangesSaver changesSaver, + boolean notifySuccess) { myProject = project; myRepositoryToAbort = repositoryToAbort; myRepositoriesToRollback = repositoriesToRollback; myInitialCurrentBranches = initialCurrentBranches; myIndicator = progressIndicator; mySaver = changesSaver; + myNotifySuccess = notifySuccess; myGit = Git.getInstance(); myNotifier = VcsNotifier.getInstance(myProject); @@ -92,6 +95,12 @@ class GitAbortRebaseProcess { } } + void abortAndRollback() { + LOG.info("Abort rebase. " + (myRepositoryToAbort == null ? "Nothing to abort" : getShortRepositoryName(myRepositoryToAbort)) + + ". Roots to rollback: " + DvcsUtil.joinShortNames(myRepositoriesToRollback.keySet())); + doAbort(true); + } + @NotNull private AbortChoice confirmAbort() { String title = "Abort Rebase"; @@ -182,7 +191,9 @@ class GitAbortRebaseProcess { if (mySaver != null) { mySaver.load(); } - myNotifier.notifySuccess("Rebase abort succeeded"); + if (myNotifySuccess) { + myNotifier.notifySuccess("Rebase abort succeeded"); + } } finally { refresh(repositoriesToRefresh); diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaseProcess.java b/plugins/git4idea/src/git4idea/rebase/GitRebaseProcess.java index e8cef95768f1..ef1bb8888cb3 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitRebaseProcess.java +++ b/plugins/git4idea/src/git4idea/rebase/GitRebaseProcess.java @@ -330,7 +330,7 @@ public class GitRebaseProcess { return filter(repositories, repository -> myChangeListManager.haveChangesUnder(repository.getRoot()) != ThreeState.NO); } - private void notifySuccess(@NotNull Map successful, + protected void notifySuccess(@NotNull Map successful, @NotNull MultiMap skippedCommits) { String rebasedBranch = getCommonCurrentBranchNameIfAllTheSame(myRebaseSpec.getAllRepositories()); List successTypes = map(successful.values(), GitSuccessfulRebase::getSuccessType); diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java b/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java index bb5ebfd47568..36d07b26fdbb 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java +++ b/plugins/git4idea/src/git4idea/rebase/GitRebaseUtils.java @@ -120,7 +120,7 @@ public class GitRebaseUtils { GitRebaseSpec spec = GitUtil.getRepositoryManager(project).getOngoingRebaseSpec(); if (spec != null) { new GitAbortRebaseProcess(project, spec.getOngoingRebase(), spec.getHeadPositionsToRollback(), spec.getInitialBranchNames(), - indicator, spec.getSaver()).abortWithConfirmation(); + indicator, spec.getSaver(), true).abortWithConfirmation(); } else { LOG.warn("Refusing to abort: no rebase spec"); @@ -133,7 +133,7 @@ public class GitRebaseUtils { */ public static void abort(@NotNull final Project project, @Nullable final GitRepository repository, @NotNull ProgressIndicator indicator) { new GitAbortRebaseProcess(project, repository, Collections.emptyMap(), - Collections.emptyMap(), indicator, null).abortWithConfirmation(); + Collections.emptyMap(), indicator, null, true).abortWithConfirmation(); } private static boolean isRebaseAllowed(@NotNull Project project, @NotNull Collection repositories) { diff --git a/plugins/git4idea/src/git4idea/rebase/GitRewordOperation.kt b/plugins/git4idea/src/git4idea/rebase/GitRewordOperation.kt index 4f13dc0e127f..0c8d2e07d386 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitRewordOperation.kt +++ b/plugins/git4idea/src/git4idea/rebase/GitRewordOperation.kt @@ -15,29 +15,38 @@ */ package git4idea.rebase -import com.intellij.openapi.diagnostic.logger +import com.intellij.notification.Notification +import com.intellij.notification.NotificationAction +import com.intellij.notification.NotificationType +import com.intellij.openapi.actionSystem.AnActionEvent 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.rebase.GitRebaseEntry.Action.pick import git4idea.rebase.GitRebaseEntry.Action.reword +import git4idea.rebase.GitRebaseStatus.Type.SUCCESS import git4idea.repo.GitRepository class GitRewordOperation(private val repository: GitRepository, private val commit: VcsCommitMetadata, private val newMessage: String) { - private val LOG = logger() - fun execute() { - val rebaseEditor = GitAutomaticRebaseEditor(repository.project, commit.root, + val project = repository.project + val rebaseEditor = GitAutomaticRebaseEditor(project, commit.root, entriesEditor = { list -> injectRewordAction(list) }, plainTextEditor = { editorText -> supplyNewMessage(editorText) }) val params = GitRebaseParams.editCommits(commit.parents.first().asString(), rebaseEditor, true) val indicator = ProgressManager.getInstance().progressIndicator ?: EmptyProgressIndicator() - val spec = GitRebaseSpec.forNewRebase(repository.project, params, listOf(repository), indicator) - GitRebaseProcess(repository.project, spec, null).rebase() + val spec = GitRebaseSpec.forNewRebase(project, params, listOf(repository), indicator) + RewordProcess(project, spec).rebase() } private fun injectRewordAction(list: List): List { @@ -56,4 +65,27 @@ class GitRewordOperation(private val repository: GitRepository, throw IllegalStateException("Unexpected editor content: $editorText") } } + + private inner class RewordProcess(val project: Project, val spec: GitRebaseSpec) : GitRebaseProcess(project, spec, null) { + override fun notifySuccess(successful: MutableMap, + skippedCommits: MultiMap) { + val notification = STANDARD_NOTIFICATION.createNotification("Reworded Successfully", "", NotificationType.INFORMATION, null) + notification.addAction(object : NotificationAction("Undo") { + override fun actionPerformed(e: AnActionEvent, notification: Notification) { + val specForUndo = spec.cloneWithNewStatuses(mapOf(repository to GitRebaseStatus(SUCCESS, emptyList()))) + undo(project, specForUndo) + } + }) + VcsNotifier.getInstance(project).notify(notification) + } + + private fun undo(project: Project, spec: GitRebaseSpec) { + 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() + } + }) + } + } } \ No newline at end of file