Queue cherry-picking tasks: IDEA-181553

Otherwise calling Cherry-pick several times produces several independent
tasks which conflict each other, especially during changelists manipulation.
This might have led to EA-110376
This commit is contained in:
Kirill Likhodedov
2017-11-03 17:47:55 +03:00
parent bc3d92b00a
commit d9578660a8
@@ -21,15 +21,12 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProgressIndicator; 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.project.Project;
import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.actions.BackgroundTaskGroup;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vcs.VcsNotifier;
import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ChangeListManagerEx; import com.intellij.openapi.vcs.changes.ChangeListManagerEx;
import com.intellij.util.ThrowableConsumer;
import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.MultiMap;
import com.intellij.vcs.log.CommitId; import com.intellij.vcs.log.CommitId;
@@ -45,15 +42,17 @@ public class VcsCherryPickManager {
@NotNull private final Project myProject; @NotNull private final Project myProject;
@NotNull private final ProjectLevelVcsManager myProjectLevelVcsManager; @NotNull private final ProjectLevelVcsManager myProjectLevelVcsManager;
@NotNull private final Set<CommitId> myIdsInProgress = ContainerUtil.newConcurrentSet(); @NotNull private final Set<CommitId> myIdsInProgress = ContainerUtil.newConcurrentSet();
private final BackgroundTaskGroup myTaskQueue;
public VcsCherryPickManager(@NotNull Project project, @NotNull ProjectLevelVcsManager projectLevelVcsManager) { public VcsCherryPickManager(@NotNull Project project, @NotNull ProjectLevelVcsManager projectLevelVcsManager) {
myProject = project; myProject = project;
myProjectLevelVcsManager = projectLevelVcsManager; myProjectLevelVcsManager = projectLevelVcsManager;
myTaskQueue = new BackgroundTaskGroup(project, "Cherry-picking");
} }
public void cherryPick(@NotNull VcsLog log) { public void cherryPick(@NotNull VcsLog log) {
log.requestSelectedDetails( log.requestSelectedDetails(
details -> ProgressManager.getInstance().run(new CherryPickingTask(myProject, ContainerUtil.reverse(details)))); details -> myTaskQueue.runInBackground("Cherry-picking", new CherryPickingTask(ContainerUtil.reverse(details))));
} }
public boolean isCherryPickAlreadyStartedFor(@NotNull List<CommitId> commits) { public boolean isCherryPickAlreadyStartedFor(@NotNull List<CommitId> commits) {
@@ -79,12 +78,11 @@ public class VcsCherryPickManager {
picker -> picker.getSupportedVcs().equals(key)); picker -> picker.getSupportedVcs().equals(key));
} }
private class CherryPickingTask extends Task.Backgroundable { private class CherryPickingTask implements ThrowableConsumer<ProgressIndicator, VcsException> {
@NotNull private final List<VcsFullCommitDetails> myAllDetailsInReverseOrder; @NotNull private final List<VcsFullCommitDetails> myAllDetailsInReverseOrder;
@NotNull private final ChangeListManagerEx myChangeListManager; @NotNull private final ChangeListManagerEx myChangeListManager;
public CherryPickingTask(@NotNull Project project, @NotNull List<VcsFullCommitDetails> detailsInReverseOrder) { public CherryPickingTask(@NotNull List<VcsFullCommitDetails> detailsInReverseOrder) {
super(project, "Cherry-Picking");
myAllDetailsInReverseOrder = detailsInReverseOrder; myAllDetailsInReverseOrder = detailsInReverseOrder;
myChangeListManager = (ChangeListManagerEx)ChangeListManager.getInstance(myProject); myChangeListManager = (ChangeListManagerEx)ChangeListManager.getInstance(myProject);
myChangeListManager.blockModalNotifications(); myChangeListManager.blockModalNotifications();
@@ -117,7 +115,7 @@ public class VcsCherryPickManager {
} }
@Override @Override
public void run(@NotNull ProgressIndicator indicator) { public void consume(ProgressIndicator indicator) {
try { try {
boolean isOk = true; boolean isOk = true;
MultiMap<VcsCherryPicker, VcsFullCommitDetails> groupedCommits = createArrayMultiMap(); MultiMap<VcsCherryPicker, VcsFullCommitDetails> groupedCommits = createArrayMultiMap();