diff --git a/platform/dvcs-impl/src/META-INF/dvcs.xml b/platform/dvcs-impl/src/META-INF/dvcs.xml
index c045e58a9e3a..6a6de37de05a 100644
--- a/platform/dvcs-impl/src/META-INF/dvcs.xml
+++ b/platform/dvcs-impl/src/META-INF/dvcs.xml
@@ -38,6 +38,7 @@
+
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/cherrypick/VcsCherryPickAction.java b/platform/dvcs-impl/src/com/intellij/dvcs/cherrypick/VcsCherryPickAction.java
index efff67a5486b..5523461a1afd 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/cherrypick/VcsCherryPickAction.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/cherrypick/VcsCherryPickAction.java
@@ -17,25 +17,14 @@ package com.intellij.dvcs.cherrypick;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
-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.ChangeListManagerEx;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.*;
@@ -47,47 +36,20 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
public class VcsCherryPickAction extends DumbAwareAction {
- private static final Logger LOG = Logger.getInstance(VcsCherryPickAction.class);
private static final String NAME = "Cherry-Pick";
- @NotNull private final Set myIdsInProgress;
public VcsCherryPickAction() {
super(NAME, null, DvcsImplIcons.CherryPick);
- myIdsInProgress = ContainerUtil.newHashSet();
}
@Override
public void actionPerformed(AnActionEvent e) {
FileDocumentManager.getInstance().saveAllDocuments();
- final Project project = e.getRequiredData(CommonDataKeys.PROJECT);
+ Project project = e.getRequiredData(CommonDataKeys.PROJECT);
VcsLog log = e.getRequiredData(VcsLogDataKeys.VCS_LOG);
- log.requestSelectedDetails(new Consumer>() {
- @Override
- public void consume(Set details) {
- ProgressManager.getInstance().run(new CherryPickingTask(project, details));
- }
- }, null);
- }
-
- /**
- * Sort commits so that earliest ones come first: they need to be cherry-picked first.
- */
- @NotNull
- public static List sortCommits(@NotNull List commits) {
- Collections.reverse(commits);
- return commits;
- }
-
- @Nullable
- private static VcsCherryPicker getCherryPickerFor(@NotNull Project project, @NotNull final VcsKey key) {
- return ContainerUtil.find(Extensions.getExtensions(VcsCherryPicker.EXTENSION_POINT_NAME, project), new Condition() {
- @Override
- public boolean value(VcsCherryPicker picker) {
- return picker.getSupportedVcs().equals(key);
- }
- });
+ VcsCherryPickManager.getInstance(project).cherryPick(log);
}
@Override
@@ -148,85 +110,12 @@ public class VcsCherryPickAction extends DumbAwareAction {
return ContainerUtil.mapNotNull(vcss, new Function() {
@Override
public VcsCherryPicker fun(AbstractVcs vcs) {
- return vcs != null ? getCherryPickerFor(project, vcs.getKeyInstanceMethod()) : null;
+ return vcs != null ? VcsCherryPickManager.getInstance(project).getCherryPickerFor(vcs.getKeyInstanceMethod()) : null;
}
});
}
return ContainerUtil.emptyList();
}
- @Nullable
- private static VcsCherryPicker getCherryPickerForCommit(@NotNull Project project,
- @NotNull ProjectLevelVcsManager projectLevelVcsManager,
- @NotNull VcsFullCommitDetails commitDetails) {
- AbstractVcs vcs = projectLevelVcsManager.getVcsFor(commitDetails.getRoot());
- if (vcs == null) return null;
- VcsKey key = vcs.getKeyInstanceMethod();
- return getCherryPickerFor(project, key);
- }
- private class CherryPickingTask extends Task.Backgroundable {
- private final Project myProject;
- private final ProjectLevelVcsManager myProjectLevelVcsManager;
- private final Map> myGroupedCommits = ContainerUtil.newHashMap();
- private final Collection myAllCommits;
- private final ChangeListManagerEx myChangeListManagerEx;
-
- public CherryPickingTask(@NotNull Project project, @NotNull Set details) {
- super(project, "Cherry-Picking");
- myProject = project;
- myProjectLevelVcsManager = ProjectLevelVcsManager.getInstance(myProject);
- myAllCommits = details;
- myChangeListManagerEx = (ChangeListManagerEx)ChangeListManager.getInstance(myProject);
- myChangeListManagerEx.blockModalNotifications();
- }
-
- public boolean processDetails(@NotNull VcsFullCommitDetails details) {
- myIdsInProgress.add(details.getId());
-
- VcsCherryPicker cherryPicker = getCherryPickerForCommit(myProject, myProjectLevelVcsManager, details);
- if (cherryPicker == null) {
- String message =
- "Cherry pick is not supported for commit " + details.getId().toShortString() + " from root " + details.getRoot().getName();
- VcsNotifier.getInstance(myProject).notifyWeakError(message);
- LOG.warn(message);
- return false;
- }
- List list = myGroupedCommits.get(cherryPicker);
- if (list == null) {
- myGroupedCommits.put(cherryPicker, list = new ArrayList()); // ordered set!!
- }
- list.add(details);
- return true;
- }
-
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- try {
- boolean isOk = true;
- for (VcsFullCommitDetails details : myAllCommits) {
- if (!processDetails(details)) {
- isOk = false;
- break;
- }
- }
-
- if (isOk) {
- for (Map.Entry> entry : myGroupedCommits.entrySet()) {
- entry.getKey().cherryPick(sortCommits(entry.getValue()));
- }
- }
- }
- finally {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- public void run() {
- myChangeListManagerEx.unblockModalNotifications();
- for (VcsFullCommitDetails commit : myAllCommits) {
- myIdsInProgress.remove(commit.getId());
- }
- }
- });
- }
- }
- }
}
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/cherrypick/VcsCherryPickManager.java b/platform/dvcs-impl/src/com/intellij/dvcs/cherrypick/VcsCherryPickManager.java
new file mode 100644
index 000000000000..c3d542f4fb07
--- /dev/null
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/cherrypick/VcsCherryPickManager.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.dvcs.cherrypick;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.Extensions;
+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.util.Condition;
+import com.intellij.openapi.vcs.AbstractVcs;
+import com.intellij.openapi.vcs.ProjectLevelVcsManager;
+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.ChangeListManagerEx;
+import com.intellij.util.Consumer;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.vcs.log.CommitId;
+import com.intellij.vcs.log.VcsFullCommitDetails;
+import com.intellij.vcs.log.VcsLog;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+public class VcsCherryPickManager {
+ private static final Logger LOG = Logger.getInstance(VcsCherryPickManager.class);
+ @NotNull private final Project myProject;
+ @NotNull private final Set myIdsInProgress = ContainerUtil.newConcurrentSet();
+
+ public VcsCherryPickManager(@NotNull Project project) {
+ myProject = project;
+ }
+
+ public void cherryPick(@NotNull VcsLog log) {
+ log.requestSelectedDetails(new Consumer>() {
+ @Override
+ public void consume(Set details) {
+ ProgressManager.getInstance().run(new CherryPickingTask(myProject, details));
+ }
+ }, null);
+ }
+
+ @Nullable
+ private VcsCherryPicker getCherryPickerForCommit(@NotNull ProjectLevelVcsManager projectLevelVcsManager,
+ @NotNull VcsFullCommitDetails commitDetails) {
+ AbstractVcs vcs = projectLevelVcsManager.getVcsFor(commitDetails.getRoot());
+ if (vcs == null) return null;
+ VcsKey key = vcs.getKeyInstanceMethod();
+ return getCherryPickerFor(key);
+ }
+
+ @Nullable
+ public VcsCherryPicker getCherryPickerFor(@NotNull final VcsKey key) {
+ return ContainerUtil.find(Extensions.getExtensions(VcsCherryPicker.EXTENSION_POINT_NAME, myProject), new Condition() {
+ @Override
+ public boolean value(VcsCherryPicker picker) {
+ return picker.getSupportedVcs().equals(key);
+ }
+ });
+ }
+
+ private class CherryPickingTask extends Task.Backgroundable {
+ private final Project myProject;
+ private final ProjectLevelVcsManager myProjectLevelVcsManager;
+ private final Map> myGroupedCommits = ContainerUtil.newHashMap();
+ private final Collection myAllCommits;
+ private final ChangeListManagerEx myChangeListManagerEx;
+
+ public CherryPickingTask(@NotNull Project project, @NotNull Set details) {
+ super(project, "Cherry-Picking");
+ myProject = project;
+ myProjectLevelVcsManager = ProjectLevelVcsManager.getInstance(myProject);
+ myAllCommits = details;
+ myChangeListManagerEx = (ChangeListManagerEx)ChangeListManager.getInstance(myProject);
+ myChangeListManagerEx.blockModalNotifications();
+ }
+
+ public boolean processDetails(@NotNull VcsFullCommitDetails details) {
+ myIdsInProgress.add(new CommitId(details.getId(), details.getRoot()));
+
+ VcsCherryPicker cherryPicker = getCherryPickerForCommit(myProjectLevelVcsManager, details);
+ if (cherryPicker == null) {
+ String message =
+ "Cherry pick is not supported for commit " + details.getId().toShortString() + " from root " + details.getRoot().getName();
+ VcsNotifier.getInstance(myProject).notifyWeakError(message);
+ LOG.warn(message);
+ return false;
+ }
+ List list = myGroupedCommits.get(cherryPicker);
+ if (list == null) {
+ myGroupedCommits.put(cherryPicker, list = new ArrayList()); // ordered set!!
+ }
+ list.add(details);
+ return true;
+ }
+
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ try {
+ boolean isOk = true;
+ for (VcsFullCommitDetails details : myAllCommits) {
+ if (!processDetails(details)) {
+ isOk = false;
+ break;
+ }
+ }
+
+ if (isOk) {
+ for (Map.Entry> entry : myGroupedCommits.entrySet()) {
+ entry.getKey().cherryPick(sortCommits(entry.getValue()));
+ }
+ }
+ }
+ finally {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public void run() {
+ myChangeListManagerEx.unblockModalNotifications();
+ for (VcsFullCommitDetails details : myAllCommits) {
+ myIdsInProgress.remove(new CommitId(details.getId(), details.getRoot()));
+ }
+ }
+ });
+ }
+ }
+ }
+
+ @NotNull
+ private static List sortCommits(@NotNull List commits) {
+ Collections.reverse(commits);
+ return commits;
+ }
+
+ public static VcsCherryPickManager getInstance(@NotNull Project project) {
+ return ServiceManager.getService(project, VcsCherryPickManager.class);
+ }
+}