1 /*******************************************************************************
2 * Copyright (c) 2010, 2016 SAP AG and others
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * Stefan Lay (SAP AG) - initial implementation
10 * Thomas Wolf <thomas.wolf@paranor.ch> - Bug 495777
11 *******************************************************************************/
13 package org
.eclipse
.egit
.ui
.internal
.actions
;
15 import java
.io
.IOException
;
17 import org
.eclipse
.core
.commands
.ExecutionEvent
;
18 import org
.eclipse
.core
.commands
.ExecutionException
;
19 import org
.eclipse
.core
.resources
.WorkspaceJob
;
20 import org
.eclipse
.core
.runtime
.IStatus
;
21 import org
.eclipse
.core
.runtime
.jobs
.IJobChangeEvent
;
22 import org
.eclipse
.core
.runtime
.jobs
.JobChangeAdapter
;
23 import org
.eclipse
.egit
.core
.internal
.job
.JobUtil
;
24 import org
.eclipse
.egit
.core
.op
.MergeOperation
;
25 import org
.eclipse
.egit
.ui
.Activator
;
26 import org
.eclipse
.egit
.ui
.JobFamilies
;
27 import org
.eclipse
.egit
.ui
.internal
.UIText
;
28 import org
.eclipse
.egit
.ui
.internal
.branch
.LaunchFinder
;
29 import org
.eclipse
.egit
.ui
.internal
.dialogs
.BasicConfigurationDialog
;
30 import org
.eclipse
.egit
.ui
.internal
.dialogs
.MergeTargetSelectionDialog
;
31 import org
.eclipse
.egit
.ui
.internal
.merge
.MergeResultDialog
;
32 import org
.eclipse
.jface
.dialogs
.IDialogConstants
;
33 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
34 import org
.eclipse
.jgit
.lib
.Constants
;
35 import org
.eclipse
.jgit
.lib
.Ref
;
36 import org
.eclipse
.jgit
.lib
.Repository
;
37 import org
.eclipse
.jgit
.lib
.RepositoryState
;
38 import org
.eclipse
.osgi
.util
.NLS
;
39 import org
.eclipse
.swt
.widgets
.Shell
;
40 import org
.eclipse
.ui
.PlatformUI
;
43 * Action for selecting a commit and merging it with the current branch.
45 public class MergeActionHandler
extends RepositoryActionHandler
{
48 public Object
execute(final ExecutionEvent event
) throws ExecutionException
{
49 Repository repository
= getRepository(true, event
);
50 Shell shell
= getShell(event
);
51 if (repository
== null
52 || !checkMergeIsPossible(repository
, shell
)
53 || LaunchFinder
.shouldCancelBecauseOfRunningLaunches(repository
,
57 BasicConfigurationDialog
.show(repository
);
58 MergeTargetSelectionDialog mergeTargetSelectionDialog
= new MergeTargetSelectionDialog(
60 if (mergeTargetSelectionDialog
.open() == IDialogConstants
.OK_ID
) {
61 String refName
= mergeTargetSelectionDialog
.getRefName();
62 MergeOperation op
= new MergeOperation(repository
, refName
);
63 op
.setSquash(mergeTargetSelectionDialog
.isMergeSquash());
64 op
.setFastForwardMode(mergeTargetSelectionDialog
.getFastForwardMode());
65 op
.setCommit(mergeTargetSelectionDialog
.isCommit());
66 doMerge(repository
, op
, refName
);
72 public boolean isEnabled() {
73 Repository repo
= getRepository();
75 && repo
.getRepositoryState() == RepositoryState
.SAFE
76 && isLocalBranchCheckedout(repo
);
80 * Checks if merge is possible:
82 * <li>HEAD must point to a branch</li>
83 * <li>Repository State must be SAFE</li>
85 * Shows an error dialog if a merge is not possible.
88 * the repository used for the merge
90 * used to show a dialog in the error case
91 * @return true if a merge is possible on the current HEAD
93 public static boolean checkMergeIsPossible(Repository repository
, Shell shell
) {
94 String message
= null;
96 Ref head
= repository
.exactRef(Constants
.HEAD
);
97 if (head
== null || !head
.isSymbolic())
98 message
= UIText
.MergeAction_HeadIsNoBranch
;
99 else if (!repository
.getRepositoryState().equals(
100 RepositoryState
.SAFE
))
101 message
= NLS
.bind(UIText
.MergeAction_WrongRepositoryState
,
102 repository
.getRepositoryState());
103 } catch (IOException e
) {
104 Activator
.logError(e
.getMessage(), e
);
105 message
= e
.getMessage();
109 MessageDialog
.openError(shell
, UIText
.MergeAction_CannotMerge
, message
);
110 return (message
== null);
114 * Run a {@link MergeOperation} in a {@link WorkspaceJob} and report the
115 * result in a dialog.
118 * the merge operates on
120 * performing the merge
122 * the merge is for; used in the job's name
124 public static void doMerge(Repository repository
, MergeOperation op
,
126 JobUtil
.scheduleUserWorkspaceJob(op
,
127 NLS
.bind(UIText
.MergeAction_JobNameMerge
, refName
),
128 JobFamilies
.MERGE
, new JobChangeAdapter() {
131 public void done(IJobChangeEvent event
) {
132 IStatus result
= event
.getJob().getResult();
133 if (result
.getSeverity() == IStatus
.CANCEL
) {
134 PlatformUI
.getWorkbench().getDisplay()
136 Shell shell
= PlatformUI
.getWorkbench()
137 .getActiveWorkbenchWindow()
139 MessageDialog
.openInformation(shell
,
140 UIText
.MergeAction_MergeCanceledTitle
,
141 UIText
.MergeAction_MergeCanceledMessage
);
143 } else if (!result
.isOK()) {
144 Activator
.handleError(result
.getMessage(),
145 result
.getException(), true);
147 PlatformUI
.getWorkbench().getDisplay()
149 Shell shell
= PlatformUI
.getWorkbench()
150 .getActiveWorkbenchWindow()
152 MergeResultDialog
.getDialog(shell
,
153 repository
, op
.getResult())