1 /*******************************************************************************
2 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
3 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
4 * Copyright (C) 2008, 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 * See LICENSE for the full license text, also available.
9 *******************************************************************************/
10 package org
.spearce
.egit
.core
.op
;
13 import java
.io
.IOException
;
15 import org
.eclipse
.core
.resources
.IProject
;
16 import org
.eclipse
.core
.resources
.IResource
;
17 import org
.eclipse
.core
.resources
.IWorkspaceRunnable
;
18 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
19 import org
.eclipse
.core
.runtime
.CoreException
;
20 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
21 import org
.eclipse
.team
.core
.TeamException
;
22 import org
.spearce
.jgit
.lib
.Commit
;
23 import org
.spearce
.jgit
.lib
.Constants
;
24 import org
.spearce
.jgit
.lib
.GitIndex
;
25 import org
.spearce
.jgit
.lib
.ObjectId
;
26 import org
.spearce
.jgit
.lib
.RefLogWriter
;
27 import org
.spearce
.jgit
.lib
.RefUpdate
;
28 import org
.spearce
.jgit
.lib
.Repository
;
29 import org
.spearce
.jgit
.lib
.Tag
;
30 import org
.spearce
.jgit
.lib
.Tree
;
31 import org
.spearce
.jgit
.lib
.WorkDirCheckout
;
34 * A class for changing a ref and possibly index and workdir too.
36 public class ResetOperation
implements IWorkspaceRunnable
{
40 public enum ResetType
{
42 * Just change the ref. The index and workdir are not changed.
47 * Change the ref and the index. The workdir is not changed.
52 * Change the ref, the index and the workdir
57 private final Repository repository
;
58 private final String refName
;
59 private final ResetType type
;
61 private Commit commit
;
62 private Commit previousCommit
;
64 private GitIndex index
;
67 * Construct a {@link ResetOperation}
73 public ResetOperation(Repository repository
, String refName
, ResetType type
) {
74 this.repository
= repository
;
75 this.refName
= refName
;
79 public void run(IProgressMonitor monitor
) throws CoreException
{
80 monitor
.beginTask("Performing " + type
.toString().toLowerCase() + " reset to " + refName
, 7);
88 if (type
!= ResetType
.SOFT
) {
89 if (type
== ResetType
.MIXED
)
97 if (type
== ResetType
.HARD
) {
102 if (type
!= ResetType
.SOFT
) {
115 private void refreshIndex() throws TeamException
{
116 // File workdir = repository.getDirectory().getParentFile();
117 // for (Entry e : newIndex.getMembers()) {
119 // e.update(new File(workdir, e.getName()));
120 // } catch (IOException ignore) {}
124 } catch (IOException e1
) {
125 throw new TeamException("Writing index", e1
);
129 private void refreshProjects() {
130 final IProject
[] projects
= ResourcesPlugin
.getWorkspace().getRoot().getProjects();
131 final File parentFile
= repository
.getWorkDir();
132 for (IProject p
: projects
) {
133 final File file
= p
.getLocation().toFile();
134 if (file
.getAbsolutePath().startsWith(parentFile
.getAbsolutePath())) {
136 System
.out
.println("Refreshing " + p
);
137 p
.refreshLocal(IResource
.DEPTH_INFINITE
, null);
138 } catch (CoreException e
) {
145 private void mapObjects() throws TeamException
{
146 final ObjectId commitId
;
148 commitId
= repository
.resolve(refName
);
149 } catch (IOException e
) {
150 throw new TeamException("looking up ref " + refName
, e
);
153 commit
= repository
.mapCommit(commitId
);
154 } catch (IOException e
) {
156 Tag t
= repository
.mapTag(refName
, commitId
);
157 commit
= repository
.mapCommit(t
.getObjId());
158 } catch (IOException e2
) {
159 throw new TeamException("looking up commit " + commitId
, e2
);
164 previousCommit
= repository
.mapCommit(repository
.resolve(Constants
.HEAD
));
165 } catch (IOException e
) {
166 throw new TeamException("looking up HEAD commit", e
);
170 private void writeRef() throws TeamException
{
172 final RefUpdate ru
= repository
.updateRef(Constants
.HEAD
);
173 ru
.setNewObjectId(commit
.getCommitId());
174 ru
.setRefLogMessage("reset", false);
175 if (ru
.forceUpdate() == RefUpdate
.Result
.LOCK_FAILURE
)
176 throw new TeamException("Can't update " + ru
.getName());
177 } catch (IOException e
) {
178 throw new TeamException("Updating " + Constants
.HEAD
+ " failed", e
);
182 private void readIndex() throws TeamException
{
184 newTree
= commit
.getTree();
185 index
= repository
.getIndex();
186 } catch (IOException e
) {
187 throw new TeamException("Reading index", e
);
191 private void resetIndex() throws TeamException
{
193 newTree
= commit
.getTree();
194 index
= repository
.getIndex();
195 index
.readTree(newTree
);
196 } catch (IOException e
) {
197 throw new TeamException("Reading index", e
);
201 private void writeIndex() throws CoreException
{
204 } catch (IOException e
) {
205 throw new TeamException("Writing index", e
);
209 private void checkoutIndex() throws TeamException
{
210 final File parentFile
= repository
.getWorkDir();
212 WorkDirCheckout workDirCheckout
=
213 new WorkDirCheckout(repository
, parentFile
, index
, newTree
);
214 workDirCheckout
.setFailOnConflict(false);
215 workDirCheckout
.checkout();
216 } catch (IOException e
) {
217 throw new TeamException("mapping tree for commit", e
);
222 private void writeReflog(String reflogRelPath
) throws IOException
{
223 String name
= refName
;
224 if (name
.startsWith("refs/heads/"))
225 name
= name
.substring(11);
226 if (name
.startsWith("refs/remotes/"))
227 name
= name
.substring(13);
229 String message
= "reset --" + type
.toString().toLowerCase() + " " + name
;
231 RefLogWriter
.writeReflog(repository
, previousCommit
.getCommitId(), commit
.getCommitId(), message
, reflogRelPath
);
234 private void writeReflogs() throws TeamException
{
236 writeReflog(Constants
.HEAD
);
237 writeReflog(repository
.getFullBranch());
238 } catch (IOException e
) {
239 throw new TeamException("Writing reflogs", e
);