diff options
author | Maik Schreiber | 2014-06-19 13:20:52 +0000 |
---|---|---|
committer | Matthias Sohn | 2014-06-25 22:43:49 +0000 |
commit | e7a0ec115347e2d147b8794d78cc5a8883f1cc3e (patch) | |
tree | b9a394b3e4eaaf957420a4066f5258c8c820d382 /org.eclipse.egit.ui | |
parent | df52b57528097f988607e965a2cd93e6565e3da1 (diff) | |
download | egit-e7a0ec115347e2d147b8794d78cc5a8883f1cc3e.tar.gz egit-e7a0ec115347e2d147b8794d78cc5a8883f1cc3e.tar.xz egit-e7a0ec115347e2d147b8794d78cc5a8883f1cc3e.zip |
Add support for cherry-picking multiple commits at once.
This modifies the Cherry Pick menu item in the History view such that
multiple selected commits may be cherry-picked at once, instead of
one-by-one.
Cherry-picking now uses the mechanics of interactive rebase. If a
conflict occurs during merging one of the commits, it needs to be
resolved manually, and then the interactive rebase may be resumed
(just like with a regular interactive rebase.)
Cherry-picking a single commit uses the same mechanics just mentioned.
Change-Id: I23d1339072c9557af530c9e3f8d6636cf24fbac1
Signed-off-by: Maik Schreiber <blizzy@blizzy.de>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Diffstat (limited to 'org.eclipse.egit.ui')
5 files changed, 43 insertions, 140 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java index e31def9058..eb5f9a147f 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java @@ -1115,30 +1115,6 @@ public class UIText extends NLS { public static String CheckoutHandler_SelectBranchTitle; /** */ - public static String CherryPickHandler_NoCherryPickPerformedMessage; - - /** */ - public static String CherryPickHandler_NoCherryPickPerformedTitle; - - /** */ - public static String CherryPickHandler_CherryPickConflictsMessage; - - /** */ - public static String CherryPickHandler_CherryPickConflictsTitle; - - /** */ - public static String CherryPickHandler_CherryPickFailedMessage; - - /** */ - public static String CherryPickHandler_CouldNotDeleteFile; - - /** */ - public static String CherryPickHandler_ErrorMsgTemplate; - - /** */ - public static String CherryPickHandler_IndexDirty; - - /** */ public static String CherryPickHandler_JobName; /** */ @@ -1148,12 +1124,6 @@ public class UIText extends NLS { public static String CherryPickHandler_ConfirmTitle; /** */ - public static String CherryPickHandler_unknown; - - /** */ - public static String CherryPickHandler_WorktreeDirty; - - /** */ public static String CherryPickOperation_InternalError; /** */ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CherryPickHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CherryPickHandler.java index ae2211af34..917597390e 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CherryPickHandler.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CherryPickHandler.java @@ -1,6 +1,7 @@ /****************************************************************************** * Copyright (c) 2010 SAP AG. - * Copyright (c) 2011 GitHub Inc. + * Copyright (c) 2011, 2014 GitHub Inc. + * and other copyright owners as documented in the project's IP log. * 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 @@ -8,38 +9,33 @@ * * Contributors: * Kevin Sawicki (GitHub Inc.) - initial API and implementation + * Maik Schreiber - modify to using interactive rebase mechanics *****************************************************************************/ package org.eclipse.egit.ui.internal.commit.command; import java.io.IOException; import java.text.MessageFormat; -import java.util.Map; -import java.util.Map.Entry; +import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.egit.core.op.CherryPickOperation; import org.eclipse.egit.ui.Activator; import org.eclipse.egit.ui.JobFamilies; +import org.eclipse.egit.ui.internal.UIRepositoryUtils; import org.eclipse.egit.ui.internal.UIText; import org.eclipse.egit.ui.internal.handler.SelectionHandler; import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jgit.api.CherryPickResult; -import org.eclipse.jgit.api.CherryPickResult.CherryPickStatus; +import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason; import org.eclipse.jgit.revwalk.RevCommit; -import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PlatformUI; /** * Handler to cherry pick the commit onto the current branch @@ -52,44 +48,33 @@ public class CherryPickHandler extends SelectionHandler { public static final String ID = "org.eclipse.egit.ui.commit.CherryPick"; //$NON-NLS-1$ public Object execute(ExecutionEvent event) throws ExecutionException { - RevCommit commit = getSelectedItem(RevCommit.class, event); - if (commit == null) + List<RevCommit> commits = getSelectedItems(RevCommit.class, event); + if ((commits == null) || commits.isEmpty()) return null; Repository repo = getSelectedItem(Repository.class, event); if (repo == null) return null; final Shell parent = getPart(event).getSite().getShell(); - if (!confirmCherryPick(parent, repo, commit)) + if (!confirmCherryPick(parent, repo, commits)) return null; - final CherryPickOperation op = new CherryPickOperation(repo, commit); - - Job job = new WorkspaceJob(MessageFormat.format( - UIText.CherryPickHandler_JobName, commit.name())) { + try { + if (!UIRepositoryUtils.handleUncommittedFiles(repo, parent)) + return null; + } catch (GitAPIException e) { + Activator.logError(e.getMessage(), e); + return null; + } + final CherryPickOperation op = new CherryPickOperation(repo, commits); + Job job = new Job(MessageFormat.format( + UIText.CherryPickHandler_JobName, + Integer.valueOf(commits.size()))) { @Override - public IStatus runInWorkspace(IProgressMonitor monitor) { + protected IStatus run(IProgressMonitor monitor) { try { op.execute(monitor); - CherryPickResult cherryPickResult = op.getResult(); - RevCommit newHead = cherryPickResult.getNewHead(); - if (newHead != null - && cherryPickResult.getCherryPickedRefs().isEmpty()) - showNotPerformedDialog(parent); - if (newHead == null) { - CherryPickStatus status = cherryPickResult.getStatus(); - switch (status) { - case CONFLICTING: - showConflictDialog(parent); - break; - case FAILED: - showFailure(cherryPickResult); - break; - case OK: - break; - } - } } catch (CoreException e) { Activator.logError( UIText.CherryPickOperation_InternalError, e); @@ -111,14 +96,14 @@ public class CherryPickHandler extends SelectionHandler { } private boolean confirmCherryPick(final Shell shell, - final Repository repository, final RevCommit commit) + final Repository repository, final List<RevCommit> commits) throws ExecutionException { final AtomicBoolean confirmed = new AtomicBoolean(false); final String message; try { message = MessageFormat.format( UIText.CherryPickHandler_ConfirmMessage, - commit.abbreviate(7).name(), repository.getBranch()); + Integer.valueOf(commits.size()), repository.getBranch()); } catch (IOException e) { throw new ExecutionException( "Exception obtaining current repository branch", e); //$NON-NLS-1$ @@ -133,58 +118,4 @@ public class CherryPickHandler extends SelectionHandler { }); return confirmed.get(); } - - private void showNotPerformedDialog(final Shell shell) { - PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { - - public void run() { - MessageDialog.openWarning(shell, - UIText.CherryPickHandler_NoCherryPickPerformedTitle, - UIText.CherryPickHandler_NoCherryPickPerformedMessage); - } - }); - } - - private void showConflictDialog(final Shell shell) { - PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { - - public void run() { - MessageDialog.openWarning(shell, - UIText.CherryPickHandler_CherryPickConflictsTitle, - UIText.CherryPickHandler_CherryPickConflictsMessage); - } - }); - } - - private void showFailure(CherryPickResult result) { - IStatus details = getErrorList(result.getFailingPaths()); - Activator.showErrorStatus( - UIText.CherryPickHandler_CherryPickFailedMessage, details); - } - - private IStatus getErrorList(Map<String, MergeFailureReason> failingPaths) { - MultiStatus result = new MultiStatus(Activator.getPluginId(), - IStatus.ERROR, - UIText.CherryPickHandler_CherryPickFailedMessage, null); - for (Entry<String, MergeFailureReason> entry : failingPaths.entrySet()) { - String path = entry.getKey(); - String reason = getReason(entry.getValue()); - String errorMessage = NLS.bind( - UIText.CherryPickHandler_ErrorMsgTemplate, path, reason); - result.add(Activator.createErrorStatus(errorMessage)); - } - return result; - } - - private String getReason(MergeFailureReason mergeFailureReason) { - switch (mergeFailureReason) { - case COULD_NOT_DELETE: - return UIText.CherryPickHandler_CouldNotDeleteFile; - case DIRTY_INDEX: - return UIText.CherryPickHandler_IndexDirty; - case DIRTY_WORKTREE: - return UIText.CherryPickHandler_WorktreeDirty; - } - return UIText.CherryPickHandler_unknown; - } } 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 c80e73c3a6..ed87b691bf 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 @@ -830,9 +830,6 @@ class CommitGraphTable { HistoryViewCommands.CREATE_PATCH, UIText.GitHistoryPage_CreatePatchMenuLabel)); popupMgr.add(getCommandContributionItem( - HistoryViewCommands.CHERRYPICK, - UIText.GitHistoryPage_cherryPickMenuItem)); - popupMgr.add(getCommandContributionItem( HistoryViewCommands.REVERT, UIText.GitHistoryPage_revertMenuItem)); popupMgr.add(getCommandContributionItem( @@ -860,6 +857,12 @@ class CommitGraphTable { } popupMgr.add(new Separator()); + popupMgr.add(getCommandContributionItem( + HistoryViewCommands.CHERRYPICK, + UIText.GitHistoryPage_cherryPickMenuItem)); + + popupMgr.add(new Separator()); + MenuManager quickDiffManager = new MenuManager( UIText.GitHistoryPage_QuickdiffMenuLabel, null, "Quickdiff"); //$NON-NLS-1$ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CherryPickHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CherryPickHandler.java index 30c3f4a3a2..5be3f3ac92 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CherryPickHandler.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CherryPickHandler.java @@ -1,5 +1,6 @@ /******************************************************************************* - * Copyright (c) 2010 SAP AG. + * Copyright (c) 2010, 2014 SAP AG + * and other copyright owners as documented in the project's IP log. * 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 @@ -12,6 +13,9 @@ package org.eclipse.egit.ui.internal.history.command; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.egit.ui.internal.CommonUtils; @@ -36,17 +40,22 @@ public class CherryPickHandler extends AbstractHistoryCommandHandler { } public Object execute(ExecutionEvent event) throws ExecutionException { - RevCommit commit = getSelectedCommit(event); + List<RevCommit> commits = getSelectedCommits(event); Repository repo = getRepository(event); if (repo == null) return null; + List<RepositoryCommit> repositoryCommits = new ArrayList<RepositoryCommit>(); + for (RevCommit commit : commits) + repositoryCommits.add(new RepositoryCommit(repo, commit)); + final IStructuredSelection selected = new StructuredSelection( - new RepositoryCommit(repo, commit)); + repositoryCommits); CommonUtils .runCommand( org.eclipse.egit.ui.internal.commit.command.CherryPickHandler.ID, selected); + return null; } } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties index 7221a34ee9..b569e928a0 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties @@ -267,19 +267,9 @@ CheckoutDialog_OkCheckout=&Checkout CheckoutDialog_OkCheckoutWithQuestion=&Checkout... CheckoutHandler_SelectBranchMessage=There is more than one branch for this commit. Please select the branch you want to check out. CheckoutHandler_SelectBranchTitle=Select a Branch for Checkout -CherryPickHandler_NoCherryPickPerformedMessage=The change has already been included -CherryPickHandler_NoCherryPickPerformedTitle=No cherry pick performed -CherryPickHandler_CherryPickConflictsMessage=Cherry pick could not be completed automatically because of conflicts. Please resolve and commit. -CherryPickHandler_CherryPickConflictsTitle=Cherry Pick Conflicts -CherryPickHandler_CherryPickFailedMessage=Cherry pick failed -CherryPickHandler_CouldNotDeleteFile=Could not delete file -CherryPickHandler_ErrorMsgTemplate={0} {1} -CherryPickHandler_IndexDirty=Index is dirty -CherryPickHandler_JobName=Cherry Picking Commit {0} -CherryPickHandler_ConfirmMessage=Are you sure you want to cherry pick commit ''{0}'' onto branch ''{1}''? +CherryPickHandler_JobName=Cherry Picking {0} Commits +CherryPickHandler_ConfirmMessage=Are you sure you want to cherry pick {0} commits onto branch ''{1}''? CherryPickHandler_ConfirmTitle=Cherry Pick Commit -CherryPickHandler_unknown=unknown -CherryPickHandler_WorktreeDirty=File is modified CherryPickOperation_InternalError=An internal error occurred CompareTargetSelectionDialog_CompareButton=&Compare CompareTargetSelectionDialog_CompareMessage=Select a branch, tag, or reference to compare the resource with |