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 * 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
;
14 import java
.io
.IOException
;
16 import org
.eclipse
.core
.resources
.IProject
;
17 import org
.eclipse
.core
.resources
.IResource
;
18 import org
.eclipse
.core
.resources
.IWorkspaceRunnable
;
19 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
20 import org
.eclipse
.core
.runtime
.CoreException
;
21 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
22 import org
.eclipse
.team
.core
.TeamException
;
23 import org
.spearce
.jgit
.lib
.Commit
;
24 import org
.spearce
.jgit
.lib
.Constants
;
25 import org
.spearce
.jgit
.lib
.GitIndex
;
26 import org
.spearce
.jgit
.lib
.ObjectId
;
27 import org
.spearce
.jgit
.lib
.RefLogWriter
;
28 import org
.spearce
.jgit
.lib
.RefUpdate
;
29 import org
.spearce
.jgit
.lib
.Repository
;
30 import org
.spearce
.jgit
.lib
.Tag
;
31 import org
.spearce
.jgit
.lib
.Tree
;
32 import org
.spearce
.jgit
.lib
.WorkDirCheckout
;
35 * A class for changing a ref and possibly index and workdir too.
37 public class ResetOperation
implements IWorkspaceRunnable
{
41 public enum ResetType
{
43 * Just change the ref. The index and workdir are not changed.
48 * Change the ref and the index. The workdir is not changed.
53 * Change the ref, the index and the workdir
58 private final Repository repository
;
59 private final String refName
;
60 private final ResetType type
;
62 private Commit commit
;
63 private Commit previousCommit
;
65 private GitIndex index
;
68 * Construct a {@link ResetOperation}
74 public ResetOperation(Repository repository
, String refName
, ResetType type
) {
75 this.repository
= repository
;
76 this.refName
= refName
;
80 public void run(IProgressMonitor monitor
) throws CoreException
{
81 monitor
.beginTask("Performing " + type
.toString().toLowerCase() + " reset to " + refName
, 7);
89 if (type
!= ResetType
.SOFT
) {
90 if (type
== ResetType
.MIXED
)
98 if (type
== ResetType
.HARD
) {
103 if (type
!= ResetType
.SOFT
) {
116 private void refreshIndex() throws TeamException
{
117 // File workdir = repository.getDirectory().getParentFile();
118 // for (Entry e : newIndex.getMembers()) {
120 // e.update(new File(workdir, e.getName()));
121 // } catch (IOException ignore) {}
125 } catch (IOException e1
) {
126 throw new TeamException("Writing index", e1
);
130 private void refreshProjects() {
131 final IProject
[] projects
= ResourcesPlugin
.getWorkspace().getRoot().getProjects();
132 final File parentFile
= repository
.getWorkDir();
133 for (IProject p
: projects
) {
134 final File file
= p
.getLocation().toFile();
135 if (file
.getAbsolutePath().startsWith(parentFile
.getAbsolutePath())) {
137 System
.out
.println("Refreshing " + p
);
138 p
.refreshLocal(IResource
.DEPTH_INFINITE
, null);
139 } catch (CoreException e
) {
146 private void mapObjects() throws TeamException
{
147 final ObjectId commitId
;
149 commitId
= repository
.resolve(refName
);
150 } catch (IOException e
) {
151 throw new TeamException("looking up ref " + refName
, e
);
154 commit
= repository
.mapCommit(commitId
);
155 } catch (IOException e
) {
157 Tag t
= repository
.mapTag(refName
, commitId
);
158 commit
= repository
.mapCommit(t
.getObjId());
159 } catch (IOException e2
) {
160 throw new TeamException("looking up commit " + commitId
, e2
);
165 previousCommit
= repository
.mapCommit(repository
.resolve(Constants
.HEAD
));
166 } catch (IOException e
) {
167 throw new TeamException("looking up HEAD commit", e
);
171 private void writeRef() throws TeamException
{
173 final RefUpdate ru
= repository
.updateRef(Constants
.HEAD
);
174 ru
.setNewObjectId(commit
.getCommitId());
175 ru
.setRefLogMessage("reset", false);
176 if (ru
.forceUpdate() == RefUpdate
.Result
.LOCK_FAILURE
)
177 throw new TeamException("Can't update " + ru
.getName());
178 } catch (IOException e
) {
179 throw new TeamException("Updating " + Constants
.HEAD
+ " failed", e
);
183 private void readIndex() throws TeamException
{
185 newTree
= commit
.getTree();
186 index
= repository
.getIndex();
187 } catch (IOException e
) {
188 throw new TeamException("Reading index", e
);
192 private void resetIndex() throws TeamException
{
194 newTree
= commit
.getTree();
195 index
= repository
.getIndex();
196 index
.readTree(newTree
);
197 } catch (IOException e
) {
198 throw new TeamException("Reading index", e
);
202 private void writeIndex() throws CoreException
{
205 } catch (IOException e
) {
206 throw new TeamException("Writing index", e
);
210 private void checkoutIndex() throws TeamException
{
211 final File parentFile
= repository
.getWorkDir();
213 WorkDirCheckout workDirCheckout
=
214 new WorkDirCheckout(repository
, parentFile
, index
, newTree
);
215 workDirCheckout
.setFailOnConflict(false);
216 workDirCheckout
.checkout();
217 } catch (IOException e
) {
218 throw new TeamException("mapping tree for commit", e
);
223 private void writeReflog(String reflogRelPath
) throws IOException
{
224 String name
= refName
;
225 if (name
.startsWith("refs/heads/"))
226 name
= name
.substring(11);
227 if (name
.startsWith("refs/remotes/"))
228 name
= name
.substring(13);
230 String message
= "reset --" + type
.toString().toLowerCase() + " " + name
;
232 RefLogWriter
.writeReflog(repository
, previousCommit
.getCommitId(), commit
.getCommitId(), message
, reflogRelPath
);
235 private void writeReflogs() throws TeamException
{
237 writeReflog(Constants
.HEAD
);
238 writeReflog(repository
.getFullBranch());
239 } catch (IOException e
) {
240 throw new TeamException("Writing reflogs", e
);