From e1d7e3a11eac67467e0ddf3d6d19ed107af966e3 Mon Sep 17 00:00:00 2001 From: Mathias Kinzler Date: Thu, 5 Aug 2010 15:06:45 +0200 Subject: History View: Create Branch/Tag on commit This allows to create a branch or tag on a commit by right-clicking the commit in the history view. Bug: 320469 Change-Id: I5a3a2db49b6713123d099969f6281d8231174899 Signed-off-by: Mathias Kinzler Signed-off-by: Chris Aniszczyk --- .../egit/ui/test/history/HistoryViewTest.java | 86 +++++++- org.eclipse.egit.ui/META-INF/MANIFEST.MF | 1 - org.eclipse.egit.ui/icons/obj16/checkout.gif | Bin 0 -> 940 bytes org.eclipse.egit.ui/plugin.properties | 10 +- org.eclipse.egit.ui/plugin.xml | 73 ++++--- .../src/org/eclipse/egit/ui/UIText.java | 6 + .../egit/ui/internal/actions/ActionCommands.java | 6 + .../ui/internal/actions/CheckoutCommitAction.java | 23 +++ .../actions/CheckoutCommitActionHandler.java | 217 +++++++++++++++++++++ .../actions/CreateBranchOnCommitAction.java | 22 +++ .../actions/CreateBranchOnCommitActionHandler.java | 73 +++++++ .../internal/actions/CreateTagOnCommitAction.java | 21 ++ .../actions/CreateTagOnCommitActionHandler.java | 76 ++++++++ .../egit/ui/internal/actions/RepositoryAction.java | 17 +- .../internal/actions/RepositoryActionHandler.java | 79 ++++++-- .../egit/ui/internal/actions/TagActionHandler.java | 23 --- .../egit/ui/internal/dialogs/CreateTagDialog.java | 43 +++- .../egit/ui/internal/history/GitHistoryPage.java | 14 -- .../command/AbstractHistoryViewCommandHandler.java | 116 ----------- .../internal/history/command/CheckoutHandler.java | 208 -------------------- .../src/org/eclipse/egit/ui/uitext.properties | 2 + 21 files changed, 698 insertions(+), 418 deletions(-) create mode 100644 org.eclipse.egit.ui/icons/obj16/checkout.gif create mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CheckoutCommitAction.java create mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CheckoutCommitActionHandler.java create mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateBranchOnCommitAction.java create mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateBranchOnCommitActionHandler.java create mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateTagOnCommitAction.java create mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateTagOnCommitActionHandler.java delete mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/AbstractHistoryViewCommandHandler.java delete mode 100644 org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CheckoutHandler.java diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/history/HistoryViewTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/history/HistoryViewTest.java index a898f4892d..3bd0cb7d79 100644 --- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/history/HistoryViewTest.java +++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/history/HistoryViewTest.java @@ -11,9 +11,12 @@ package org.eclipse.egit.ui.test.history; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; +import java.io.File; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -22,9 +25,16 @@ import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.egit.ui.UIText; import org.eclipse.egit.ui.common.LocalRepositoryTestCase; import org.eclipse.egit.ui.test.ContextMenuHelper; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotPerspective; import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable; import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarToggleButton; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; @@ -48,10 +58,12 @@ public class HistoryViewTest extends LocalRepositoryTestCase { private static int commitCount; + private static File repoFile; + @BeforeClass public static void setup() throws Exception { // File repoFile = - createProjectAndCommitToRepository(); + repoFile = createProjectAndCommitToRepository(); perspective = bot.activePerspective(); bot.perspectiveById("org.eclipse.pde.ui.PDEPerspective").activate(); IProject prj = ResourcesPlugin.getWorkspace().getRoot().getProject( @@ -237,4 +249,76 @@ public class HistoryViewTest extends LocalRepositoryTestCase { return bot.viewById("org.eclipse.team.ui.GenericHistoryView").bot() .table(); } + + @Test + public void testAddBranch() throws Exception { + Repository repo = lookupRepository(repoFile); + assertNull(repo.resolve(Constants.R_HEADS + "NewBranch")); + SWTBotTable table = getHistoryViewTable(PROJ1); + table.getTableItem(0).select(); + + ContextMenuHelper.clickContextMenu(table, util + .getPluginLocalizedValue("CreateBranchOnCommitActionLabel")); + SWTBotShell dialog = bot + .shell(UIText.BranchSelectionDialog_QuestionNewBranchTitle); + dialog.bot().text().setText("NewBranch"); + dialog.bot().button(IDialogConstants.OK_LABEL).click(); + waitInUI(); + assertNotNull(repo.resolve(Constants.R_HEADS + "NewBranch")); + } + + @Test + public void testAddTag() throws Exception { + Repository repo = lookupRepository(repoFile); + assertNull(repo.resolve(Constants.R_TAGS + "NewTag")); + final SWTBotTable table = getHistoryViewTable(PROJ1); + table.getTableItem(0).select(); + final RevCommit[] commit = new RevCommit[1]; + + Display.getDefault().syncExec(new Runnable() { + + public void run() { + commit[0] = (RevCommit) table.widget.getSelection()[0] + .getData(); + } + }); + + ContextMenuHelper.clickContextMenu(table, util + .getPluginLocalizedValue("CreateTagOnCommitActionLabel")); + SWTBotShell dialog = bot.shell(NLS.bind( + UIText.CreateTagDialog_CreateTagOnCommitTitle, commit[0] + .getId().name())); + dialog.bot().textWithLabel(UIText.CreateTagDialog_tagName).setText( + "NewTag"); + dialog.bot().textWithLabel(UIText.CreateTagDialog_tagMessage).setText( + "New Tag message"); + dialog.bot().button(IDialogConstants.OK_LABEL).click(); + waitInUI(); + assertNotNull(repo.resolve(Constants.R_TAGS + "NewTag")); + } + + @Test + public void testCheckOut() throws Exception { + Repository repo = lookupRepository(repoFile); + assertEquals(Constants.MASTER, repo.getBranch()); + + final SWTBotTable table = getHistoryViewTable(PROJ1); + // check out the second line + table.getTableItem(1).select(); + final RevCommit[] commit = new RevCommit[1]; + + Display.getDefault().syncExec(new Runnable() { + + public void run() { + commit[0] = (RevCommit) table.widget.getSelection()[0] + .getData(); + } + }); + + ContextMenuHelper.clickContextMenu(table, util + .getPluginLocalizedValue("CheckoutCommand")); + + waitInUI(); + assertEquals(commit[0].getId().name(), repo.getBranch()); + } } diff --git a/org.eclipse.egit.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.ui/META-INF/MANIFEST.MF index 566ab245d9..3cdbfe7074 100644 --- a/org.eclipse.egit.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.egit.ui/META-INF/MANIFEST.MF @@ -85,7 +85,6 @@ Export-Package: org.eclipse.egit.ui; org.eclipse.egit.ui.internal.factories;x-internal:=true, org.eclipse.egit.ui.internal.fetch;x-internal:=true, org.eclipse.egit.ui.internal.history;x-internal:=true, - org.eclipse.egit.ui.internal.history.command;x-internal:=true, org.eclipse.egit.ui.internal.preferences;x-internal:=true, org.eclipse.egit.ui.internal.push;x-internal:=true, org.eclipse.egit.ui.internal.repository;x-internal:=true, diff --git a/org.eclipse.egit.ui/icons/obj16/checkout.gif b/org.eclipse.egit.ui/icons/obj16/checkout.gif new file mode 100644 index 0000000000..45893eb4d0 Binary files /dev/null and b/org.eclipse.egit.ui/icons/obj16/checkout.gif differ diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties index 5b473a15c9..b825599ace 100644 --- a/org.eclipse.egit.ui/plugin.properties +++ b/org.eclipse.egit.ui/plugin.properties @@ -162,4 +162,12 @@ MergeWithDialogCommand = Merge... ResetCommand = Reset... gitsyncwizard.description = Git Synchronization ShowRepositoryAction_label = Show in Repositories &View -TeamMenuCommandsLabel = The commands for the Team menu \ No newline at end of file +TeamMenuCommandsLabel = The commands for the Team menu +SharedCommandsLabel = The shared commands +RepositoryCommandsLabel = The commands for the repositories view +HistoryViewCommandsLabel = History View Commands +HistoryCreateTagCommandLabel = Create Tag... +HistoryCreateBranchCommandLabel = Create Branch... +CheckoutCommitActionLabel = &Checkout +CreateBranchOnCommitActionLabel = Create &Branch... +CreateTagOnCommitActionLabel = Create &Tag... \ No newline at end of file diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml index b3efb7deb3..2005e7e3c1 100644 --- a/org.eclipse.egit.ui/plugin.xml +++ b/org.eclipse.egit.ui/plugin.xml @@ -95,7 +95,7 @@ @@ -183,7 +183,7 @@ @@ -246,6 +247,25 @@ name="reset"> + + + + + + + + + + @@ -1244,7 +1275,7 @@ - - + + + + + + @@ -1593,23 +1631,6 @@ - - - - - - - - - - - - - diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java index a127be61f9..ed546b2685 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java @@ -1263,6 +1263,9 @@ public class UIText extends NLS { /** */ public static String ConfirmationPage_title; + /** */ + public static String CreateBranchHandler_CreatePromptMessage; + /** */ public static String CreateBranchPage_BranchAlreadyExistsMessage; @@ -2199,6 +2202,9 @@ public class UIText extends NLS { /** */ public static String CreateTagDialog_clearButtonTooltip; + /** */ + public static String CreateTagDialog_CreateTagOnCommitTitle; + /** */ public static String CommitCombo_showSuggestedCommits; diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java index 2c3af3ba73..93c46babc1 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java @@ -32,6 +32,12 @@ public class ActionCommands { /** "Compare with revision" action command id */ public static final String COMPARE_WITH_REVISION_ACTION = "org.eclipse.egit.ui.team.CompareWithRevision"; //$NON-NLS-1$ + /** "Create Branch" command id */ + public static final String CREATE_BRANCH = "org.eclipse.egit.ui.command.historyCreateBranch"; //$NON-NLS-1$ + + /** "Create Tag" command id */ + public static final String CREATE_TAG = "org.eclipse.egit.ui.command.historyCreateTag"; //$NON-NLS-1$ + /** "Discard changes" action command id */ public static final String DISCARD_CHANGES_ACTION = "org.eclipse.egit.ui.team.Discard"; //$NON-NLS-1$ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CheckoutCommitAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CheckoutCommitAction.java new file mode 100644 index 0000000000..ecf7fc5796 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CheckoutCommitAction.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (C) 2010, Mathias Kinzler + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.egit.ui.internal.actions; + +import org.eclipse.egit.ui.internal.commands.SharedCommands; + +/** + * Check out a commit + */ +public class CheckoutCommitAction extends RepositoryAction { + /** + * Constructs this action + */ + public CheckoutCommitAction() { + super(SharedCommands.CHECKOUT, new CheckoutCommitActionHandler()); + } +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CheckoutCommitActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CheckoutCommitActionHandler.java new file mode 100644 index 0000000000..3865a3d27e --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CheckoutCommitActionHandler.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright (C) 2010, Mathias Kinzler + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.egit.ui.internal.actions; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.egit.core.op.BranchOperation; +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.RepositoryNode; +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.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.window.Window; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revplot.PlotCommit; +import org.eclipse.jgit.revwalk.RevCommit; +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; + +/** + * Action for checking out a commit + */ +public class CheckoutCommitActionHandler extends RepositoryActionHandler { + + private final class BranchMessageDialog extends MessageDialog { + private final List nodes; + + TableViewer branchesList; + + RefNode selected; + + private BranchMessageDialog(Shell parentShell, List nodes) { + super(parentShell, UIText.CheckoutHandler_SelectBranchTitle, null, + UIText.CheckoutHandler_SelectBranchMessage, + 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()); + + branchesList = new TableViewer(area, SWT.SINGLE | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.BORDER); + branchesList.setContentProvider(ArrayContentProvider.getInstance()); + branchesList.setLabelProvider(new BranchLabelProvider()); + branchesList.setInput(nodes); + branchesList + .addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + getButton(OK).setEnabled( + !event.getSelection().isEmpty()); + } + }); + return area; + } + + @Override + protected void buttonPressed(int buttonId) { + if (buttonId == OK) + selected = (RefNode) ((IStructuredSelection) branchesList + .getSelection()).getFirstElement(); + super.buttonPressed(buttonId); + } + + @Override + public void create() { + super.create(); + getButton(OK).setEnabled(false); + } + + public RefNode getSelectedNode() { + return selected; + } + + } + + 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(ExecutionEvent event) throws ExecutionException { + + PlotCommit commit = (PlotCommit) getSelection(event).getFirstElement(); + Repository repo = getRepository(false, event); + List availableBranches = new ArrayList(); + + final BranchOperation op; + + try { + Map localBranches = repo.getRefDatabase().getRefs( + Constants.R_HEADS); + for (Ref branch : localBranches.values()) { + if (branch.getLeaf().getObjectId().equals(commit.getId())) { + availableBranches.add(branch); + } + } + } catch (IOException e) { + // ignore here + } + + if (availableBranches.isEmpty()) + op = new BranchOperation(repo, commit.getId()); + else if (availableBranches.size() == 1) + op = new BranchOperation(repo, availableBranches.get(0).getName()); + else { + List nodes = new ArrayList(); + RepositoryNode repoNode = new RepositoryNode(null, repo); + for (Ref ref : availableBranches) { + nodes.add(new RefNode(repoNode, repo, ref)); + } + BranchMessageDialog dlg = new BranchMessageDialog(getShell(event), + nodes); + if (dlg.open() == Window.OK) { + op = new BranchOperation(repo, dlg.getSelectedNode() + .getObject().getName()); + } else { + op = null; + } + } + + if (op == null) + return null; + + // for the sake of UI responsiveness, let's start a job + Job job = new Job(NLS.bind(UIText.RepositoriesView_CheckingOutMessage, + commit.getId().name())) { + + @Override + protected IStatus run(IProgressMonitor monitor) { + + IWorkspaceRunnable wsr = new IWorkspaceRunnable() { + + public void run(IProgressMonitor myMonitor) + throws CoreException { + op.execute(myMonitor); + } + }; + + try { + ResourcesPlugin.getWorkspace().run(wsr, + ResourcesPlugin.getWorkspace().getRoot(), + IWorkspace.AVOID_UPDATE, monitor); + } catch (CoreException e1) { + return Activator.createErrorStatus(e1.getMessage(), e1); + } + + return Status.OK_STATUS; + } + }; + + job.setUser(true); + job.schedule(); + return null; + } + + @Override + public boolean isEnabled() { + try { + IStructuredSelection sel = getSelection(null); + return sel.size() == 1 + && sel.getFirstElement() instanceof RevCommit; + } catch (ExecutionException e) { + Activator.handleError(e.getMessage(), e, false); + return false; + } + } +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateBranchOnCommitAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateBranchOnCommitAction.java new file mode 100644 index 0000000000..cba5ff80c2 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateBranchOnCommitAction.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (C) 2010, Mathias Kinzler + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.egit.ui.internal.actions; + +/** + * Create a branch on a commit + */ +public class CreateBranchOnCommitAction extends RepositoryAction { + /** + * Constructs this action + */ + public CreateBranchOnCommitAction() { + super(ActionCommands.CREATE_BRANCH, + new CreateBranchOnCommitActionHandler()); + } +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateBranchOnCommitActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateBranchOnCommitActionHandler.java new file mode 100644 index 0000000000..5bbe5d71de --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateBranchOnCommitActionHandler.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (C) 2010, Mathias Kinzler + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.egit.ui.internal.actions; + +import java.io.IOException; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.egit.ui.Activator; +import org.eclipse.egit.ui.UIText; +import org.eclipse.egit.ui.internal.ValidationUtils; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.RefUpdate; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revplot.PlotCommit; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.osgi.util.NLS; + +/** + * Create a branch based on a commit + */ +public class CreateBranchOnCommitActionHandler extends RepositoryActionHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + try { + PlotCommit commit = (PlotCommit) getSelection(event) + .getFirstElement(); + ObjectId startAt = commit.getId(); + Repository repo = getRepository(false, event); + String prompt = NLS.bind( + UIText.CreateBranchHandler_CreatePromptMessage, startAt + .name(), Constants.R_HEADS); + + InputDialog dlg = new InputDialog(getShell(event), + UIText.BranchSelectionDialog_QuestionNewBranchTitle, + prompt, "", ValidationUtils //$NON-NLS-1$ + .getRefNameInputValidator(repo, Constants.R_HEADS)); + if (dlg.open() != Window.OK) + return null; + RefUpdate updateRef = repo.updateRef(Constants.R_HEADS + + dlg.getValue()); + updateRef.setNewObjectId(startAt); + updateRef.setRefLogMessage( + "branch: Created from " + startAt.name(), false); //$NON-NLS-1$ + updateRef.update(); + } catch (IOException e) { + throw new ExecutionException(e.getMessage(), e); + } + return null; + } + + @Override + public boolean isEnabled() { + try { + IStructuredSelection sel = getSelection(null); + return sel.size() == 1 + && sel.getFirstElement() instanceof RevCommit; + } catch (ExecutionException e) { + Activator.handleError(e.getMessage(), e, false); + return false; + } + } +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateTagOnCommitAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateTagOnCommitAction.java new file mode 100644 index 0000000000..528bba8ae2 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateTagOnCommitAction.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (C) 2010, Mathias Kinzler + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.egit.ui.internal.actions; + +/** + * Create a tag on a commit + */ +public class CreateTagOnCommitAction extends RepositoryAction { + /** + * Constructs this action + */ + public CreateTagOnCommitAction() { + super(ActionCommands.CREATE_TAG, new CreateTagOnCommitActionHandler()); + } +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateTagOnCommitActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateTagOnCommitActionHandler.java new file mode 100644 index 0000000000..200465914f --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreateTagOnCommitActionHandler.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (C) 2010, Mathias Kinzler + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.egit.ui.internal.actions; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.egit.core.op.TagOperation; +import org.eclipse.egit.ui.Activator; +import org.eclipse.egit.ui.internal.ValidationUtils; +import org.eclipse.egit.ui.internal.dialogs.CreateTagDialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.Tag; +import org.eclipse.jgit.revplot.PlotCommit; +import org.eclipse.jgit.revwalk.RevCommit; + +/** + * Create a tag based on a commit + */ +public class CreateTagOnCommitActionHandler extends RepositoryActionHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + PlotCommit commit = (PlotCommit) getSelection(event).getFirstElement(); + final Repository repo = getRepository(false, event); + + CreateTagDialog dialog = new CreateTagDialog(getShell(event), + ValidationUtils + .getRefNameInputValidator(repo, Constants.R_TAGS), + commit.getId()); + + dialog.setExistingTags(getRevTags(event)); + if (dialog.open() != Window.OK) + return null; + + final Tag tag = new Tag(repo); + PersonIdent personIdent = new PersonIdent(repo); + String tagName = dialog.getTagName(); + + tag.setTag(tagName); + tag.setTagger(personIdent); + tag.setMessage(dialog.getTagMessage()); + + tag.setObjId(commit.getId()); + + try { + new TagOperation(repo, tag, false) + .execute(new NullProgressMonitor()); + } catch (CoreException e) { + throw new ExecutionException(e.getMessage(), e); + } + return null; + } + + @Override + public boolean isEnabled() { + try { + IStructuredSelection sel = getSelection(null); + return sel.size() == 1 + && sel.getFirstElement() instanceof RevCommit; + } catch (ExecutionException e) { + Activator.handleError(e.getMessage(), e, false); + return false; + } + } +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryAction.java index c927c9aa67..39d580f821 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryAction.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryAction.java @@ -24,7 +24,6 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.ui.IObjectActionDelegate; -import org.eclipse.ui.ISelectionService; import org.eclipse.ui.ISources; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PlatformUI; @@ -64,11 +63,17 @@ public abstract class RepositoryAction extends AbstractHandler implements protected IStructuredSelection getSelection() { // TODO Synchronize CommitOperation overwrites this, can we get rid // of it? - ISelectionService srv = (ISelectionService) PlatformUI.getWorkbench() - .getActiveWorkbenchWindow().getService(ISelectionService.class); - if (srv == null) - return new StructuredSelection(); - return (IStructuredSelection) srv.getSelection(); + ISelection selection; + + IHandlerService hsr = (IHandlerService) PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getService(IHandlerService.class); + IEvaluationContext ctx = hsr.getCurrentState(); + selection = (ISelection) ctx + .getVariable(ISources.ACTIVE_MENU_SELECTION_NAME); + + if (selection instanceof IStructuredSelection) + return (IStructuredSelection) selection; + return new StructuredSelection(); } public void setActivePart(IAction action, IWorkbenchPart targetPart) { diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java index a209356b85..758cea2bee 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java @@ -10,15 +10,19 @@ *******************************************************************************/ package org.eclipse.egit.ui.internal.actions; +import java.io.IOException; import java.lang.reflect.Array; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Set; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; @@ -29,12 +33,19 @@ import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.Tag; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.ISelectionService; +import org.eclipse.team.ui.history.IHistoryView; +import org.eclipse.ui.ISources; import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.handlers.IHandlerService; /** * A helper class for Team Actions on Git controlled projects @@ -50,7 +61,7 @@ public abstract class RepositoryActionHandler extends AbstractHandler { throws ExecutionException { Set ret = new HashSet(); for (IResource resource : (IResource[]) getSelectedAdaptables( - getSelection(event), IResource.class)) + getSelection(event), IResource.class, event)) ret.add(resource.getProject()); return ret.toArray(new IProject[ret.size()]); } @@ -176,16 +187,13 @@ public abstract class RepositoryActionHandler extends AbstractHandler { if (event != null) selection = HandlerUtil.getCurrentSelectionChecked(event); else { - // the event is sometimes null, in particular, during - // isEnabled() - ISelectionService srv = (ISelectionService) PlatformUI - .getWorkbench().getActiveWorkbenchWindow().getService( - ISelectionService.class); - if (srv == null) + IHandlerService hsr = (IHandlerService) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getService(IHandlerService.class); + IEvaluationContext ctx = hsr.getCurrentState(); + selection = (ISelection) ctx.getVariable(ISources.ACTIVE_MENU_SELECTION_NAME); + if (selection == null) throw new ExecutionException( UIText.RepositoryActionHandler_CouldNotGetSelection_message); - else - selection = srv.getSelection(); + } if (selection instanceof IStructuredSelection) return (IStructuredSelection) selection; @@ -198,16 +206,19 @@ public abstract class RepositoryActionHandler extends AbstractHandler { * * @param selection * @param c + * @param event * @return the selected adaptables + * @throws ExecutionException */ @SuppressWarnings("unchecked") - protected Object[] getSelectedAdaptables(ISelection selection, Class c) { + protected Object[] getSelectedAdaptables(ISelection selection, Class c, + ExecutionEvent event) throws ExecutionException { ArrayList result = null; if (selection != null && !selection.isEmpty()) { result = new ArrayList(); Iterator elements = ((IStructuredSelection) selection).iterator(); while (elements.hasNext()) { - Object adapter = getAdapter(elements.next(), c); + Object adapter = getAdapter(elements.next(), c, event); if (c.isInstance(adapter)) { result.add(adapter); } @@ -220,7 +231,8 @@ public abstract class RepositoryActionHandler extends AbstractHandler { return (Object[]) Array.newInstance(c, 0); } - private Object getAdapter(Object adaptable, Class c) { + private Object getAdapter(Object adaptable, Class c, ExecutionEvent event) + throws ExecutionException { if (c.isInstance(adaptable)) { return adaptable; } @@ -231,6 +243,10 @@ public abstract class RepositoryActionHandler extends AbstractHandler { return adapter; } } + if (adaptable instanceof RevCommit) { + IHistoryView view = (IHistoryView) getPart(event); + return getAdapter(view.getHistoryPage().getInput(), c, event); + } return null; } @@ -258,7 +274,7 @@ public abstract class RepositoryActionHandler extends AbstractHandler { throws ExecutionException { Set result = new HashSet(); for (Object o : getSelection(event).toList()) { - IResource resource = (IResource) getAdapter(o, IResource.class); + IResource resource = (IResource) getAdapter(o, IResource.class, event); if (resource != null) result.add(resource); } @@ -281,6 +297,39 @@ public abstract class RepositoryActionHandler extends AbstractHandler { */ protected IWorkbenchPage getPartPage(ExecutionEvent event) throws ExecutionException { - return HandlerUtil.getActivePartChecked(event).getSite().getPage(); + return getPart(event).getSite().getPage(); + } + + /** + * @param event + * @return the page + * @throws ExecutionException + */ + protected IWorkbenchPart getPart(ExecutionEvent event) + throws ExecutionException { + return HandlerUtil.getActivePartChecked(event); + } + + /** + * @param event + * @return the tags + * @throws ExecutionException + */ + protected List getRevTags(ExecutionEvent event) + throws ExecutionException { + Repository repo = getRepository(false, event); + Collection revTags = repo.getTags().values(); + List tags = new ArrayList(); + RevWalk walk = new RevWalk(repo); + for (Ref ref : revTags) { + try { + Tag tag = walk.parseTag(repo.resolve(ref.getName())) + .asTag(walk); + tags.add(tag); + } catch (IOException e) { + throw new ExecutionException(e.getMessage(), e); + } + } + return tags; } } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagActionHandler.java index c3a7c31606..771978b4fb 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagActionHandler.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagActionHandler.java @@ -9,8 +9,6 @@ package org.eclipse.egit.ui.internal.actions; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; import java.util.List; import org.eclipse.core.commands.ExecutionEvent; @@ -33,7 +31,6 @@ import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; -import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Tag; import org.eclipse.jgit.revwalk.RevSort; @@ -139,26 +136,6 @@ public class TagActionHandler extends RepositoryActionHandler { } } - private List getRevTags(ExecutionEvent event) - throws ExecutionException { - Collection revTags = repo.getTags().values(); - List tags = new ArrayList(); - RevWalk walk = new RevWalk(repo); - for (Ref ref : revTags) { - try { - Tag tag = walk.parseTag(repo.resolve(ref.getName())).asTag(walk); - tags.add(tag); - } catch (IOException e) { - ErrorDialog.openError(getShell(event), - UIText.TagAction_errorDuringTagging, NLS.bind( - UIText.TagAction_errorWhileMappingRevTag, ref - .getName()), new Status(IStatus.ERROR, - Activator.getPluginId(), e.getMessage(), e)); - } - } - return tags; - } - private RevWalk getRevCommits(ExecutionEvent event) throws ExecutionException { RevWalk revWalk = new RevWalk(repo); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java index 2e18760fac..a1739b1553 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java @@ -106,6 +106,8 @@ public class CreateTagDialog extends Dialog { private final String branchName; + private final ObjectId commitId; + private final IInputValidator tagNameValidator; static class TagInputList extends LabelProvider implements IWorkbenchAdapter { @@ -175,6 +177,22 @@ public class CreateTagDialog extends Dialog { super(parent); this.tagNameValidator = tagNameValidator; this.branchName = branchName; + this.commitId = null; + } + + /** + * Construct dialog to creating or editing tag. + * + * @param parent + * @param tagNameValidator + * @param commitId + */ + public CreateTagDialog(Shell parent, IInputValidator tagNameValidator, + ObjectId commitId) { + super(parent); + this.tagNameValidator = tagNameValidator; + this.branchName = null; + this.commitId = commitId; } /** @@ -246,6 +264,10 @@ public class CreateTagDialog extends Dialog { if (branchName != null) { newShell.setText(NLS.bind( UIText.CreateTagDialog_questionNewTagTitle, branchName)); + } else if (commitId != null) { + newShell.setText(NLS.bind( + UIText.CreateTagDialog_CreateTagOnCommitTitle, commitId + .name())); } newShell.setMinimumSize(600, 400); @@ -299,9 +321,10 @@ public class CreateTagDialog extends Dialog { case CLEAR_ID: tagNameText.setText(""); //$NON-NLS-1$ tagMessageText.setText(""); //$NON-NLS-1$ - commitCombo.clearSelection(); - - commitCombo.setEnabled(true); + if (commitCombo != null) { + commitCombo.clearSelection(); + commitCombo.setEnabled(true); + } tagNameText.setEnabled(true); tagMessageText.setEnabled(true); overwriteButton.setEnabled(false); @@ -310,7 +333,8 @@ public class CreateTagDialog extends Dialog { case IDialogConstants.OK_ID: // read and store data from widgets tagName = tagNameText.getText(); - tagCommit = commitCombo.getValue(); + if (commitCombo != null) + tagCommit = commitCombo.getValue(); tagMessage = tagMessageText.getText(); overwriteTag = overwriteButton.getSelection(); //$FALL-THROUGH$ continue propagating OK button action @@ -402,7 +426,8 @@ public class CreateTagDialog extends Dialog { public void widgetSelected(SelectionEvent e) { boolean state = overwriteButton.getSelection(); tagNameText.setEnabled(state); - commitCombo.setEnabled(state); + if (commitCombo != null) + commitCombo.setEnabled(state); tagMessageText.setEnabled(state); validateInput(); } @@ -412,6 +437,8 @@ public class CreateTagDialog extends Dialog { } private void createAdvancedSection(final Composite composite) { + if (commitId!=null) + return; ExpandableComposite advanced = new ExpandableComposite(composite, ExpandableComposite.TREE_NODE | ExpandableComposite.CLIENT_INDENT); @@ -530,7 +557,8 @@ public class CreateTagDialog extends Dialog { overwriteButton.setEnabled(true); tagNameText.setEnabled(false); - commitCombo.setEnabled(false); + if (commitCombo != null) + commitCombo.setEnabled(false); tagMessageText.setEnabled(false); } @@ -540,7 +568,8 @@ public class CreateTagDialog extends Dialog { private void setTagImpl() { tagNameText.setText(tag.getTag()); - commitCombo.setSelectedElement(tag.getObjId()); + if (commitCombo != null) + commitCombo.setSelectedElement(tag.getObjId()); // handle un-annotated tags String message = tag.getMessage(); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java index 19e76cbf9a..69e4986220 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java @@ -38,7 +38,6 @@ import org.eclipse.egit.ui.UIText; import org.eclipse.egit.ui.internal.CompareUtils; import org.eclipse.egit.ui.internal.EgitUiEditorUtils; import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput; -import org.eclipse.egit.ui.internal.commands.SharedCommands; import org.eclipse.egit.ui.internal.trace.GitTraceLocation; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ActionContributionItem; @@ -107,8 +106,6 @@ import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.eclipse.ui.menus.CommandContributionItem; -import org.eclipse.ui.menus.CommandContributionItemParameter; import org.eclipse.ui.part.IPageSite; import org.eclipse.ui.progress.IWorkbenchSiteProgressService; @@ -144,8 +141,6 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener { private IAction compareModeAction; - private IContributionItem checkoutItem; - private boolean compareMode = false; private CreatePatchAction createPatchAction = new CreatePatchAction(); @@ -570,13 +565,6 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener { private void attachContextMenu(final Control c) { c.setMenu(popupMgr.createContextMenu(c)); - if (checkoutItem == null) { - CommandContributionItemParameter p = new CommandContributionItemParameter( - getSite(), SharedCommands.CHECKOUT, - SharedCommands.CHECKOUT, CommandContributionItem.STYLE_PUSH); - checkoutItem = new CommandContributionItem(p); - } - if (c == graph.getControl()) { c.addMenuDetectListener(new MenuDetectListener() { @@ -588,11 +576,9 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener { compareVersionsAction)); popupMgr.remove(new ActionContributionItem( viewVersionsAction)); - popupMgr.remove(checkoutItem); int size = ((IStructuredSelection) revObjectSelectionProvider .getSelection()).size(); if (size == 1) { - popupMgr.add(checkoutItem); popupMgr.add(new Separator()); popupMgr.add(createPatchAction); createPatchAction.setEnabled(createPatchAction.isEnabled()); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/AbstractHistoryViewCommandHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/AbstractHistoryViewCommandHandler.java deleted file mode 100644 index 27172fdf1a..0000000000 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/AbstractHistoryViewCommandHandler.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010 SAP AG. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathias Kinzler (SAP AG) - initial implementation - *******************************************************************************/ -package org.eclipse.egit.ui.internal.history.command; - -import java.util.List; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.commands.IHandler; -import org.eclipse.core.resources.IResource; -import org.eclipse.egit.core.project.RepositoryMapping; -import org.eclipse.egit.ui.UIText; -import org.eclipse.egit.ui.internal.history.GitHistoryPage; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.revplot.PlotCommit; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.ui.history.IHistoryView; -import org.eclipse.ui.handlers.HandlerUtil; - -/** - * Abstract superclass for history view based command handlers. - *

- * This provides some convenience methods for concrete subclasses - */ -public abstract class AbstractHistoryViewCommandHandler extends AbstractHandler - implements IHandler { - /** - * @param event - * @return the selection - * @throws ExecutionException - */ - @SuppressWarnings("unchecked") - protected List getSelection(ExecutionEvent event) - throws ExecutionException { - try { - ISelection selection = HandlerUtil - .getCurrentSelectionChecked(event); - return ((StructuredSelection) selection).toList(); - } catch (ClassCastException e) { - throw new ExecutionException(e.getMessage(), e); - } - } - - /** - * @param event - * @return the selection - * @throws ExecutionException - */ - protected PlotCommit getSingleCommit(ExecutionEvent event) - throws ExecutionException { - List selection = getSelection(event); - if (selection.size() == 1) - return selection.get(0); - throw new ExecutionException( - UIText.AbstractHitoryViewCommandHandler_CanNotGetCommitMessage); - } - - /** - * @param event - * @return the history page - * @throws ExecutionException - */ - private GitHistoryPage getPage(ExecutionEvent event) - throws ExecutionException { - try { - IHistoryView view = (IHistoryView) HandlerUtil - .getActivePartChecked(event); - return (GitHistoryPage) view.getHistoryPage(); - } catch (ClassCastException e) { - throw new ExecutionException(e.getMessage(), e); - } - } - - /** - * @param event - * @return the {@link Repository} of the history view's input - * @throws ExecutionException - */ - protected Repository getRepository(ExecutionEvent event) - throws ExecutionException { - GitHistoryPage page = getPage(event); - RepositoryMapping mapping = RepositoryMapping - .getMapping((IResource) page.getInput()); - - if (mapping == null) - throw new ExecutionException( - UIText.AbstractHitoryViewCommandHandler_NoRepositoryMessage); - return mapping.getRepository(); - } - - /** - * @param event - * @return the shell - * @throws ExecutionException - */ - protected Shell getShell(ExecutionEvent event) throws ExecutionException { - try { - IHistoryView view = (IHistoryView) HandlerUtil - .getActivePartChecked(event); - return view.getHistoryPage().getHistoryPageSite().getShell(); - } catch (ClassCastException e) { - throw new ExecutionException(e.getMessage(), e); - } - } -} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CheckoutHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CheckoutHandler.java deleted file mode 100644 index 409df7e00a..0000000000 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CheckoutHandler.java +++ /dev/null @@ -1,208 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010 SAP AG. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Mathias Kinzler (SAP AG) - initial implementation - *******************************************************************************/ -package org.eclipse.egit.ui.internal.history.command; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.egit.core.op.BranchOperation; -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.RepositoryNode; -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.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.window.Window; -import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.lib.Ref; -import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.revplot.PlotCommit; -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; - -/** - * Implements "Checkout" from history view - */ -public class CheckoutHandler extends AbstractHistoryViewCommandHandler { - - private final class BranchMessageDialog extends MessageDialog { - private final List nodes; - - TableViewer branchesList; - - RefNode selected; - - private BranchMessageDialog(Shell parentShell, List nodes) { - super(parentShell, UIText.CheckoutHandler_SelectBranchTitle, null, - UIText.CheckoutHandler_SelectBranchMessage, - 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()); - - branchesList = new TableViewer(area, SWT.SINGLE | SWT.H_SCROLL - | SWT.V_SCROLL | SWT.BORDER); - branchesList.setContentProvider(ArrayContentProvider.getInstance()); - branchesList.setLabelProvider(new BranchLabelProvider()); - branchesList.setInput(nodes); - branchesList - .addSelectionChangedListener(new ISelectionChangedListener() { - - public void selectionChanged(SelectionChangedEvent event) { - getButton(OK).setEnabled( - !event.getSelection().isEmpty()); - } - }); - return area; - } - - @Override - protected void buttonPressed(int buttonId) { - if (buttonId == OK) - selected = (RefNode) ((IStructuredSelection) branchesList - .getSelection()).getFirstElement(); - super.buttonPressed(buttonId); - } - - @Override - public void create() { - super.create(); - getButton(OK).setEnabled(false); - } - - public RefNode getSelectedNode() { - return selected; - } - - } - - 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(ExecutionEvent event) throws ExecutionException { - - PlotCommit commit = getSingleCommit(event); - Repository repo = getRepository(event); - List availableBranches = new ArrayList(); - - final BranchOperation op; - - try { - Map localBranches = repo.getRefDatabase().getRefs( - Constants.R_HEADS); - for (Ref branch : localBranches.values()) { - if (branch.getLeaf().getObjectId().equals(commit.getId())) { - availableBranches.add(branch); - } - } - } catch (IOException e) { - // ignore here - } - - if (availableBranches.isEmpty()) - op = new BranchOperation(repo, commit.getId()); - else if (availableBranches.size() == 1) - op = new BranchOperation(repo, availableBranches.get(0).getName()); - else { - List nodes = new ArrayList(); - RepositoryNode repoNode = new RepositoryNode(null, repo); - for (Ref ref : availableBranches) { - nodes.add(new RefNode(repoNode, repo, ref)); - } - BranchMessageDialog dlg = new BranchMessageDialog(getShell(event), - nodes); - if (dlg.open() == Window.OK) { - op = new BranchOperation(repo, dlg.getSelectedNode() - .getObject().getName()); - } else { - op = null; - } - } - - if (op == null) - return null; - - // for the sake of UI responsiveness, let's start a job - Job job = new Job(NLS.bind(UIText.RepositoriesView_CheckingOutMessage, - commit.getId().name())) { - - @Override - protected IStatus run(IProgressMonitor monitor) { - - IWorkspaceRunnable wsr = new IWorkspaceRunnable() { - - public void run(IProgressMonitor myMonitor) - throws CoreException { - op.execute(myMonitor); - } - }; - - try { - ResourcesPlugin.getWorkspace().run(wsr, - ResourcesPlugin.getWorkspace().getRoot(), - IWorkspace.AVOID_UPDATE, monitor); - } catch (CoreException e1) { - return Activator.createErrorStatus(e1.getMessage(), e1); - } - - return Status.OK_STATUS; - } - }; - - job.setUser(true); - job.schedule(); - - return null; - } - -} 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 7f0aabc50b..2aa7a535be 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 @@ -449,6 +449,7 @@ ConfirmationPage_errorUnexpected=Unexpected error occurred: {0} ConfirmationPage_requireUnchangedButton=Push only if remote refs don't change in the mean time ConfirmationPage_showOnlyIfChanged=Show final report dialog only when it differs from this confirmation report ConfirmationPage_title=Push Confirmation +CreateBranchHandler_CreatePromptMessage=Please enter a name for the new branch. The new branch will be based on commit {0} and the name will be prepended with {1} CreateBranchPage_BranchAlreadyExistsMessage=Branch {0} already exists CreateBranchPage_BranchNameLabel=Branch name CreateBranchPage_CheckingOutMessage=Checking out new branch... @@ -776,6 +777,7 @@ CreateTagDialog_advancedMessage=Choose commit that should be associated with thi CreateTagDialog_tagNameToolTip=Start typing tag name to filter list of existing tags. CreateTagDialog_clearButton=C&lear CreateTagDialog_clearButtonTooltip=Clear all dialog fields. +CreateTagDialog_CreateTagOnCommitTitle=Create a new tag on commit {0} CommitCombo_showSuggestedCommits=Start typing SHA-1 of existing commit or part of first line in commit message to see suggested commits. -- cgit v1.2.3