[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Reproduction recipe for failing package rename

From: Gerco Ballintijn <Gerco.Ballintijn_at_cwi.nl>
Date: 2004-04-19 13:52:02 CEST

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

This is an archived mail posted to the Subclipse Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.