Action Reactoring (AbstractOperationAction)
[egit.git] / org.eclipse.egit.core / src / org / eclipse / egit / core / op / BranchOperation.java
blobca38e543997a2b971630241f76cd858a0fc93f0f
1 /*******************************************************************************
2 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
3 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
4 * Copyright (C) 2006, Shawn O. Pearce <spearce@spearce.org>
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *******************************************************************************/
11 package org.eclipse.egit.core.op;
13 import java.io.IOException;
15 import org.eclipse.core.resources.IWorkspaceRunnable;
16 import org.eclipse.core.resources.ResourcesPlugin;
17 import org.eclipse.core.runtime.CoreException;
18 import org.eclipse.core.runtime.IProgressMonitor;
19 import org.eclipse.core.runtime.SubProgressMonitor;
20 import org.eclipse.core.runtime.jobs.ISchedulingRule;
21 import org.eclipse.egit.core.CoreText;
22 import org.eclipse.egit.core.internal.util.ProjectUtil;
23 import org.eclipse.jgit.errors.CheckoutConflictException;
24 import org.eclipse.jgit.lib.Commit;
25 import org.eclipse.jgit.lib.Constants;
26 import org.eclipse.jgit.lib.GitIndex;
27 import org.eclipse.jgit.lib.RefUpdate;
28 import org.eclipse.jgit.lib.Repository;
29 import org.eclipse.jgit.lib.Tree;
30 import org.eclipse.jgit.lib.WorkDirCheckout;
31 import org.eclipse.osgi.util.NLS;
32 import org.eclipse.team.core.TeamException;
34 /**
35 * This class implements checkouts of a specific revision. A check
36 * is made that this can be done without data loss.
38 public class BranchOperation implements IEGitOperation {
40 private final Repository repository;
42 private final String refName;
44 /**
45 * Construct a {@link BranchOperation} object.
46 * @param repository
47 * @param refName Name of git ref to checkout
49 public BranchOperation(Repository repository, String refName) {
50 this.repository = repository;
51 this.refName = refName;
54 private Tree oldTree;
56 private GitIndex index;
58 private Tree newTree;
60 private Commit oldCommit;
62 private Commit newCommit;
66 /* (non-Javadoc)
67 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
69 public void execute(IProgressMonitor monitor) throws CoreException {
71 if (!refName.startsWith(Constants.R_REFS))
72 throw new TeamException(NLS.bind(
73 CoreText.BranchOperation_CheckoutOnlyBranchOrTag, refName));
75 IWorkspaceRunnable action = new IWorkspaceRunnable() {
77 public void run(IProgressMonitor monitor) throws CoreException {
78 monitor.beginTask(NLS.bind(
79 CoreText.BranchOperation_performingBranch, refName), 6);
80 lookupRefs();
81 monitor.worked(1);
83 mapObjects();
84 monitor.worked(1);
86 checkoutTree();
87 monitor.worked(1);
89 writeIndex();
90 monitor.worked(1);
92 updateHeadRef();
93 monitor.worked(1);
95 ProjectUtil.refreshProjects(repository, new SubProgressMonitor(
96 monitor, 1));
97 monitor.worked(1);
99 monitor.done();
102 // lock workspace to protect working tree changes
103 ResourcesPlugin.getWorkspace().run(action, monitor);
106 /* (non-Javadoc)
107 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
109 public ISchedulingRule getSchedulingRule() {
110 return ResourcesPlugin.getWorkspace().getRoot();
113 private void updateHeadRef() throws TeamException {
114 try {
115 RefUpdate u = repository.updateRef(Constants.HEAD);
116 u.setRefLogMessage(NLS.bind(
117 CoreText.BranchOperation_checkoutMovingTo, refName), false);
118 switch (u.link(refName)) {
119 case NEW:
120 case FORCED:
121 case NO_CHANGE:
122 break;
123 default:
124 throw new IOException(u.getResult().name());
126 } catch (IOException e) {
127 throw new TeamException(NLS.bind(
128 CoreText.BranchOperation_updatingHeadToRef, refName), e);
132 private void writeIndex() throws TeamException {
133 try {
134 index.write();
135 } catch (IOException e) {
136 throw new TeamException(CoreText.BranchOperation_writingIndex, e);
140 private void checkoutTree() throws TeamException {
141 try {
142 new WorkDirCheckout(repository, repository.getWorkDir(), oldTree,
143 index, newTree).checkout();
144 } catch (CheckoutConflictException e) {
145 TeamException teamException = new TeamException(e.getMessage());
146 throw teamException;
147 } catch (IOException e) {
148 throw new TeamException(CoreText.BranchOperation_checkoutProblem, e);
152 private void mapObjects() throws TeamException {
153 try {
154 oldTree = oldCommit.getTree();
155 index = repository.getIndex();
156 newTree = newCommit.getTree();
157 } catch (IOException e) {
158 throw new TeamException(CoreText.BranchOperation_mappingTrees, e);
162 private void lookupRefs() throws TeamException {
163 try {
164 newCommit = repository.mapCommit(refName);
165 } catch (IOException e) {
166 throw new TeamException(NLS.bind(
167 CoreText.BranchOperation_mappingCommit, refName), e);
170 try {
171 oldCommit = repository.mapCommit(Constants.HEAD);
172 } catch (IOException e) {
173 throw new TeamException(CoreText.BranchOperation_mappingCommitHead,