Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 103761be6f5f1594b097b44c662dc86cbaf3fb21 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*******************************************************************************
 * Copyright (C) 2014, Andreas Hermann <a.v.hermann@gmail.com>
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
package org.eclipse.egit.ui.internal.commit.command;

import java.text.MessageFormat;
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.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.egit.core.op.StashDropOperation;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.JobFamilies;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.commit.CommitEditor;
import org.eclipse.egit.ui.internal.handler.SelectionHandler;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPart;

/**
 * Handler to delete a stashed commit
 */
public class StashDropHandler extends SelectionHandler {

	/**
	 * Command id
	 */
	public static final String ID = "org.eclipse.egit.ui.commit.StashDrop"; //$NON-NLS-1$

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		final 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();
		final int stashIndex = getStashIndex(repo, commit.getId());

		if (!confirmStashDrop(parent, stashIndex))
			return null;

		final StashDropOperation op = new StashDropOperation(repo, stashIndex);

		Job job = new WorkspaceJob(MessageFormat.format(
				UIText.StashDropCommand_jobTitle, commit.name())) {

			@Override
			public IStatus runInWorkspace(IProgressMonitor monitor) {
				try {
					op.execute(monitor);
				} catch (CoreException e) {
					Activator.logError(MessageFormat.format(
							UIText.StashDropCommand_dropFailed, "stash@{" //$NON-NLS-1$
									+ stashIndex + "}"), e); //$NON-NLS-1$
				}

				return Status.OK_STATUS;
			}

			@Override
			public boolean belongsTo(Object family) {
				if (JobFamilies.STASH.equals(family))
					return true;
				return super.belongsTo(family);
			}
		};
		final IWorkbenchPart part = getPart(event);
		job.addJobChangeListener(new JobChangeAdapter() {
			@Override
			public void done(IJobChangeEvent event) {
				if (event.getResult().isOK()) {
					if (part instanceof CommitEditor) {
						((CommitEditor) part).close(false);
					}
				}
			}

		});
		job.setUser(true);
		job.setRule(op.getSchedulingRule());
		job.schedule();
		return null;
	}

	private int getStashIndex(Repository repo, ObjectId id)
			throws ExecutionException {
		int index = 0;
		try {
			for (RevCommit commit : Git.wrap(repo).stashList().call())
				if (commit.getId().equals(id))
					return index;
				else
					index++;
			throw new IllegalStateException(MessageFormat.format(
					UIText.StashDropCommand_stashCommitNotFound, id.name()));
		} catch (Exception e) {
			String message = MessageFormat.format(
					UIText.StashDropCommand_dropFailed, id.name());
			Activator.showError(message, e);
			throw new ExecutionException(message, e);
		}
	}

	private boolean confirmStashDrop(final Shell shell, final int stashIndex) {
		final AtomicBoolean confirmed = new AtomicBoolean(false);

		shell.getDisplay().syncExec(new Runnable() {
			@Override
			public void run() {
				String message = MessageFormat.format(
						UIText.StashDropCommand_confirmSingle,
						Integer.toString(stashIndex));
				confirmed.set(MessageDialog.openConfirm(shell,
						UIText.StashDropCommand_confirmTitle, message));
			}
		});
		return confirmed.get();
	}
}

Back to the top