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
.IWorkspaceRunnable
;
17 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
18 import org
.eclipse
.core
.runtime
.CoreException
;
19 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
20 import org
.eclipse
.core
.runtime
.SubProgressMonitor
;
21 import org
.eclipse
.egit
.core
.CoreText
;
22 import org
.eclipse
.egit
.core
.internal
.util
.ProjectUtil
;
23 import org
.eclipse
.jgit
.lib
.Commit
;
24 import org
.eclipse
.jgit
.lib
.Constants
;
25 import org
.eclipse
.jgit
.lib
.GitIndex
;
26 import org
.eclipse
.jgit
.lib
.ObjectId
;
27 import org
.eclipse
.jgit
.lib
.RefUpdate
;
28 import org
.eclipse
.jgit
.lib
.Repository
;
29 import org
.eclipse
.jgit
.lib
.Tag
;
30 import org
.eclipse
.jgit
.lib
.Tree
;
31 import org
.eclipse
.jgit
.lib
.WorkDirCheckout
;
32 import org
.eclipse
.osgi
.util
.NLS
;
33 import org
.eclipse
.team
.core
.TeamException
;
36 * A class for changing a ref and possibly index and workdir too.
38 public class ResetOperation
implements IEGitOperation
{
42 public enum ResetType
{
44 * Just change the ref. The index and workdir are not changed.
49 * Change the ref and the index. The workdir is not changed.
54 * Change the ref, the index and the workdir
59 private final Repository repository
;
60 private final String refName
;
61 private final ResetType type
;
63 private Commit commit
;
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
;
81 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
83 public void execute(IProgressMonitor monitor
) throws CoreException
{
84 if (type
== ResetType
.HARD
) {
85 IWorkspaceRunnable action
= new IWorkspaceRunnable() {
86 public void run(IProgressMonitor monitor
) throws CoreException
{
90 // lock workspace to protect working tree changes
91 ResourcesPlugin
.getWorkspace().run(action
, monitor
);
97 private void reset(IProgressMonitor monitor
) throws CoreException
{
98 monitor
.beginTask(NLS
.bind(CoreText
.ResetOperation_performingReset
,
99 type
.toString().toLowerCase(), refName
), 7);
107 if (type
!= ResetType
.SOFT
) {
108 if (type
== ResetType
.MIXED
)
116 if (type
== ResetType
.HARD
) {
121 if (type
!= ResetType
.SOFT
) {
128 if (type
== ResetType
.HARD
)
129 // only refresh if working tree changes
130 ProjectUtil
.refreshProjects(repository
, new SubProgressMonitor(
136 private void refreshIndex() throws TeamException
{
137 // File workdir = repository.getDirectory().getParentFile();
138 // for (Entry e : newIndex.getMembers()) {
140 // e.update(new File(workdir, e.getName()));
141 // } catch (IOException ignore) {}
145 } catch (IOException e1
) {
146 throw new TeamException(CoreText
.ResetOperation_writingIndex
, e1
);
150 private void mapObjects() throws TeamException
{
151 final ObjectId commitId
;
153 commitId
= repository
.resolve(refName
);
154 } catch (IOException e
) {
155 throw new TeamException(NLS
.bind(
156 CoreText
.ResetOperation_lookingUpRef
, refName
), e
);
159 commit
= repository
.mapCommit(commitId
);
160 } catch (IOException e
) {
162 Tag t
= repository
.mapTag(refName
, commitId
);
163 commit
= repository
.mapCommit(t
.getObjId());
164 } catch (IOException e2
) {
165 throw new TeamException(NLS
.bind(
166 CoreText
.ResetOperation_lookingUpCommit
, commitId
), e2
);
172 private void writeRef() throws TeamException
{
174 final RefUpdate ru
= repository
.updateRef(Constants
.HEAD
);
175 ru
.setNewObjectId(commit
.getCommitId());
176 String name
= refName
;
177 if (name
.startsWith("refs/heads/")) //$NON-NLS-1$
178 name
= name
.substring(11);
179 if (name
.startsWith("refs/remotes/")) //$NON-NLS-1$
180 name
= name
.substring(13);
181 String message
= "reset --" //$NON-NLS-1$
182 + type
.toString().toLowerCase() + " " + name
; //$NON-NLS-1$
183 ru
.setRefLogMessage(message
, false);
184 if (ru
.forceUpdate() == RefUpdate
.Result
.LOCK_FAILURE
)
185 throw new TeamException(NLS
.bind(
186 CoreText
.ResetOperation_cantUpdate
, ru
.getName()));
187 } catch (IOException e
) {
188 throw new TeamException(NLS
.bind(
189 CoreText
.ResetOperation_updatingFailed
, Constants
.HEAD
), e
);
193 private void readIndex() throws TeamException
{
195 newTree
= commit
.getTree();
196 index
= repository
.getIndex();
197 } catch (IOException e
) {
198 throw new TeamException(CoreText
.ResetOperation_readingIndex
, e
);
202 private void resetIndex() throws TeamException
{
204 newTree
= commit
.getTree();
205 index
= repository
.getIndex();
206 index
.readTree(newTree
);
207 } catch (IOException e
) {
208 throw new TeamException(CoreText
.ResetOperation_readingIndex
, e
);
212 private void writeIndex() throws CoreException
{
215 } catch (IOException e
) {
216 throw new TeamException(CoreText
.ResetOperation_writingIndex
, e
);
220 private void checkoutIndex() throws TeamException
{
221 final File parentFile
= repository
.getWorkDir();
223 WorkDirCheckout workDirCheckout
=
224 new WorkDirCheckout(repository
, parentFile
, index
, newTree
);
225 workDirCheckout
.setFailOnConflict(false);
226 workDirCheckout
.checkout();
227 } catch (IOException e
) {
228 throw new TeamException(
229 CoreText
.ResetOperation_mappingTreeForCommit
, e
);