[duplicate code] Unify scheduling of merge jobs
[egit/eclipse.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / actions / MergeActionHandler.java
blob8500e084e2613fbbc9a7cf7727107a074427cde0
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
8 * Contributors:
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;
42 /**
43 * Action for selecting a commit and merging it with the current branch.
45 public class MergeActionHandler extends RepositoryActionHandler {
47 @Override
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,
54 null)) {
55 return null;
57 BasicConfigurationDialog.show(repository);
58 MergeTargetSelectionDialog mergeTargetSelectionDialog = new MergeTargetSelectionDialog(
59 shell, repository);
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);
68 return null;
71 @Override
72 public boolean isEnabled() {
73 Repository repo = getRepository();
74 return repo != null
75 && repo.getRepositoryState() == RepositoryState.SAFE
76 && isLocalBranchCheckedout(repo);
79 /**
80 * Checks if merge is possible:
81 * <ul>
82 * <li>HEAD must point to a branch</li>
83 * <li>Repository State must be SAFE</li>
84 * </ul>
85 * Shows an error dialog if a merge is not possible.
87 * @param repository
88 * the repository used for the merge
89 * @param shell
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;
95 try {
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();
108 if (message != null)
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.
117 * @param repository
118 * the merge operates on
119 * @param op
120 * performing the merge
121 * @param refName
122 * the merge is for; used in the job's name
124 public static void doMerge(Repository repository, MergeOperation op,
125 String refName) {
126 JobUtil.scheduleUserWorkspaceJob(op,
127 NLS.bind(UIText.MergeAction_JobNameMerge, refName),
128 JobFamilies.MERGE, new JobChangeAdapter() {
130 @Override
131 public void done(IJobChangeEvent event) {
132 IStatus result = event.getJob().getResult();
133 if (result.getSeverity() == IStatus.CANCEL) {
134 PlatformUI.getWorkbench().getDisplay()
135 .asyncExec(() -> {
136 Shell shell = PlatformUI.getWorkbench()
137 .getActiveWorkbenchWindow()
138 .getShell();
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);
146 } else {
147 PlatformUI.getWorkbench().getDisplay()
148 .asyncExec(() -> {
149 Shell shell = PlatformUI.getWorkbench()
150 .getActiveWorkbenchWindow()
151 .getShell();
152 MergeResultDialog.getDialog(shell,
153 repository, op.getResult())
154 .open();