diff options
author | Matthias Sohn | 2014-12-03 14:22:33 +0000 |
---|---|---|
committer | Stefan Lay | 2014-12-04 08:52:48 +0000 |
commit | f7fb42e48e4fcd3f218cd5670203b8bd5295fb7d (patch) | |
tree | 9cfbd483407ec7276ec5315b7056c8e957af82c2 | |
parent | 56e136e36316342347cbc035d2f765bd9624367a (diff) | |
download | egit-f7fb42e48e4fcd3f218cd5670203b8bd5295fb7d.tar.gz egit-f7fb42e48e4fcd3f218cd5670203b8bd5295fb7d.tar.xz egit-f7fb42e48e4fcd3f218cd5670203b8bd5295fb7d.zip |
Revert "Add support for cherry-picking multiple commits at once"
This reverts commit e7a0ec115347e2d147b8794d78cc5a8883f1cc3e.
Bug: 447115
Change-Id: Ife9a30e68660d879e8d394d2c3ecb87d568fe34d
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 files changed, 159 insertions, 87 deletions
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties index 43c1239a97..418d079c3f 100644 --- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties +++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties @@ -10,7 +10,7 @@ # Daniel Megert <daniel_megert@ch.ibm.com> - Escaped single quotes where needed ############################################################################### -CherryPickOperation_cherryPicking=Running cherry-pick on {0} commits +CherryPickOperation_cherryPicking=Running cherry-pick on commit {0} CommitFileRevision_pathNotIn=Path {1} not in commit {0}. CommitFileRevision_errorLookingUpPath=IO error looking up path {1} in {0}. ConfigureFetchAfterCloneTask_couldNotFetch=Could not fetch with refSpec {0} diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CherryPickOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CherryPickOperation.java index aa5d363f62..8f9592a51a 100644 --- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CherryPickOperation.java +++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CherryPickOperation.java @@ -1,6 +1,5 @@ /****************************************************************************** - * Copyright (c) 2011, 2014 GitHub Inc - * and other copyright owners as documented in the project's IP log. + * Copyright (c) 2011 GitHub Inc. * 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,15 +7,10 @@ * * Contributors: * Kevin Sawicki (GitHub Inc.) - initial API and implementation - * Maik Schreiber - modify to using interactive rebase mechanics *****************************************************************************/ package org.eclipse.egit.core.op; -import java.io.IOException; import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; @@ -29,92 +23,60 @@ import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.egit.core.internal.CoreText; import org.eclipse.egit.core.internal.job.RuleUtil; import org.eclipse.egit.core.internal.util.ProjectUtil; +import org.eclipse.jgit.api.CherryPickCommand; +import org.eclipse.jgit.api.CherryPickResult; import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.RebaseCommand; -import org.eclipse.jgit.api.RebaseCommand.InteractiveHandler; import org.eclipse.jgit.api.errors.GitAPIException; -import org.eclipse.jgit.errors.IllegalTodoFileModification; -import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.lib.RebaseTodoLine; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; -import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.team.core.TeamException; /** * Cherry pick operation */ public class CherryPickOperation implements IEGitOperation { + private final Repository repo; - private List<RevCommit> commits; + private final RevCommit commit; + + private CherryPickResult result; /** * Create cherry pick operation * * @param repository - * the repository to work on - * @param commits - * the commits in newest-first order + * @param commit */ - public CherryPickOperation(Repository repository, List<RevCommit> commits) { + public CherryPickOperation(Repository repository, RevCommit commit) { this.repo = repository; - this.commits = commits; + this.commit = commit; + } + + /** + * @return cherry pick result + */ + public CherryPickResult getResult() { + return result; } public void execute(IProgressMonitor m) throws CoreException { IProgressMonitor monitor = m != null ? m : new NullProgressMonitor(); - IWorkspaceRunnable action = new IWorkspaceRunnable() { + public void run(IProgressMonitor pm) throws CoreException { pm.beginTask("", 2); //$NON-NLS-1$ pm.subTask(MessageFormat.format( CoreText.CherryPickOperation_cherryPicking, - Integer.valueOf(commits.size()))); - - InteractiveHandler handler = new InteractiveHandler() { - public void prepareSteps(List<RebaseTodoLine> steps) { - for (RebaseTodoLine step : steps) { - try { - step.setAction(RebaseTodoLine.Action.PICK); - } catch (IllegalTodoFileModification e) { - // shouldn't happen - } - } - - // apply steps in the chronological order - List<RevCommit> stepCommits = new ArrayList<RevCommit>( - commits); - Collections.reverse(stepCommits); - - for (RevCommit commit : stepCommits) { - RebaseTodoLine step = new RebaseTodoLine( - RebaseTodoLine.Action.PICK, - commit.abbreviate(7), ""); //$NON-NLS-1$ - steps.add(step); - } - } - - public String modifyCommitMessage(String oldMessage) { - return oldMessage; - } - }; + commit.name())); + CherryPickCommand command = new Git(repo).cherryPick().include( + commit.getId()); try { - Git git = new Git(repo); - ObjectId headCommitId = repo.resolve(Constants.HEAD); - RevCommit headCommit = new RevWalk(repo) - .parseCommit(headCommitId); - git.rebase().setUpstream(headCommit.getParent(0)) - .runInteractively(handler) - .setOperation(RebaseCommand.Operation.BEGIN).call(); + result = command.call(); } catch (GitAPIException e) { throw new TeamException(e.getLocalizedMessage(), e.getCause()); - } catch (IOException e) { - throw new TeamException(e.getLocalizedMessage(), - e.getCause()); } pm.worked(1); 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 6530634478..5acfb8703b 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 @@ -1138,6 +1138,30 @@ 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; /** */ @@ -1147,6 +1171,12 @@ 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 5366b55408..af1755362c 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 @@ -9,14 +9,16 @@ * * 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.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.core.commands.ExecutionEvent; @@ -24,6 +26,7 @@ import org.eclipse.core.commands.ExecutionException; 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; @@ -39,14 +42,19 @@ import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.window.Window; +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.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; @@ -61,15 +69,15 @@ 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 { - List<RevCommit> commits = getSelectedItems(RevCommit.class, event); - if ((commits == null) || commits.isEmpty()) + RevCommit commit = getSelectedItem(RevCommit.class, event); + if (commit == null) return null; Repository repo = getSelectedItem(Repository.class, event); if (repo == null) return null; final Shell parent = getPart(event).getSite().getShell(); - if (!confirmCherryPick(parent, repo, commits)) + if (!confirmCherryPick(parent, repo, commit)) return null; try { @@ -80,14 +88,31 @@ public class CherryPickHandler extends SelectionHandler { return null; } - final CherryPickOperation op = new CherryPickOperation(repo, commits); + final CherryPickOperation op = new CherryPickOperation(repo, commit); Job job = new Job(MessageFormat.format( - UIText.CherryPickHandler_JobName, - Integer.valueOf(commits.size()))) { + UIText.CherryPickHandler_JobName, 1)) { @Override 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); @@ -109,14 +134,14 @@ public class CherryPickHandler extends SelectionHandler { } private boolean confirmCherryPick(final Shell shell, - final Repository repository, final List<RevCommit> commits) + final Repository repository, final RevCommit commit) throws ExecutionException { final AtomicBoolean confirmed = new AtomicBoolean(false); final String message; try { message = MessageFormat.format( - UIText.CherryPickHandler_ConfirmMessage, - Integer.valueOf(commits.size()), repository.getBranch()); + UIText.CherryPickHandler_ConfirmMessage, 1, + repository.getBranch()); } catch (IOException e) { throw new ExecutionException( "Exception obtaining current repository branch", e); //$NON-NLS-1$ @@ -126,7 +151,7 @@ public class CherryPickHandler extends SelectionHandler { public void run() { ConfirmCherryPickDialog dialog = new ConfirmCherryPickDialog( - shell, message, repository, commits); + shell, message, repository, Arrays.asList(commit)); int result = dialog.open(); confirmed.set(result == Window.OK); } @@ -181,4 +206,58 @@ public class CherryPickHandler extends SelectionHandler { } } } + + 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 f7bc1b3418..d55e58c9bc 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 @@ -753,6 +753,9 @@ class CommitGraphTable { HistoryViewCommands.CREATE_PATCH, UIText.GitHistoryPage_CreatePatchMenuLabel)); popupMgr.add(getCommandContributionItem( + HistoryViewCommands.CHERRYPICK, + UIText.GitHistoryPage_cherryPickMenuItem)); + popupMgr.add(getCommandContributionItem( HistoryViewCommands.MERGE, UIText.GitHistoryPage_mergeMenuItem)); popupMgr.add(getCommandContributionItem( @@ -778,9 +781,6 @@ class CommitGraphTable { popupMgr.add(new Separator()); - popupMgr.add(getCommandContributionItem( - HistoryViewCommands.CHERRYPICK, - UIText.GitHistoryPage_cherryPickMenuItem)); popupMgr.add(getCommandContributionItem(HistoryViewCommands.REVERT, UIText.GitHistoryPage_revertMenuItem)); 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 5be3f3ac92..30c3f4a3a2 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,6 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2014 SAP AG - * and other copyright owners as documented in the project's IP log. + * 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 @@ -13,9 +12,6 @@ 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; @@ -40,22 +36,17 @@ public class CherryPickHandler extends AbstractHistoryCommandHandler { } public Object execute(ExecutionEvent event) throws ExecutionException { - List<RevCommit> commits = getSelectedCommits(event); + RevCommit commit = getSelectedCommit(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( - repositoryCommits); + new RepositoryCommit(repo, commit)); 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 5649b866fd..09f849baaa 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 @@ -273,7 +273,17 @@ CheckoutHandler_SelectBranchMessage=There is more than one branch for this commi CheckoutHandler_SelectBranchTitle=Select a Branch for Checkout CherryPickHandler_JobName=Cherry Picking {0} Commits CherryPickHandler_ConfirmMessage=Are you sure you want to cherry pick the following {0,choice,1#commit|1<{0} commits} onto branch ''{1}''? +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_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 |