summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorBenjamin Muskalla2010-07-14 07:58:56 (EDT)
committer Matthias Sohn2010-07-16 04:41:39 (EDT)
commit551b1d4c7c79d7ac661e00bf23caf2851858bf1a (patch)
tree06969afa05e5f39e5be381ca5411d2a412c127b9
parentee8b0c15e0decd309980d09de3397fb86a96ba91 (diff)
downloadegit-551b1d4c7c79d7ac661e00bf23caf2851858bf1a.zip
egit-551b1d4c7c79d7ac661e00bf23caf2851858bf1a.tar.gz
egit-551b1d4c7c79d7ac661e00bf23caf2851858bf1a.tar.bz2
Allow deleting multiple branches at oncerefs/changes/87/1087/5
From time to time, one wants to cleanup old and obsolete branches. To help the user with this task, it is now possible to select multiple local branches and delete them all at once. To improve user experience, the affected branches will be shown again in the dialog before confirmation. Bug: 319246 Change-Id: I70ea9db24fafa90742ee147248558d8ffb011bc8 Signed-off-by: Benjamin Muskalla <bmuskalla@eclipsesource.com> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java73
-rw-r--r--org.eclipse.egit.ui/plugin.xml3
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteBranchCommand.java106
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties2
4 files changed, 155 insertions, 29 deletions
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
index 40eb097..d255654 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
@@ -558,4 +558,77 @@ public class GitRepositoriesViewTest extends GitRepositoriesViewTestBase {
perspective.activate();
}
}
+
+ @Test
+ public void testDeleteSingleBranch() throws Exception {
+ // expand first level
+ SWTBotTree tree = getOrOpenView().bot().tree();
+ refreshAndWait();
+ // create a branch (no checkout)
+ SWTBotTreeItem localBranchesItem = getLocalBranchesItem(tree,
+ repositoryFile).expand();
+ SWTBotTreeItem masterNode = localBranchesItem.getNode("master");
+ masterNode.select();
+ ContextMenuHelper.clickContextMenu(tree, "Create Branch...");
+ SWTBotShell createBranchShell = bot.shell("Create Branch");
+ createBranchShell.bot().text("").setText("abc");
+ createBranchShell.bot().checkBox().deselect();
+ createBranchShell.bot().button(IDialogConstants.FINISH_LABEL).click();
+ refreshAndWait();
+ // delete branch
+ localBranchesItem.getNode("abc").select();
+ ContextMenuHelper.clickContextMenu(tree, "Delete Branch...");
+
+ SWTBotShell deleteBranchDialog = bot.shell(UIText.RepositoriesView_ConfirmDeleteTitle);
+ deleteBranchDialog.bot().button(IDialogConstants.OK_LABEL).click();
+ refreshAndWait();
+ SWTBotTreeItem[] items = getLocalBranchesItem(tree, repositoryFile)
+ .getItems();
+ assertEquals("Wrong number of branches", 2, items.length);
+ assertEquals("master", items[0].getText());
+ assertEquals("stable", items[1].getText());
+ }
+
+ @Test
+ public void testDeleteMultipleBranches() throws Exception {
+ // expand first level
+ SWTBotTree tree = getOrOpenView().bot().tree();
+ refreshAndWait();
+ // open a branch (checkout)
+ SWTBotTreeItem localBranchesItem = getLocalBranchesItem(tree,
+ repositoryFile).expand();
+ SWTBotTreeItem masterNode = localBranchesItem.getNode("master");
+ // create first branch (abc)
+ masterNode.select();
+ ContextMenuHelper.clickContextMenu(tree, "Create Branch...");
+ SWTBotShell createBranchShell = bot.shell("Create Branch");
+ createBranchShell.bot().text("").setText("abc");
+ createBranchShell.bot().checkBox().deselect();
+ createBranchShell.bot().button(IDialogConstants.FINISH_LABEL).click();
+ // create second branch (123)
+ ContextMenuHelper.clickContextMenu(tree, "Create Branch...");
+ createBranchShell = bot.shell("Create Branch");
+ createBranchShell.bot().text("").setText("123");
+ createBranchShell.bot().checkBox().deselect();
+ createBranchShell.bot().button(IDialogConstants.FINISH_LABEL).click();
+ refreshAndWait();
+ localBranchesItem = getLocalBranchesItem(tree,
+ repositoryFile).expand();
+ // delete both
+ localBranchesItem.select("abc", "123");
+ ContextMenuHelper.clickContextMenu(tree, UIText.RepositoriesView_DeleteBranchMenu);
+
+ SWTBotShell deleteBranchDialog = bot.shell(UIText.RepositoriesView_ConfirmDeleteTitle);
+ assertNotNull(deleteBranchDialog.bot().table(0).getTableItem("refs/heads/abc"));
+ assertNotNull(deleteBranchDialog.bot().table(0).getTableItem("refs/heads/123"));
+ deleteBranchDialog.bot().button(IDialogConstants.OK_LABEL).click();
+ refreshAndWait();
+
+ SWTBotTreeItem[] items = getLocalBranchesItem(tree, repositoryFile)
+ .getItems();
+ assertEquals("Wrong number of branches", 2, items.length);
+ assertEquals("master", items[0].getText());
+ assertEquals("stable", items[1].getText());
+ }
+
} \ No newline at end of file
diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml
index 1c3ec3e..7a072de 100644
--- a/org.eclipse.egit.ui/plugin.xml
+++ b/org.eclipse.egit.ui/plugin.xml
@@ -1073,9 +1073,6 @@
<visibleWhen
checkEnabled="false">
<and>
- <count
- value="1">
- </count>
<iterate>
<and>
<or>
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteBranchCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteBranchCommand.java
index 6919d91..36a8038 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteBranchCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteBranchCommand.java
@@ -12,6 +12,8 @@ package org.eclipse.egit.ui.internal.repository.tree.command;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
@@ -19,51 +21,92 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIText;
import org.eclipse.egit.ui.internal.repository.tree.RefNode;
+import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNodeType;
+import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.window.Window;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
/**
* Deletes a branch.
- * <p>
- * TODO This uses the force option always, so a warning pop-up is shown to the
- * user; instead this should check if deletion can be performed without data
- * loss and in this case the deletion should be done quietly; the warning pop-up
- * should only be shown if the force option is really needed.
*/
public class DeleteBranchCommand extends
RepositoriesViewCommandHandler<RefNode> {
+
+ private final class BranchMessageDialog extends MessageDialog {
+ private final List<RefNode> nodes;
+
+ private BranchMessageDialog(Shell parentShell, List<RefNode> nodes) {
+ super(parentShell, UIText.RepositoriesView_ConfirmDeleteTitle,
+ null, UIText.RepositoriesView_ConfirmBranchDeletionMessage,
+ MessageDialog.QUESTION, new String[] {
+ IDialogConstants.OK_LABEL,
+ IDialogConstants.CANCEL_LABEL }, 0);
+ this.nodes = nodes;
+ }
+
+ @Override
+ protected Control createCustomArea(Composite parent) {
+ Composite area = new Composite(parent, SWT.NONE);
+ area.setLayoutData(new GridData(GridData.FILL_BOTH));
+ area.setLayout(new FillLayout());
+
+ TableViewer branchesList = new TableViewer(area);
+ branchesList.setContentProvider(ArrayContentProvider.getInstance());
+ branchesList.setLabelProvider(new BranchLabelProvider());
+ branchesList.setInput(nodes);
+ return area;
+ }
+
+ }
+
+ private final class BranchLabelProvider extends LabelProvider {
+ @Override
+ public String getText(Object element) {
+ RefNode refNode = (RefNode) element;
+ return refNode.getObject().getName();
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ return RepositoryTreeNodeType.REF.getIcon();
+ }
+ }
+
public Object execute(final ExecutionEvent event) throws ExecutionException {
- final RefNode node = getSelectedNodes(event).get(0);
- final Ref ref = node.getObject();
+ final List<RefNode> nodes = getSelectedNodes(event);
+ final List<Ref> refs = new ArrayList<Ref>();
+ for (RefNode refNode : nodes) {
+ refs.add(refNode.getObject());
+ }
Shell shell = getShell(event);
- if (!MessageDialog.openConfirm(shell,
- UIText.RepositoriesView_ConfirmDeleteTitle, NLS.bind(
- UIText.RepositoriesView_ConfirmBranchDeletionMessage,
- ref.getName())))
+ MessageDialog messageDialog = new BranchMessageDialog(shell, nodes);
+ if (messageDialog.open() != Window.OK)
return null;
try {
- new ProgressMonitorDialog(shell).run(
- false, false, new IRunnableWithProgress() {
+ new ProgressMonitorDialog(shell).run(false, false,
+ new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
throws InvocationTargetException,
InterruptedException {
try {
- RefUpdate op = node.getRepository().updateRef(
- ref.getName());
- op.setRefLogMessage("branch deleted", //$NON-NLS-1$
- false);
- // we set the force update in order
- // to avoid having this rejected
- // due to minor issues
- op.setForceUpdate(true);
- op.delete();
+ for (RefNode refNode : nodes)
+ deleteBranch(refNode, refNode.getObject());
} catch (IOException ioe) {
throw new InvocationTargetException(ioe);
}
@@ -71,8 +114,8 @@ public class DeleteBranchCommand extends
});
} catch (InvocationTargetException e1) {
Activator.handleError(
- UIText.RepositoriesView_BranchDeletionFailureMessage, e1
- .getCause(), true);
+ UIText.RepositoriesView_BranchDeletionFailureMessage,
+ e1.getCause(), true);
e1.printStackTrace();
} catch (InterruptedException e1) {
// ignore
@@ -80,4 +123,17 @@ public class DeleteBranchCommand extends
return null;
}
+
+ private void deleteBranch(final RefNode node, final Ref ref)
+ throws IOException {
+ RefUpdate op = node.getRepository().updateRef(ref.getName());
+ op.setRefLogMessage("branch deleted", //$NON-NLS-1$
+ false);
+ // TODO: This uses the force option always, so a warning pop-up is shown to the
+ // user; instead this should check if deletion can be performed without data
+ // loss and in this case the deletion should be done quietly; the warning pop-up
+ // should only be shown if the force option is really needed.
+ op.setForceUpdate(true);
+ op.delete();
+ }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
index 605d193..00e3bdc 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
@@ -602,7 +602,7 @@ RepositoriesView_Clone_Tooltip=Clone a Git Repository
RepositoriesView_CollapseAllMenu=Collapse all
RepositoriesView_ConfigureFetchMenu=&Configure Fetch...
RepositoriesView_ConfigurePushMenu=&Configure Push...
-RepositoriesView_ConfirmBranchDeletionMessage=Are you sure you want to forcefully delete branch {0}?\n\n\
+RepositoriesView_ConfirmBranchDeletionMessage=Are you sure you want to forcefully delete the following branches?\n\n\
No check will be done if all its commits have been merged to the currently checked out branch.
RepositoriesView_ConfirmDeleteRemoteHeader=Confirm deletion of remote configuration
RepositoriesView_ConfirmDeleteRemoteMessage=This will remove remote configuration {0} completely, are you sure?