From 2ecd8faa20760545fd31867a5acf0e2a973ad34c Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 15 Nov 2013 15:16:32 +0400 Subject: [PATCH] IDEA-115586 Support specifying default base branch and branch prefix for branches created through Task system --- .../intellij/openapi/vcs/VcsTaskHandler.java | 13 +++- .../git4idea/src/git4idea/GitTaskHandler.java | 26 ++++++- .../src/git4idea/branch/GitBranchUtil.java | 27 ++++++++ .../ui/branch/GitMultiRootBranchConfig.java | 32 +-------- .../tasks/actions/OpenTaskDialog.form | 19 ++++- .../tasks/actions/OpenTaskDialog.java | 69 +++++++++++++++++-- .../intellij/tasks/impl/TaskManagerImpl.java | 8 ++- .../intellij/tasks/vcs/TaskBranchesTest.java | 2 +- 8 files changed, 154 insertions(+), 42 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java index 34fdd62da731..6f5ea05abea3 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java @@ -36,15 +36,26 @@ public abstract class VcsTaskHandler { public TaskInfo(MultiMap branches) { this.branches = branches; } + + public String getName() { + return branches.isEmpty() ? null : branches.keySet().iterator().next(); + } + + @Override + public boolean equals(Object obj) { + return branches.equals(((TaskInfo)obj).branches); + } } private static final ExtensionPointName EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.vcs.taskHandler"); public abstract TaskInfo startNewTask(String taskName); - public abstract void switchToTask(TaskInfo taskInfo); + public abstract void switchToTask(TaskInfo taskInfo, Runnable invokeAfter); public abstract void closeTask(TaskInfo taskInfo, TaskInfo original); public abstract TaskInfo getActiveTask(); + + public abstract TaskInfo[] getCurrentTasks(); } diff --git a/plugins/git4idea/src/git4idea/GitTaskHandler.java b/plugins/git4idea/src/git4idea/GitTaskHandler.java index c5269a22ce60..7dac4654d860 100644 --- a/plugins/git4idea/src/git4idea/GitTaskHandler.java +++ b/plugins/git4idea/src/git4idea/GitTaskHandler.java @@ -22,9 +22,11 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsTaskHandler; +import com.intellij.util.Function; import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; +import git4idea.branch.GitBranchUtil; import git4idea.branch.GitBrancher; import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryManager; @@ -88,7 +90,7 @@ public class GitTaskHandler extends VcsTaskHandler { } @Override - public void switchToTask(TaskInfo taskInfo) { + public void switchToTask(TaskInfo taskInfo, Runnable invokeAfter) { for (final String branchName : taskInfo.branches.keySet()) { List repositories = getRepositories(taskInfo.branches.get(branchName)); List notFound = ContainerUtil.filter(repositories, new Condition() { @@ -102,7 +104,7 @@ public class GitTaskHandler extends VcsTaskHandler { } repositories.removeAll(notFound); if (!repositories.isEmpty()) { - myBrancher.checkout(branchName, repositories, null); + myBrancher.checkout(branchName, repositories, invokeAfter); } } } @@ -144,6 +146,26 @@ public class GitTaskHandler extends VcsTaskHandler { return new TaskInfo(branches); } + @Override + public TaskInfo[] getCurrentTasks() { + List repositories = myRepositoryManager.getRepositories(); + final List names = ContainerUtil.map(repositories, new Function() { + @Override + public String fun(GitRepository repository) { + return repository.getPresentableUrl(); + } + }); + Collection branches = GitBranchUtil.getCommonBranches(repositories, true); + return ContainerUtil.map2Array(branches, TaskInfo.class, new Function() { + @Override + public TaskInfo fun(String branchName) { + MultiMap map = new MultiMap(); + map.put(branchName, names); + return new TaskInfo(map); + } + }); + } + private List getRepositories(Collection urls) { final List repositories = myRepositoryManager.getRepositories(); return ContainerUtil.mapNotNull(urls, new NullableFunction() { diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java b/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java index 6b4def565499..96480a3aeda7 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java +++ b/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java @@ -542,4 +542,31 @@ public class GitBranchUtil { return rootCandidate; } + @NotNull + public static Collection getCommonBranches(Collection repositories, + boolean local) { + Collection commonBranches = null; + for (GitRepository repository : repositories) { + GitBranchesCollection branchesCollection = repository.getBranches(); + + Collection names = local + ? convertBranchesToNames(branchesCollection.getLocalBranches()) + : getBranchNamesWithoutRemoteHead(branchesCollection.getRemoteBranches()); + if (commonBranches == null) { + commonBranches = names; + } + else { + commonBranches.retainAll(names); + } + } + + if (commonBranches != null) { + ArrayList common = new ArrayList(commonBranches); + Collections.sort(common); + return common; + } + else { + return Collections.emptyList(); + } + } } diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java b/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java index a9974be49706..c47977855a0b 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java +++ b/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java @@ -19,7 +19,6 @@ import git4idea.GitBranch; import git4idea.GitLocalBranch; import git4idea.GitRemoteBranch; import git4idea.branch.GitBranchUtil; -import git4idea.branch.GitBranchesCollection; import git4idea.repo.GitBranchTrackInfo; import git4idea.repo.GitRepository; import org.jetbrains.annotations.NotNull; @@ -78,12 +77,12 @@ public class GitMultiRootBranchConfig { @NotNull Collection getLocalBranches() { - return getCommonBranches(true); + return GitBranchUtil.getCommonBranches(myRepositories, true); } @NotNull Collection getRemoteBranches() { - return getCommonBranches(false); + return GitBranchUtil.getCommonBranches(myRepositories, false); } /** @@ -144,33 +143,6 @@ public class GitMultiRootBranchConfig { return branch == null ? null : branch.findTrackedBranch(repository); } - @NotNull - private Collection getCommonBranches(boolean local) { - Collection commonBranches = null; - for (GitRepository repository : myRepositories) { - GitBranchesCollection branchesCollection = repository.getBranches(); - - Collection names = local - ? GitBranchUtil.convertBranchesToNames(branchesCollection.getLocalBranches()) - : GitBranchUtil.getBranchNamesWithoutRemoteHead(branchesCollection.getRemoteBranches()); - if (commonBranches == null) { - commonBranches = names; - } - else { - commonBranches.retainAll(names); - } - } - - if (commonBranches != null) { - ArrayList common = new ArrayList(commonBranches); - Collections.sort(common); - return common; - } - else { - return Collections.emptyList(); - } - } - @Override public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.form b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.form index 1061bc998af8..fb7ab62bdaa8 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.form +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.form @@ -73,7 +73,7 @@ - + @@ -96,7 +96,7 @@ - + @@ -120,6 +120,21 @@ + + + + + + + + + + + + + + + diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java index 3eeea41976ec..4a7f3e729d4b 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java @@ -16,19 +16,26 @@ package com.intellij.tasks.actions; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.binding.BindControl; import com.intellij.openapi.options.binding.ControlBinder; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.ValidationInfo; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.VcsTaskHandler; import com.intellij.openapi.vcs.VcsType; import com.intellij.tasks.*; import com.intellij.tasks.impl.TaskManagerImpl; import com.intellij.tasks.impl.TaskUtil; +import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.components.JBCheckBox; +import com.intellij.ui.components.JBLabel; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -42,6 +49,7 @@ import java.awt.event.ActionListener; */ public class OpenTaskDialog extends DialogWrapper { private final static Logger LOG = Logger.getInstance("#com.intellij.tasks.actions.SimpleOpenTaskDialog"); + public static final String START_FROM_BRANCH = "start.from.branch"; private JPanel myPanel; @BindControl(value = "clearContext", instant = true) @@ -53,9 +61,12 @@ public class OpenTaskDialog extends DialogWrapper { private JTextField myChangelistName; private JBCheckBox myCreateBranch; private JBCheckBox myCreateChangelist; + private JBLabel myFromLabel; + private ComboBox myBranchFrom; private final Project myProject; private final Task myTask; + private VcsTaskHandler myVcsTaskHandler; public OpenTaskDialog(@NotNull final Project project, @NotNull final Task task) { super(project, false); @@ -100,6 +111,48 @@ public class OpenTaskDialog extends DialogWrapper { myCreateBranch.setSelected(false); myCreateBranch.setVisible(false); myBranchName.setVisible(false); + myFromLabel.setVisible(false); + myBranchFrom.setVisible(false); + } + else { + VcsTaskHandler[] handlers = VcsTaskHandler.getAllHandlers(project); + for (VcsTaskHandler handler : handlers) { + VcsTaskHandler.TaskInfo[] tasks = handler.getCurrentTasks(); + if (tasks.length > 0) { + myVcsTaskHandler = handler; + myBranchFrom.setModel(new DefaultComboBoxModel(tasks)); + final String startFrom = PropertiesComponent.getInstance(project).getValue(START_FROM_BRANCH); + VcsTaskHandler.TaskInfo info = null; + if (startFrom != null) { + info = ContainerUtil.find(tasks, new Condition() { + @Override + public boolean value(VcsTaskHandler.TaskInfo taskInfo) { + return startFrom.equals(taskInfo.getName()); + } + }); + } + if (info == null) { + info = handler.getActiveTask(); + } + myBranchFrom.setSelectedItem(info); + myBranchFrom.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + VcsTaskHandler.TaskInfo item = (VcsTaskHandler.TaskInfo)myBranchFrom.getSelectedItem(); + if (item != null) { + PropertiesComponent.getInstance(project).setValue(START_FROM_BRANCH, item.getName()); + } + } + }); + break; + } + } + myBranchFrom.setRenderer(new ColoredListCellRenderer() { + @Override + protected void customizeCellRenderer(JList list, VcsTaskHandler.TaskInfo value, int index, boolean selected, boolean hasFocus) { + append(value.getName()); + } + }); } myBranchName.setText(taskManager.suggestBranchName(task)); @@ -122,7 +175,7 @@ public class OpenTaskDialog extends DialogWrapper { } public void createTask() { - TaskManagerImpl taskManager = (TaskManagerImpl)TaskManager.getManager(myProject); + final TaskManagerImpl taskManager = (TaskManagerImpl)TaskManager.getManager(myProject); taskManager.getState().markAsInProgress = isMarkAsInProgress(); taskManager.getState().createChangelist = myCreateChangelist.isSelected(); @@ -138,13 +191,21 @@ public class OpenTaskDialog extends DialogWrapper { LOG.warn(ex); } } - LocalTask activeTask = taskManager.getActiveTask(); - LocalTask localTask = taskManager.activateTask(myTask, isClearContext()); + final LocalTask activeTask = taskManager.getActiveTask(); + final LocalTask localTask = taskManager.activateTask(myTask, isClearContext()); if (myCreateChangelist.isSelected()) { taskManager.createChangeList(localTask, myChangelistName.getText()); } if (myCreateBranch.isSelected()) { - taskManager.createBranch(localTask, activeTask, myBranchName.getText()); + VcsTaskHandler.TaskInfo item = (VcsTaskHandler.TaskInfo)myBranchFrom.getSelectedItem(); + if (item != null && !item.equals(myVcsTaskHandler.getActiveTask())) { + myVcsTaskHandler.switchToTask(item, new Runnable() { + @Override + public void run() { + taskManager.createBranch(localTask, activeTask, myBranchName.getText()); + } + }); + } } if (myTask.getType() == TaskType.EXCEPTION && AnalyzeTaskStacktraceAction.hasTexts(myTask)) { AnalyzeTaskStacktraceAction.analyzeStacktrace(myTask, myProject); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java index 1dd06d9d186e..afc6a8002e73 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java @@ -379,11 +379,15 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe List branches = task.getBranches(false); VcsTaskHandler.TaskInfo info = fromBranches(branches); + switchBranch(info); + return task; + } + + public void switchBranch(VcsTaskHandler.TaskInfo info) { VcsTaskHandler[] handlers = VcsTaskHandler.getAllHandlers(myProject); for (VcsTaskHandler handler : handlers) { - handler.switchToTask(info); + handler.switchToTask(info, null); } - return task; } private static VcsTaskHandler.TaskInfo fromBranches(List branches) { diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java index 36cc584ba1a4..dab5b99834f2 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java @@ -69,7 +69,7 @@ public class TaskBranchesTest extends PlatformTestCase { assertEquals(2, repository.getBranches().getLocalBranches().size()); assertEquals(first, repository.getCurrentBranch().getName()); - handler.switchToTask(defaultInfo); + handler.switchToTask(defaultInfo, null); assertEquals("master", repository.getCurrentBranch().getName()); final String second = "second";