diff options
| author | Markus Duft | 2012-03-14 22:03:25 +0000 |
|---|---|---|
| committer | Matthias Sohn | 2012-04-02 09:10:02 +0000 |
| commit | 82b60e5aff1bd4ee9e8413806ab491d4da4302fa (patch) | |
| tree | 5966752271704cb1c1582da82312820f4c7547b7 | |
| parent | ca2d68af286093b76ff9da962e2db04e8036b1a7 (diff) | |
| download | egit-82b60e5aff1bd4ee9e8413806ab491d4da4302fa.tar.gz egit-82b60e5aff1bd4ee9e8413806ab491d4da4302fa.tar.xz egit-82b60e5aff1bd4ee9e8413806ab491d4da4302fa.zip | |
Allow push of single Refs/Commits from Repo & History Views
This adds a new SimplePushWizard which just allows selecting a target
remote and ref name. It then pushes out the selected Ref/Commit to the
selected target ref.
While implementing this I split out the Ref content assist functionality
from the existing RefSpecDialog to be reusable by this code.
Bug: 341076
Bug: 356314
Bug: 337747
CQ: 6347
Change-Id: If3be09886c23b031489116d448cae2dce29e281a
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 files changed, 661 insertions, 118 deletions
diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties index 1b7516ed33..5411979b59 100644 --- a/org.eclipse.egit.ui/plugin.properties +++ b/org.eclipse.egit.ui/plugin.properties @@ -168,6 +168,7 @@ CompareModeCommandParameter.name = Compare mode CreatePatchCommand.name = Create Patch CreateBranchCommand.name = Create Branch CreateTagCommand.name = Create Tag +PushCommit.name = Push Commit... ResetCommand.name = Reset ResetModeCommandParameter.name = Reset mode ResetQuickdiffCommand.name = Reset quickdiff baseline @@ -176,6 +177,8 @@ SetQuickdiffBaselineCommand.name = Set quickdiff baseline RepoViewFetch.label = &Fetch... RepoViewCommit.label = &Commit... RepoViewPush.label = &Push... +RepoViewPushBranch.label = &Push Branch... +RepoViewPushTag.label = &Push Tag... RepoViewImportProjects.label = &Import Projects... RepoViewCheckout.label = &Checkout RepoViewSynchronize.label = &Synchronize with Workspace diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml index 31a74959b6..2a09d47bd6 100644 --- a/org.eclipse.egit.ui/plugin.xml +++ b/org.eclipse.egit.ui/plugin.xml @@ -1090,13 +1090,19 @@ <count value="1"> </count> - <and> - <iterate> - <instanceof - value="org.eclipse.egit.ui.internal.repository.tree.RepositoryNode"> - </instanceof> - </iterate> - </and> + <iterate> + <or> + <instanceof + value="org.eclipse.egit.ui.internal.repository.tree.RefNode"> + </instanceof> + <instanceof + value="org.eclipse.egit.ui.internal.repository.tree.TagNode"> + </instanceof> + <instanceof + value="org.eclipse.egit.ui.internal.repository.tree.RepositoryNode"> + </instanceof> + </or> + </iterate> </and> </activeWhen> </handler> @@ -1871,6 +1877,44 @@ </visibleWhen> </command> <command + commandId="org.eclipse.egit.ui.team.Push" + icon="icons/obj16/push.gif" + label="%RepoViewPushBranch.label" + style="push"> + <visibleWhen + checkEnabled="false"> + <and> + <count + value="1"> + </count> + <iterate> + <instanceof + value="org.eclipse.egit.ui.internal.repository.tree.RefNode"> + </instanceof> + </iterate> + </and> + </visibleWhen> + </command> + <command + commandId="org.eclipse.egit.ui.team.Push" + icon="icons/obj16/push.gif" + label="%RepoViewPushTag.label" + style="push"> + <visibleWhen + checkEnabled="false"> + <and> + <count + value="1"> + </count> + <iterate> + <instanceof + value="org.eclipse.egit.ui.internal.repository.tree.TagNode"> + </instanceof> + </iterate> + </and> + </visibleWhen> + </command> + <command commandId="org.eclipse.egit.ui.RepositoriesViewCreateBranch" icon="icons/obj16/new_branch_obj.gif" label="%RepoViewCreateBranch.label" @@ -2595,12 +2639,10 @@ <count value="1"> </count> - <iterate - ifEmpty="false" - operator="and"> - <instanceof - value="org.eclipse.egit.ui.internal.repository.tree.RepositoryNode"> - </instanceof> + <iterate> + <instanceof + value="org.eclipse.egit.ui.internal.repository.tree.RepositoryNode"> + </instanceof> </iterate> </and> </visibleWhen> @@ -3988,6 +4030,10 @@ icon="icons/obj16/new_tag_obj.gif"> </image> <image + commandId="org.eclipse.egit.ui.history.PushCommit" + icon="icons/obj16/push.gif"> + </image> + <image commandId="org.eclipse.egit.ui.history.CheckoutCommand" icon="icons/obj16/checkout.gif"> </image> @@ -4489,6 +4535,11 @@ name="%CreateTagCommand.name"> </command> <command + defaultHandler="org.eclipse.egit.ui.internal.history.command.PushCommitHandler" + id="org.eclipse.egit.ui.history.PushCommit" + name="%PushCommit.name"> + </command> + <command defaultHandler="org.eclipse.egit.ui.internal.history.command.ResetHandler" id="org.eclipse.egit.ui.history.Reset" name="%ResetCommand.name"> 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 92023b54b3..0bb74efe4d 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 @@ -541,6 +541,9 @@ public class UIText extends NLS { public static String GitHistoryPage_ListIncompleteWarningMessage; /** */ + public static String GitHistoryPage_pushCommit; + + /** */ public static String GitHistoryPage_ShowSubMenuLabel; /** */ @@ -4007,6 +4010,18 @@ public class UIText extends NLS { public static String SimplePushActionHandler_NothingToPushDialogTitle; /** */ + public static String SimplePushSpecPage_message; + + /** */ + public static String SimplePushSpecPage_pushAheadInfo; + + /** */ + public static String SimplePushSpecPage_TargetRefName; + + /** */ + public static String SimplePushSpecPage_title; + + /** */ public static String SkipRebaseCommand_CancelDialogMessage; /** */ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentAssistProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentAssistProvider.java new file mode 100644 index 0000000000..2f2cfa8faf --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentAssistProvider.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (C) 2011, Mathias Kinzler <mathias.kinzler@sap.com> + * Copyright (C) 2012, Markus Duft <markus.duft@salomon.at> + * + * 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.components; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.egit.core.op.ListRemoteOperation; +import org.eclipse.egit.ui.Activator; +import org.eclipse.egit.ui.UIPreferences; +import org.eclipse.egit.ui.UIText; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.RefDatabase; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.transport.URIish; +import org.eclipse.swt.widgets.Shell; + +/** + * Contains functionality required to calculate content assist data for {@link Ref}s + */ +public class RefContentAssistProvider { + private List<Ref> destinationRefs; + private List<Ref> sourceRefs; + private final Shell shell; + private final Repository repo; + private URIish uri; + + /** + * @param repo the repository + * @param uri the uri to fetch branches from + * @param shell the shell used to attach progress dialogs to. + */ + public RefContentAssistProvider(Repository repo, URIish uri, Shell shell) { + this.repo = repo; + this.uri = uri; + this.shell = shell; + } + + /** + * @param source whether we want proposals for the source or the destination of the operation + * @param pushMode whether the operation is a push or a fetch + * @return a list of all refs for the given mode. + */ + public List<Ref> getRefsForContentAssist(boolean source, boolean pushMode) { + if (source) { + if (sourceRefs != null) + return sourceRefs; + } else if (destinationRefs != null) + return destinationRefs; + + List<Ref> result = new ArrayList<Ref>(); + try { + boolean local = pushMode == source; + if (!local) { + final ListRemoteOperation lop = new ListRemoteOperation(repo, + uri, + Activator.getDefault().getPreferenceStore().getInt( + UIPreferences.REMOTE_CONNECTION_TIMEOUT)); + + new ProgressMonitorDialog(shell).run(false, true, + new IRunnableWithProgress() { + + public void run(IProgressMonitor monitor) + throws InvocationTargetException, + InterruptedException { + monitor + .beginTask( + UIText.RefSpecDialog_GettingRemoteRefsMonitorMessage, + IProgressMonitor.UNKNOWN); + lop.run(monitor); + monitor.done(); + } + }); + for (Ref ref : lop.getRemoteRefs()) + if (ref.getName().startsWith(Constants.R_HEADS) + || (!pushMode && ref.getName().startsWith( + Constants.R_TAGS))) + result.add(ref); + + } else if (pushMode) + for (Ref ref : repo.getRefDatabase().getRefs( + RefDatabase.ALL).values()) { + if (ref.getName().startsWith(Constants.R_REMOTES)) + continue; + result.add(ref); + } + else + for (Ref ref : repo.getRefDatabase().getRefs( + Constants.R_REMOTES).values()) + result.add(ref); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + Activator.handleError(e.getMessage(), e, true); + return result; + } + if (source) + sourceRefs = result; + else + destinationRefs = result; + return result; + } + + /** + * @return the associated current repository. + */ + public Repository getRepository() { + return repo; + } + + /** + * @return the associated remote config to fetch branches from. + */ + public URIish getRemoteURI() { + return uri; + } +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/SimplePushSpecPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/SimplePushSpecPage.java new file mode 100644 index 0000000000..92803c18a5 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/SimplePushSpecPage.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (C) 2012, Markus Duft <markus.duft@salomon.at> + * + * 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.components; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.egit.ui.UIText; +import org.eclipse.egit.ui.UIUtils; +import org.eclipse.egit.ui.UIUtils.IRefListProvider; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.jgit.lib.BranchTrackingStatus; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + * A page that allows to select a target branch for a push operation. + */ +public class SimplePushSpecPage extends WizardPage { + + private boolean forceUpdate; + + private Text remoteRefName; + + private String sourceName; + + private Repository repository; + + /** + * the content assist provider for the {@link Ref}s + */ + protected RefContentAssistProvider assist; + + /** + * Creates a new wizard page that allows selection of the target + * + * @param niceSourceName + * the nice displayable name of the source to be pushed. + * @param repo + * source repository + */ + public SimplePushSpecPage(String niceSourceName, Repository repo) { + super(UIText.SimplePushSpecPage_title); + setTitle(UIText.SimplePushSpecPage_title); + setMessage(NLS.bind(UIText.SimplePushSpecPage_message, niceSourceName)); + + this.sourceName = niceSourceName; + this.repository = repo; + } + + public void createControl(Composite parent) { + Composite main = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(main); + main.setLayout(new GridLayout(1, false)); + + Composite inputPanel = new Composite(main, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(inputPanel); + inputPanel.setLayout(new GridLayout(2, false)); + + final Label lblRemote = new Label(inputPanel, SWT.NONE); + lblRemote.setText(UIText.SimplePushSpecPage_TargetRefName); + remoteRefName = new Text(inputPanel, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(remoteRefName); + remoteRefName.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + setPageComplete(isPageComplete()); + } + }); + + UIUtils.addRefContentProposalToText(remoteRefName, repository, + new IRefListProvider() { + public List<Ref> getRefList() { + if (assist != null) + return assist.getRefsForContentAssist(false, true); + + return Collections.emptyList(); + } + }); + + final Button forceButton = new Button(main, SWT.CHECK); + forceButton.setText(UIText.RefSpecDialog_ForceUpdateCheckbox); + GridDataFactory.fillDefaults().grab(true, false).applyTo(forceButton); + + forceButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + forceUpdate = forceButton.getSelection(); + } + }); + + setControl(main); + } + + /** + * pre-fills the destination box with a remote ref name if one exists that + * matches the local branch name. + */ + protected void updateDestinationField() { + setMessage(NLS.bind(UIText.SimplePushSpecPage_message, sourceName)); + String checkRemote = sourceName; + + if (sourceName.startsWith(Constants.R_HEADS)) { + try { + BranchTrackingStatus status = BranchTrackingStatus.of( + repository, + sourceName.substring(Constants.R_HEADS.length())); + + if (status != null) { + // calculate the name of the branch on the other side. + checkRemote = status.getRemoteTrackingBranch(); + checkRemote = Constants.R_HEADS + + checkRemote.substring(checkRemote.indexOf('/', + Constants.R_REMOTES.length() + 1) + 1); + + setMessage(NLS.bind( + UIText.SimplePushSpecPage_pushAheadInfo, + new Object[] { sourceName, + Integer.valueOf(status.getAheadCount()), + status.getRemoteTrackingBranch() }), + IStatus.INFO); + } + } catch (Exception e) { + // ignore and continue... + } + + if (assist == null) { + if (checkRemote != null) + remoteRefName.setText(checkRemote); + return; + } + + if (checkRemote == null) + checkRemote = sourceName; + + for (Ref ref : assist.getRefsForContentAssist(false, true)) + if (ref.getName().equals(checkRemote)) + remoteRefName.setText(checkRemote); + } + } + + @Override + public boolean isPageComplete() { + return !remoteRefName.getText().isEmpty(); + } + + /** + * Whether the user wants to force pushing. + * + * @return whether to force the push + */ + public boolean isForceUpdate() { + return forceUpdate; + } + + /** + * Retrieves the target name to push to. + * + * @return the target name. + */ + public String getTargetRef() { + return remoteRefName.getText(); + } + +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java index fbe852ac21..2f2322277e 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java @@ -708,6 +708,9 @@ class CommitGraphTable { popupMgr.add(getCommandContributionItem( HistoryViewCommands.CHECKOUT, UIText.GitHistoryPage_CheckoutMenuLabel)); + popupMgr.add(getCommandContributionItem( + HistoryViewCommands.PUSH_COMMIT, + UIText.GitHistoryPage_pushCommit)); popupMgr.add(new Separator()); popupMgr.add(getCommandContributionItem( HistoryViewCommands.CREATE_BRANCH, diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/HistoryViewCommands.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/HistoryViewCommands.java index 0b24be3d8f..1cec20730d 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/HistoryViewCommands.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/HistoryViewCommands.java @@ -47,6 +47,9 @@ public class HistoryViewCommands { /** "Create Tag" */ public static final String CREATE_TAG = "org.eclipse.egit.ui.history.CreateTag"; //$NON-NLS-1$ + /** "Push Commit" */ + public static final String PUSH_COMMIT = "org.eclipse.egit.ui.history.PushCommit"; //$NON-NLS-1$ + /** "Open" */ public static final String OPEN = "org.eclipse.egit.ui.history.ShowVersions"; //$NON-NLS-1$ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/PushCommitHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/PushCommitHandler.java new file mode 100644 index 0000000000..c6b446ae3d --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/PushCommitHandler.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (C) 2012, Markus Duft <markus.duft@salomon.at> + * + * 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.history.command; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.egit.ui.Activator; +import org.eclipse.egit.ui.internal.history.GitHistoryPage; +import org.eclipse.egit.ui.internal.push.SimplePushRefWizard; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revplot.PlotCommit; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Command handler to enable pushing commits from the Git History View + */ +public class PushCommitHandler extends AbstractHistoryCommandHandler { + public Object execute(ExecutionEvent event) throws ExecutionException { + PlotCommit commit = (PlotCommit) getSelection(getPage()).getFirstElement(); + final Repository repo = getRepository(event); + + try { + WizardDialog dlg = new WizardDialog(HandlerUtil + .getActiveShellChecked(event), new SimplePushRefWizard(repo, commit.getId())); + dlg.setHelpAvailable(true); + dlg.open(); + } catch (Exception e) { + Activator.handleError(e.getMessage(), e, true); + } + + return null; + } + + @Override + public boolean isEnabled() { + GitHistoryPage page = getPage(); + if (page == null) + return false; + IStructuredSelection sel = getSelection(page); + return sel.size() == 1 && sel.getFirstElement() instanceof RevCommit; + } +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java index 94d5eaadf7..8c45f04f91 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java @@ -168,8 +168,8 @@ public class PushWizard extends Wizard { resultToCompare = confirmPage.getConfirmedResult(); else resultToCompare = null; - final Job job = new PushJob(operation, resultToCompare, - getDestinationString()); + final Job job = new PushJob(localDb, operation, resultToCompare, + getDestinationString(repoPage.getSelection())); job.setUser(true); job.schedule(); @@ -183,7 +183,7 @@ public class PushWizard extends Wizard { final IWizardPage currentPage = getContainer().getCurrentPage(); if (currentPage == repoPage || currentPage == null) return UIText.PushWizard_windowTitleDefault; - final String destination = getDestinationString(); + final String destination = getDestinationString(repoPage.getSelection()); return NLS.bind(UIText.PushWizard_windowTitleWithDestination, destination); } @@ -262,8 +262,7 @@ public class PushWizard extends Wizard { } } - private String getDestinationString() { - final RepositorySelection repoSelection = repoPage.getSelection(); + static String getDestinationString(RepositorySelection repoSelection) { final String destination; if (repoSelection.isConfigSelected()) destination = repoSelection.getConfigName(); @@ -272,14 +271,16 @@ public class PushWizard extends Wizard { return destination; } - private class PushJob extends Job { + static class PushJob extends Job { private final PushOperation operation; private final PushOperationResult resultToCompare; private final String destinationString; - public PushJob(final PushOperation operation, + private Repository localDb; + + public PushJob(final Repository localDb, final PushOperation operation, final PushOperationResult resultToCompare, final String destinationString) { super(NLS.bind(UIText.PushWizard_jobName, getURIsString(operation @@ -287,6 +288,7 @@ public class PushWizard extends Wizard { this.operation = operation; this.resultToCompare = resultToCompare; this.destinationString = destinationString; + this.localDb = localDb; } @Override diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java index d6c7094b06..bf5ff42a07 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java @@ -8,24 +8,16 @@ *******************************************************************************/ package org.eclipse.egit.ui.internal.push; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; import java.util.List; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.egit.core.op.ListRemoteOperation; -import org.eclipse.egit.ui.Activator; -import org.eclipse.egit.ui.UIPreferences; import org.eclipse.egit.ui.UIText; import org.eclipse.egit.ui.UIUtils; import org.eclipse.egit.ui.UIUtils.IRefListProvider; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.egit.ui.internal.components.RefContentAssistProvider; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Ref; -import org.eclipse.jgit.lib.RefDatabase; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RemoteConfig; @@ -65,10 +57,6 @@ public class RefSpecDialog extends TitleAreaDialog { private boolean autoSuggestDestination; - private List<Ref> sourceRefs; - - private List<Ref> destinationRefs; - /** * Create a {@link RefSpec} * @@ -128,6 +116,19 @@ public class RefSpecDialog extends TitleAreaDialog { Composite main = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, true).applyTo(main); main.setLayout(new GridLayout(2, false)); + + URIish uriToCheck; + if (pushMode) { + if (config.getPushURIs().isEmpty()) + uriToCheck = config.getURIs().get(0); + else + uriToCheck = config.getPushURIs().get(0); + } else + uriToCheck = config.getURIs().get(0); + + final RefContentAssistProvider assistProvider = new RefContentAssistProvider( + repo, uriToCheck, getShell()); + // source Label sourceLabel = new Label(main, SWT.NONE); if (pushMode) @@ -161,7 +162,7 @@ public class RefSpecDialog extends TitleAreaDialog { UIUtils.addRefContentProposalToText(sourceText, repo, new IRefListProvider() { public List<Ref> getRefList() { - return getRefsForContentAssist(true); + return assistProvider.getRefsForContentAssist(true, pushMode); } }); @@ -201,7 +202,7 @@ public class RefSpecDialog extends TitleAreaDialog { UIUtils.addRefContentProposalToText(destinationText, repo, new IRefListProvider() { public List<Ref> getRefList() { - return getRefsForContentAssist(false); + return assistProvider.getRefsForContentAssist(false, pushMode); } }); @@ -256,15 +257,12 @@ public class RefSpecDialog extends TitleAreaDialog { String newDestinationText = spec.getDestination() != null ? spec .getDestination() : ""; //$NON-NLS-1$ String newStringText = spec.toString(); - if (!sourceText.getText().equals(newSourceText)) { + if (!sourceText.getText().equals(newSourceText)) sourceText.setText(newSourceText); - } - if (!destinationText.getText().equals(newDestinationText)) { + if (!destinationText.getText().equals(newDestinationText)) destinationText.setText(newDestinationText); - } - if (!specString.getText().equals(newStringText)) { + if (!specString.getText().equals(newStringText)) specString.setText(newStringText); - } forceButton.setSelection(spec.isForceUpdate()); if (sourceText.getText().length() == 0 || destinationText.getText().length() == 0) @@ -274,76 +272,4 @@ public class RefSpecDialog extends TitleAreaDialog { && destinationText.getText().length() > 0); } - private List<Ref> getRefsForContentAssist(boolean source) { - if (source) { - if (sourceRefs != null) - return sourceRefs; - } else if (destinationRefs != null) - return destinationRefs; - - List<Ref> result = new ArrayList<Ref>(); - try { - boolean local = pushMode == source; - if (!local) { - URIish uriToCheck; - if (pushMode) { - if (config.getPushURIs().isEmpty()) - uriToCheck = config.getURIs().get(0); - else - uriToCheck = config.getPushURIs().get(0); - } else - uriToCheck = config.getURIs().get(0); - final ListRemoteOperation lop = new ListRemoteOperation(repo, - uriToCheck, - Activator.getDefault().getPreferenceStore().getInt( - UIPreferences.REMOTE_CONNECTION_TIMEOUT)); - - new ProgressMonitorDialog(getShell()).run(false, true, - new IRunnableWithProgress() { - - public void run(IProgressMonitor monitor) - throws InvocationTargetException, - InterruptedException { - monitor - .beginTask( - UIText.RefSpecDialog_GettingRemoteRefsMonitorMessage, - IProgressMonitor.UNKNOWN); - lop.run(monitor); - monitor.done(); - } - }); - for (Ref ref : lop.getRemoteRefs()) { - if (ref.getName().startsWith(Constants.R_HEADS) - || (!pushMode && ref.getName().startsWith( - Constants.R_TAGS))) - result.add(ref); - } - - } else { - if (pushMode) - for (Ref ref : repo.getRefDatabase().getRefs( - RefDatabase.ALL).values()) { - if (ref.getName().startsWith(Constants.R_REMOTES)) { - continue; - } - result.add(ref); - } - else - for (Ref ref : repo.getRefDatabase().getRefs( - Constants.R_REMOTES).values()) { - result.add(ref); - } - } - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - Activator.handleError(e.getMessage(), e, true); - return result; - } - if (source) - sourceRefs = result; - else - destinationRefs = result; - return result; - } } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/SimplePushRefWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/SimplePushRefWizard.java new file mode 100644 index 0000000000..436adb91f4 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/SimplePushRefWizard.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (C) 2011, Markus Duft <markus.duft@salomon.at> + * + * 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.push; + +import java.net.URISyntaxException; +import java.util.Collections; +import java.util.List; + +import org.eclipse.egit.core.op.PushOperation; +import org.eclipse.egit.core.op.PushOperationSpecification; +import org.eclipse.egit.ui.Activator; +import org.eclipse.egit.ui.UIPreferences; +import org.eclipse.egit.ui.internal.components.RefContentAssistProvider; +import org.eclipse.egit.ui.internal.components.RepositorySelection; +import org.eclipse.egit.ui.internal.components.RepositorySelectionPage; +import org.eclipse.egit.ui.internal.components.SimplePushSpecPage; +import org.eclipse.egit.ui.internal.push.PushWizard.PushJob; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jgit.lib.AbbreviatedObjectId; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.transport.RemoteConfig; +import org.eclipse.jgit.transport.RemoteRefUpdate; + +/** + * A simple push wizard, which only pushes out the selected ref/commit to the + * selected repo. + */ +public class SimplePushRefWizard extends Wizard { + + /** + * The commit that will be pushed out. + */ + private ObjectId pushObj; + + private RepositorySelectionPage repoPage; + + private String nicePushName; + + private Repository repo; + + private SimplePushSpecPage targetPage; + + /** + * Creates a new simple push wizard for a ref + * + * @param repo + * the repository the ref belongs to + * @param refToPush + * the ref to push + * @throws URISyntaxException + */ + public SimplePushRefWizard(Repository repo, Ref refToPush) + throws URISyntaxException { + this(repo, refToPush.getObjectId(), refToPush.getName()); + } + + /** + * Creates a new simple push wizard which can be used to push out a certain + * object. + * + * @param repo + * the repository the object belongs to + * @param objectId + * the object that should be pushed. + * @throws URISyntaxException + */ + public SimplePushRefWizard(Repository repo, ObjectId objectId) + throws URISyntaxException { + this(repo, objectId, AbbreviatedObjectId.fromObjectId(objectId).name()); + } + + private SimplePushRefWizard(Repository repo, ObjectId objectId, String name) + throws URISyntaxException { + final List<RemoteConfig> remotes = RemoteConfig + .getAllRemoteConfigs(repo.getConfig()); + + this.nicePushName = name; + this.pushObj = objectId; + this.repo = repo; + + repoPage = new RepositorySelectionPage(false, remotes, null); + targetPage = new SimplePushSpecPage(nicePushName, repo) { + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + + if (visible) + try { + if (assist != null + && assist.getRepository().equals( + SimplePushRefWizard.this.repo) + && assist.getRemoteURI().equals( + repoPage.getSelection().getURI(true))) + return; + + assist = new RefContentAssistProvider( + SimplePushRefWizard.this.repo, repoPage + .getSelection().getURI(true), getShell()); + + } finally { + updateDestinationField(); + } + } + }; + } + + @Override + public void addPages() { + addPage(repoPage); + addPage(targetPage); + } + + @Override + public boolean performFinish() { + try { + int timeout = Activator.getDefault().getPreferenceStore() + .getInt(UIPreferences.REMOTE_CONNECTION_TIMEOUT); + + PushOperationSpecification specification = new PushOperationSpecification(); + RepositorySelection remote = repoPage.getSelection(); + + RemoteRefUpdate update = new RemoteRefUpdate(repo, null, pushObj, + targetPage.getTargetRef(), targetPage.isForceUpdate(), + null, null); + + specification.addURIRefUpdates(remote.getURI(true), + Collections.singleton(update)); + + PushOperation pop = new PushOperation(repo, specification, false, + timeout); + + PushJob job = new PushWizard.PushJob(repo, pop, null, + PushWizard.getDestinationString(remote)); + job.setUser(true); + job.schedule(); + + repoPage.saveUriInPrefs(); + } catch (Exception e) { + Activator.handleError(e.getMessage(), e, true); + } + + return true; + } + +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushCommand.java index d99487a932..9d41dfd3b0 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushCommand.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushCommand.java @@ -16,25 +16,42 @@ import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.egit.ui.Activator; import org.eclipse.egit.ui.internal.push.PushWizard; +import org.eclipse.egit.ui.internal.push.SimplePushRefWizard; import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode; +import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode; +import org.eclipse.jface.wizard.IWizard; import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.jgit.lib.Ref; /** * Implements "Push" from a Repository */ public class PushCommand extends RepositoriesViewCommandHandler<RepositoryNode> { public Object execute(ExecutionEvent event) throws ExecutionException { - RepositoryNode node = getSelectedNodes(event).get(0); + RepositoryTreeNode node = getSelectedNodes(event).get(0); + + IWizard pushWiz = null; try { - WizardDialog dlg = new WizardDialog(getShell(event), - new PushWizard(node.getRepository())); - dlg.setHelpAvailable(true); - dlg.open(); + switch (node.getType()) { + case REF: + case TAG: + pushWiz = new SimplePushRefWizard(node.getRepository(), (Ref)node.getObject()); + break; + case REPO: + pushWiz = new PushWizard(node.getRepository()); + break; + default: + throw new UnsupportedOperationException("type not supported!"); //$NON-NLS-1$ + } } catch (URISyntaxException e1) { Activator.handleError(e1.getMessage(), e1, true); } + WizardDialog dlg = new WizardDialog(getShell(event), pushWiz); + dlg.setHelpAvailable(true); + dlg.open(); + 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 64e7a57069..6e96c198e9 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 @@ -193,6 +193,7 @@ GitHistoryPage_FollowRenames=&Follow Renames GitHistoryPage_FilterSubMenuLabel=&Filter GitHistoryPage_IncompleteListTooltip=Not all commits are shown, the limit may be exceeded or the job building the list may have been aborted GitHistoryPage_ListIncompleteWarningMessage=The list is incomplete +GitHistoryPage_pushCommit=Push Commit... GitHistoryPage_ShowSubMenuLabel=&Show GitPreferenceRoot_automaticallyEnableChangesetModel=Automatically enable commit &grouping in Git synchronizations GitPreferenceRoot_BlameGroupHeader=Blame Annotations @@ -1446,6 +1447,10 @@ SimpleFetchActionHandler_NothingToFetchDialogTitle=Nothing to Fetch SimpleFetchRefSpecWizard_WizardTitle=Adding a Refspec for Fetch SimplePushActionHandler_NothingToPushDialogMessage=Can not push anything: the currently checked-out branch is based on a local branch SimplePushActionHandler_NothingToPushDialogTitle=Nothing to Push +SimplePushSpecPage_message=Select target to push {0} to +SimplePushSpecPage_pushAheadInfo={0} is {1} commits ahead of {2} +SimplePushSpecPage_TargetRefName=Target Ref Name: +SimplePushSpecPage_title=Select push destination SwitchToMenu_NewBranchMenuLabel=&New Branch... SwitchToMenu_OtherMenuLabel=&Other... GitActionContributor_ExpandAll=Expand All |
