Cédric Chabanois wrote:
> Thanks for your patch. However I think I corrected the bug recently (I
> committed that yesterday on trunk) ...
>
> However, I will study your patch
A new patch since my previous one was incomplete. :-) It didn't deal
with files inside the moved folder.
I looked at the trunk version, and I noticed that you use DEPTH_INFINITE
for the refreshing of all the changed resources. This seems overly
broad, especially since ancestoral folders are frequently refreshed as
well. I tried to avoid that with my new patch.
Gerco.
Index: core/src/org/tigris/subversion/subclipse/core/resources/SVNMoveDeleteHook.java
===================================================================
--- core/src/org/tigris/subversion/subclipse/core/resources/SVNMoveDeleteHook.java (revision 503)
+++ core/src/org/tigris/subversion/subclipse/core/resources/SVNMoveDeleteHook.java (working copy)
@@ -137,6 +137,9 @@
if (keepHistory)
tree.addToLocalHistory(source);
+ if (!isDeep)
+ System.out.println("moveFile: ignoring SHALLOW");
+
try {
OperationManager.getInstance().beginOperation(svnClient);
@@ -199,10 +202,13 @@
monitor.beginTask(null, 1000);
monitor.setTaskName("Working..");
+ boolean force = (updateFlags & IResource.FORCE) != 0;
+ boolean keepHistory = (updateFlags & IResource.KEEP_HISTORY) != 0;
+ boolean isDeep = (updateFlags & IResource.SHALLOW) == 0;
+
// Check to see if we are synchronized with the local file system. If we are in sync then we can
// short circuit this method and do a file system only move. Otherwise we have to recursively
// try and move all resources, doing it in a best-effort manner.
- boolean force = (updateFlags & IResource.FORCE) != 0;
if (!force && !tree.isSynchronized(source, IResource.DEPTH_INFINITE)) {
String message = org.eclipse.core.internal.utils.Policy.bind("localstore.resourceIsOutOfSync", source.getFullPath().toString());//$NON-NLS-1$
IStatus status = new ResourceStatus(IResourceStatus.ERROR, source.getFullPath(), message);
@@ -210,6 +216,12 @@
return true;
}
+ if (keepHistory)
+ System.out.println("moveFolder: ignoring KEEP_HISTORY");
+
+ if (!isDeep)
+ System.out.println("moveFolder: ignoring SHALLOW");
+
ISVNClientAdapter svnClient = resource.getRepository().getSVNClient();
try {
@@ -234,7 +246,6 @@
} finally {
OperationManager.getInstance().endOperation();
}
-
} catch (SVNException e) {
tree.failed(
new org.eclipse.core.runtime.Status(
Index: core/src/org/tigris/subversion/subclipse/core/resources/LocalFolder.java
===================================================================
--- core/src/org/tigris/subversion/subclipse/core/resources/LocalFolder.java (revision 503)
+++ core/src/org/tigris/subversion/subclipse/core/resources/LocalFolder.java (working copy)
@@ -169,6 +169,10 @@
if (!isManaged()) {
return container.exists();
}
+
+ ISVNStatus status = getStatus();
+ if (status.getTextStatus() == ISVNStatus.Kind.DELETED)
+ return true;
ISVNLocalResource[] children = (ISVNLocalResource[])members(new NullProgressMonitor(),ALL_UNIGNORED_MEMBERS);
Index: core/src/org/tigris/subversion/subclipse/core/client/OperationManager.java
===================================================================
--- core/src/org/tigris/subversion/subclipse/core/client/OperationManager.java (revision 503)
+++ core/src/org/tigris/subversion/subclipse/core/client/OperationManager.java (working copy)
@@ -9,6 +9,7 @@
* Cédric Chabanois (cchabanois@ifrance.com) - modified for Subversion
*******************************************************************************/
package org.tigris.subversion.subclipse.core.client;
+
import java.io.*;
import java.util.*;
import org.eclipse.core.resources.*;
@@ -16,6 +17,7 @@
import org.tigris.subversion.subclipse.core.*;
import org.tigris.subversion.subclipse.core.util.*;
import org.tigris.subversion.svnclientadapter.*;
+
/**
* This class manages jsvn operations. beginOperation must be called before a
* batch of svn operations and endOperation after
@@ -25,23 +27,29 @@
public class OperationManager implements ISVNNotifyListener {
// track resources that have changed in a given operation
private ReentrantLock lock = new ReentrantLock();
- private Set changedResources = new HashSet();
+ private Set changedShallowResources = new HashSet();
+ private Set changedDeepResources = new HashSet();
private ISVNClientAdapter svnClient = null;
+ private boolean isMoveCommand;
+
private static OperationManager instance;
+
/*
* private contructor
*/
private OperationManager() {
}
+
/**
* Returns the singleton instance of the synchronizer.
*/
public static OperationManager getInstance() {
- if (instance == null) {
+ if (instance == null)
instance = new OperationManager();
- }
+
return instance;
}
+
/**
* Begins a batch of operations.
*/
@@ -50,9 +58,12 @@
this.svnClient = svnClient;
svnClient.addNotifyListener(this);
if (lock.getNestingCount() == 1) {
- changedResources.clear();
+ isMoveCommand = false;
+ changedShallowResources.clear();
+ changedDeepResources.clear();
}
}
+
/**
* Ends a batch of operations. Pending changes are committed only when the
* number of calls to endOperation() balances those to beginOperation().
@@ -61,64 +72,121 @@
try {
if (lock.getNestingCount() == 1) {
svnClient.removeNotifyListener(this);
- for (Iterator it = changedResources.iterator(); it.hasNext();) {
+
+ for (Iterator it = changedShallowResources.iterator(); it.hasNext();) {
IResource resource = (IResource) it.next();
try {
+ if(Policy.DEBUG_METAFILE_CHANGES) {
+ System.out.print("[svn] shallow refresh of : ");
+ System.out.println(resource.getFullPath());
+ }
+
resource.refreshLocal(IResource.DEPTH_ZERO,
- new NullProgressMonitor());
+ new NullProgressMonitor());
} catch (CoreException e) {
throw SVNException.wrapException(e);
}
}
+
+ for (Iterator it = changedDeepResources.iterator(); it.hasNext();) {
+ IResource resource = (IResource) it.next();
+ try {
+ if(Policy.DEBUG_METAFILE_CHANGES) {
+ System.out.print("[svn] deep refresh of : ");
+ System.out.println(resource.getFullPath());
+ }
+
+ resource.refreshLocal(IResource.DEPTH_INFINITE,
+ new NullProgressMonitor());
+ } catch (CoreException e) {
+ throw SVNException.wrapException(e);
+ }
+ }
}
} finally {
lock.release();
}
}
+
public void onNotify(File path, SVNNodeKind kind) {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IWorkspaceRoot workspaceRoot = workspace.getRoot();
- IPath pathEclipse;
try {
- pathEclipse = new Path(path.getCanonicalPath());
+ IResource resource;
+ IResource dotSVN;
+ IResource entries;
+
+ IPath pathEclipse = new Path(path.getCanonicalPath());
if (kind == SVNNodeKind.UNKNOWN) { // delete, revert
- IPath pathEntries = pathEclipse.removeLastSegments(1).append(
- ".svn/entries");
- IResource entries = workspaceRoot
- .getFileForLocation(pathEntries);
- changedResources.add(entries);
- } else {
- IResource resource = null;
- if (kind == SVNNodeKind.DIR)
- resource = workspaceRoot
- .getContainerForLocation(pathEclipse);
- else if (kind == SVNNodeKind.FILE)
- resource = workspaceRoot.getFileForLocation(pathEclipse);
- IResource entries = null;
- if (resource != null)
- entries = resource.getParent().getFile(
- new Path(".svn/entries"));
- if (resource != null) {
- // this is not really necessary because as .svn/entries is
- // added, the
- // corresponding directory will be refreshed
- changedResources.add(resource);
+ IPath pathDotSVN = pathEclipse.removeLastSegments(1).append(".svn");
+ dotSVN = workspaceRoot.getContainerForLocation(pathDotSVN);
+ if (dotSVN != null)
+ changedDeepResources.add(dotSVN);
+
+ IPath pathEntries = pathEclipse.removeLastSegments(1).append(".svn/entries");
+ entries = workspaceRoot.getFileForLocation(pathEntries);
+ if (entries != null)
+ changedShallowResources.add(entries);
+ } else if (kind == SVNNodeKind.DIR) {
+ resource = workspaceRoot.getContainerForLocation(pathEclipse);
+ if (resource.getType() == IResource.FOLDER) {
+ dotSVN = resource.getParent().getFolder(new Path(".svn"));
+ if (dotSVN != null)
+ changedDeepResources.add(dotSVN);
+
+ entries = resource.getParent().getFile(new Path(".svn/entries"));
+ if (entries != null)
+ changedShallowResources.add(entries);
}
+
+ // this is not really necessary because as .svn/entries is
+ // added, the corresponding directory will be refreshed
+ if (isMoveCommand)
+ changedDeepResources.add(resource);
+ else
+ changedShallowResources.add(resource);
+
+ // Add meta data of directory/folder
+ dotSVN = ((IContainer)resource).getFolder(new Path(".svn"));
+ if (dotSVN != null)
+ changedDeepResources.add(dotSVN);
+
+ entries = ((IContainer)resource).getFile(new Path(".svn/entries"));
if (entries != null)
- changedResources.add(entries);
+ changedShallowResources.add(entries);
+ } else if (kind == SVNNodeKind.FILE) {
+ resource = workspaceRoot.getFileForLocation(pathEclipse);
+ dotSVN = resource.getParent().getFolder(new Path(".svn"));
+ if (dotSVN != null)
+ changedDeepResources.add(dotSVN);
+
+ entries = resource.getParent().getFile(new Path(".svn/entries"));
+ if (entries != null)
+ changedShallowResources.add(entries);
+
+ // this is not really necessary because as .svn/entries is
+ // added, the corresponding directory will be refreshed
+ changedShallowResources.add(resource);
}
} catch (IOException e) {
- e.printStackTrace();//shouldn't happen?
+ e.printStackTrace(); //shouldn't happen?
}
}
+
public void logCommandLine(String commandLine) {
}
+
public void logCompleted(String message) {
}
+
public void logError(String message) {
}
+
public void logMessage(String message) {
}
+
public void setCommand(int command) {
+ if (command == ISVNNotifyListener.Command.MOVE)
+ isMoveCommand = true;
}
}
Received on Mon Apr 19 21:52:02 2004