Avoid refresh on up-to-date pull operation
[egit/eclipse.git] / org.eclipse.egit.core / src / org / eclipse / egit / core / op / SquashCommitsOperation.java
blob4fa1a85cbe9cb8cb5e10612ef72aa96e9bd3433c
1 /*******************************************************************************
2 * Copyright (c) 2014, 2015 Maik Schreiber and others
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
9 * SPDX-License-Identifier: EPL-2.0
11 * Contributors:
12 * Maik Schreiber - initial implementation
13 * Laurent Delaigue (Obeo) - use of preferred merge strategy
14 * Stephan Hackstedt <stephan.hackstedt@googlemail.com - Bug 477695
15 *******************************************************************************/
16 package org.eclipse.egit.core.op;
18 import java.text.MessageFormat;
19 import java.util.List;
21 import org.eclipse.core.resources.IWorkspace;
22 import org.eclipse.core.resources.IWorkspaceRunnable;
23 import org.eclipse.core.resources.ResourcesPlugin;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 import org.eclipse.core.runtime.SubMonitor;
27 import org.eclipse.core.runtime.jobs.ISchedulingRule;
28 import org.eclipse.egit.core.Activator;
29 import org.eclipse.egit.core.CommitUtil;
30 import org.eclipse.egit.core.internal.CoreText;
31 import org.eclipse.egit.core.internal.job.RuleUtil;
32 import org.eclipse.egit.core.internal.util.ProjectUtil;
33 import org.eclipse.jgit.api.Git;
34 import org.eclipse.jgit.api.RebaseCommand;
35 import org.eclipse.jgit.api.RebaseCommand.InteractiveHandler;
36 import org.eclipse.jgit.api.errors.GitAPIException;
37 import org.eclipse.jgit.errors.IllegalTodoFileModification;
38 import org.eclipse.jgit.lib.AbbreviatedObjectId;
39 import org.eclipse.jgit.lib.RebaseTodoLine;
40 import org.eclipse.jgit.lib.Repository;
41 import org.eclipse.jgit.merge.MergeStrategy;
42 import org.eclipse.jgit.revwalk.RevCommit;
43 import org.eclipse.team.core.TeamException;
45 /** Squashes multiple commits into one. */
46 public class SquashCommitsOperation implements IEGitOperation {
47 private Repository repository;
49 private List<RevCommit> commits;
51 private InteractiveHandler messageHandler;
53 /**
54 * Constructs a new squash commits operation.
56 * @param repository
57 * the repository to work on
58 * @param commits
59 * the commits
60 * @param messageHandler
61 * handler that will be used to prompt for a commit message
63 public SquashCommitsOperation(Repository repository,
64 List<RevCommit> commits, InteractiveHandler messageHandler) {
65 this.repository = repository;
66 this.commits = CommitUtil.sortCommits(commits);
67 this.messageHandler = messageHandler;
70 @Override
71 public void execute(IProgressMonitor m) throws CoreException {
73 IWorkspaceRunnable action = new IWorkspaceRunnable() {
74 @Override
75 public void run(IProgressMonitor pm) throws CoreException {
76 SubMonitor progress = SubMonitor.convert(pm, 2);
78 progress.subTask(MessageFormat.format(
79 CoreText.SquashCommitsOperation_squashing,
80 Integer.valueOf(commits.size())));
82 InteractiveHandler handler = new InteractiveHandler() {
83 @Override
84 public void prepareSteps(List<RebaseTodoLine> steps) {
85 RevCommit firstCommit = commits.get(0);
86 for (RebaseTodoLine step : steps) {
87 if (isRelevant(step.getCommit())) {
88 try {
89 if (step.getCommit().prefixCompare(
90 firstCommit) == 0)
91 step.setAction(RebaseTodoLine.Action.PICK);
92 else
93 step.setAction(RebaseTodoLine.Action.SQUASH);
94 } catch (IllegalTodoFileModification e) {
95 // shouldn't happen
101 private boolean isRelevant(AbbreviatedObjectId id) {
102 for (RevCommit commit : commits) {
103 if (id.prefixCompare(commit) == 0)
104 return true;
106 return false;
109 @Override
110 public String modifyCommitMessage(String oldMessage) {
111 return messageHandler.modifyCommitMessage(oldMessage);
114 try (Git git = new Git(repository)) {
115 RebaseCommand command = git.rebase()
116 .setUpstream(commits.get(0).getParent(0))
117 .runInteractively(handler)
118 .setOperation(RebaseCommand.Operation.BEGIN);
119 MergeStrategy strategy = Activator.getDefault()
120 .getPreferredMergeStrategy();
121 if (strategy != null) {
122 command.setStrategy(strategy);
124 command.call();
125 } catch (GitAPIException e) {
126 throw new TeamException(e.getLocalizedMessage(),
127 e.getCause());
129 progress.worked(1);
131 ProjectUtil.refreshValidProjects(
132 ProjectUtil.getValidOpenProjects(repository),
133 progress.newChild(1));
136 ResourcesPlugin.getWorkspace().run(action, getSchedulingRule(),
137 IWorkspace.AVOID_UPDATE, m);
140 @Override
141 public ISchedulingRule getSchedulingRule() {
142 return RuleUtil.getRule(repository);