Revert "Teach GitMoveDeleteHook how to move a folder recursively"
[egit.git] / org.spearce.egit.core / src / org / spearce / egit / core / GitMoveDeleteHook.java
blob409f0184926730e370b490f9f332efe79c1d2a90
1 /*******************************************************************************
2 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * See LICENSE for the full license text, also available.
8 *******************************************************************************/
9 package org.spearce.egit.core;
11 import java.io.IOException;
13 import org.eclipse.core.resources.IFile;
14 import org.eclipse.core.resources.IFolder;
15 import org.eclipse.core.resources.IProject;
16 import org.eclipse.core.resources.IProjectDescription;
17 import org.eclipse.core.resources.IResource;
18 import org.eclipse.core.resources.team.IMoveDeleteHook;
19 import org.eclipse.core.resources.team.IResourceTree;
20 import org.eclipse.core.runtime.Assert;
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.core.runtime.Status;
24 import org.spearce.egit.core.project.GitProjectData;
25 import org.spearce.egit.core.project.RepositoryMapping;
26 import org.spearce.jgit.dircache.DirCache;
27 import org.spearce.jgit.dircache.DirCacheBuilder;
28 import org.spearce.jgit.dircache.DirCacheEditor;
29 import org.spearce.jgit.dircache.DirCacheEntry;
31 class GitMoveDeleteHook implements IMoveDeleteHook {
32 private static final boolean I_AM_DONE = true;
34 private static final boolean FINISH_FOR_ME = false;
36 private final GitProjectData data;
38 GitMoveDeleteHook(final GitProjectData d) {
39 Assert.isNotNull(d);
40 data = d;
43 public boolean deleteFile(final IResourceTree tree, final IFile file,
44 final int updateFlags, final IProgressMonitor monitor) {
45 final boolean force = (updateFlags & IResource.FORCE) == IResource.FORCE;
46 if (!force && !tree.isSynchronized(file, IResource.DEPTH_ZERO))
47 return false;
49 final RepositoryMapping map = RepositoryMapping.getMapping(file);
50 if (map == null)
51 return false;
53 try {
54 final DirCache dirc = DirCache.lock(map.getRepository());
55 final int first = dirc.findEntry(map.getRepoRelativePath(file));
56 if (first < 0) {
57 dirc.unlock();
58 return false;
61 final DirCacheBuilder edit = dirc.builder();
62 if (first > 0)
63 edit.keep(0, first);
64 final int next = dirc.nextEntry(first);
65 if (next < dirc.getEntryCount())
66 edit.keep(next, dirc.getEntryCount() - next);
67 if (!edit.commit())
68 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
69 0, CoreText.MoveDeleteHook_operationError, null));
70 tree.standardDeleteFile(file, updateFlags, monitor);
71 } catch (IOException e) {
72 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
73 CoreText.MoveDeleteHook_operationError, e));
75 return true;
78 public boolean deleteFolder(final IResourceTree tree, final IFolder folder,
79 final int updateFlags, final IProgressMonitor monitor) {
80 // Deleting a GIT repository which is in use is a pretty bad idea. To
81 // delete disconnect the team provider first.
83 if (data.isProtected(folder)) {
84 return cannotModifyRepository(tree);
85 } else {
86 return FINISH_FOR_ME;
90 public boolean deleteProject(final IResourceTree tree,
91 final IProject project, final int updateFlags,
92 final IProgressMonitor monitor) {
93 // TODO: Note that eclipse thinks folders are real, while
94 // Git does not care.
95 return FINISH_FOR_ME;
98 public boolean moveFile(final IResourceTree tree, final IFile srcf,
99 final IFile dstf, final int updateFlags,
100 final IProgressMonitor monitor) {
101 final boolean force = (updateFlags & IResource.FORCE) == IResource.FORCE;
102 if (!force && !tree.isSynchronized(srcf, IResource.DEPTH_ZERO))
103 return false;
105 final RepositoryMapping srcm = RepositoryMapping.getMapping(srcf);
106 if (srcm == null)
107 return false;
108 final RepositoryMapping dstm = RepositoryMapping.getMapping(dstf);
110 try {
111 final DirCache sCache = DirCache.lock(srcm.getRepository());
112 final String sPath = srcm.getRepoRelativePath(srcf);
113 final DirCacheEntry sEnt = sCache.getEntry(sPath);
114 if (sEnt == null) {
115 sCache.unlock();
116 return false;
119 final DirCacheEditor sEdit = sCache.editor();
120 sEdit.add(new DirCacheEditor.DeletePath(sEnt));
121 if (dstm != null && dstm.getRepository() == srcm.getRepository()) {
122 final String dPath = srcm.getRepoRelativePath(dstf);
123 sEdit.add(new DirCacheEditor.PathEdit(dPath) {
124 @Override
125 public void apply(final DirCacheEntry dEnt) {
126 dEnt.copyMetaData(sEnt);
130 if (!sEdit.commit())
131 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
132 0, CoreText.MoveDeleteHook_operationError, null));
134 tree.standardMoveFile(srcf, dstf, updateFlags, monitor);
135 } catch (IOException e) {
136 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
137 CoreText.MoveDeleteHook_operationError, e));
139 return true;
142 public boolean moveFolder(final IResourceTree tree, final IFolder source,
143 final IFolder destination, final int updateFlags,
144 final IProgressMonitor monitor) {
145 // TODO: Implement this. Should be relatively easy, but consider that
146 // Eclipse thinks folders are real thinsgs, while Git does not care.
147 return FINISH_FOR_ME;
150 public boolean moveProject(final IResourceTree tree, final IProject source,
151 final IProjectDescription description, final int updateFlags,
152 final IProgressMonitor monitor) {
153 // TODO: We should be able to do this without too much effort when the
154 // projects belong to the same Git repository.
155 return FINISH_FOR_ME;
158 private boolean cannotModifyRepository(final IResourceTree tree) {
159 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
160 CoreText.MoveDeleteHook_cannotModifyFolder, null));
161 return I_AM_DONE;