Improve notification about successful Reword & support Undo

This commit is contained in:
Kirill Likhodedov
2017-05-29 17:10:59 +03:00
parent efc6387b5a
commit be672f0372
4 changed files with 54 additions and 11 deletions
@@ -59,19 +59,22 @@ class GitAbortRebaseProcess {
@NotNull private final Map<GitRepository, String> myInitialCurrentBranches;
@NotNull private final ProgressIndicator myIndicator;
@Nullable private final GitChangesSaver mySaver;
private final boolean myNotifySuccess;
GitAbortRebaseProcess(@NotNull Project project,
@Nullable GitRepository repositoryToAbort,
@NotNull Map<GitRepository, String> repositoriesToRollback,
@NotNull Map<GitRepository, String> 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);
@@ -330,7 +330,7 @@ public class GitRebaseProcess {
return filter(repositories, repository -> myChangeListManager.haveChangesUnder(repository.getRoot()) != ThreeState.NO);
}
private void notifySuccess(@NotNull Map<GitRepository, GitSuccessfulRebase> successful,
protected void notifySuccess(@NotNull Map<GitRepository, GitSuccessfulRebase> successful,
@NotNull MultiMap<GitRepository, GitRebaseUtils.CommitInfo> skippedCommits) {
String rebasedBranch = getCommonCurrentBranchNameIfAllTheSame(myRebaseSpec.getAllRepositories());
List<SuccessType> successTypes = map(successful.values(), GitSuccessfulRebase::getSuccessType);
@@ -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<GitRepository> repositories) {
@@ -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<GitRewordOperation>()
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<GitRebaseEntry>): List<GitRebaseEntry> {
@@ -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<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) {
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()
}
})
}
}
}