From 6f261bceb66502ed63e3856d3e543738792c79da Mon Sep 17 00:00:00 2001 From: irengrig Date: Wed, 6 Oct 2010 01:45:25 +0400 Subject: [PATCH] VCS: ignored & unversioned as-is; test for external changes detection - initial version; heavy latch aware for local changes gathering: through -D --- .../vcs/MockChangelistBuilder.java | 5 - .../src/com/intellij/openapi/vcs/AreaMap.java | 20 +++ .../vcs/changes/ChangelistBuilder.java | 2 - .../vcs/changes/EmptyChangelistBuilder.java | 4 - .../vcs/changes/ChangeListManagerImpl.java | 122 +++++++++--------- .../openapi/vcs/changes/ChangeListWorker.java | 4 +- .../vcs/changes/DeletedFilesHolder.java | 2 +- .../openapi/vcs/changes/FileHolder.java | 2 +- .../vcs/changes/FileHolderComposite.java | 4 +- .../vcs/changes/LocalChangesUpdater.java | 2 +- .../vcs/changes/LogicallyLockedHolder.java | 26 +++- .../vcs/changes/RecursiveFileHolder.java | 17 ++- .../vcs/changes/UpdateRequestsQueue.java | 24 ++-- .../changes/UpdatingChangeListBuilder.java | 16 +-- .../vcs/changes/VirtualFileHolder.java | 43 +++--- .../integrate/GatheringChangelistBuilder.java | 4 - 16 files changed, 166 insertions(+), 131 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/vcs/MockChangelistBuilder.java b/platform/testFramework/src/com/intellij/testFramework/vcs/MockChangelistBuilder.java index 898998c8725c..a70b89382487 100644 --- a/platform/testFramework/src/com/intellij/testFramework/vcs/MockChangelistBuilder.java +++ b/platform/testFramework/src/com/intellij/testFramework/vcs/MockChangelistBuilder.java @@ -82,11 +82,6 @@ public class MockChangelistBuilder implements ChangelistBuilder { public void processRootSwitch(VirtualFile file, String branch) { } - @Override - public boolean isUpdatingUnversionedFiles() { - return true; - } - @Override public boolean reportChangesOutsideProject() { return false; diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/AreaMap.java b/platform/vcs-api/src/com/intellij/openapi/vcs/AreaMap.java index 87e54703a979..9e597cb65def 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/AreaMap.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/AreaMap.java @@ -134,4 +134,24 @@ public class AreaMap { myKeys.clear(); myMap.clear(); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AreaMap areaMap = (AreaMap)o; + + if (!myKeys.equals(areaMap.myKeys)) return false; + if (!myMap.equals(areaMap.myMap)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = myKeys.hashCode(); + result = 31 * result + myMap.hashCode(); + return result; + } } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangelistBuilder.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangelistBuilder.java index fa02cba3df3b..e3115f97e0f4 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangelistBuilder.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangelistBuilder.java @@ -105,7 +105,5 @@ public interface ChangelistBuilder { void processRootSwitch(VirtualFile file, String branch); - boolean isUpdatingUnversionedFiles(); - boolean reportChangesOutsideProject(); } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/EmptyChangelistBuilder.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/EmptyChangelistBuilder.java index 3e02319cffcc..7775708e8ab1 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/EmptyChangelistBuilder.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/EmptyChangelistBuilder.java @@ -61,10 +61,6 @@ public class EmptyChangelistBuilder implements ChangelistBuilder { public void processRootSwitch(VirtualFile file, String branch) { } - public boolean isUpdatingUnversionedFiles() { - return true; - } - public boolean reportChangesOutsideProject() { return false; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java index 02b5ccc087ce..1253c07886b3 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java @@ -263,20 +263,20 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec static class DisposedException extends RuntimeException {} public void scheduleUpdate() { - myUpdater.schedule(true); + myUpdater.schedule(); } public void scheduleUpdate(boolean updateUnversionedFiles) { - myUpdater.schedule(updateUnversionedFiles); + myUpdater.schedule(); } private class ActualUpdater implements LocalChangesUpdater { - public void execute(boolean updateUnversioned, AtomicSectionsAware atomicSectionsAware) { - updateImmediately(updateUnversioned, atomicSectionsAware); + public void execute(AtomicSectionsAware atomicSectionsAware) { + updateImmediately(atomicSectionsAware); } } - private void updateImmediately(final boolean updateUnversionedFiles, final AtomicSectionsAware atomicSectionsAware) { + private void updateImmediately(final AtomicSectionsAware atomicSectionsAware) { FileHolderComposite composite; ChangeListWorker changeListWorker; @@ -313,13 +313,11 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec // after update of copies of objects is complete, it would apply the same modifications to copies.) synchronized (myDataLock) { changeListWorker = myWorker.copy(); - composite = updateUnversionedFiles ? (FileHolderComposite) myComposite.copy() : myComposite; + composite = (FileHolderComposite) myComposite.copy(); myModifier.enterUpdate(); if (wasEverythingDirty) { myUpdateException = null; - } - if (updateUnversionedFiles && wasEverythingDirty) { - composite.cleanAll(); + composite.cleanAll(); } } if (wasEverythingDirty) { @@ -334,7 +332,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec public Boolean get() { return myUpdater.isStopped(); } - }, updateUnversionedFiles, myIgnoredIdeaLevel, gate); + }, myIgnoredIdeaLevel, gate); myUpdateChangesProgressIndicator = new EmptyProgressIndicator() { @Override @@ -356,29 +354,26 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec myChangesViewManager.updateProgressText(VcsBundle.message("changes.update.progress.message", vcs.getDisplayName()), false); if (! wasEverythingDirty) { + composite.cleanAndAdjustScope(adjustedScope); changeListWorker.notifyStartProcessingChanges(adjustedScope); } - if (updateUnversionedFiles && !wasEverythingDirty) { - composite.cleanScope(adjustedScope); - } - + try { actualUpdate(wasEverythingDirty, composite, builder, adjustedScope, vcs, changeListWorker, gate); } catch (Throwable t) { LOG.info(t); - if (t instanceof Error) { - throw (Error) t; - } else if (t instanceof RuntimeException) { - throw (RuntimeException) t; - } - throw new RuntimeException(t); + reThrowRuntime(t); } if (myUpdateException != null) break; } final boolean takeChanges = (myUpdateException == null); + if (takeChanges) { + // update IDEA-level ignored files + updateIgnoredFiles(composite); + } synchronized (myDataLock) { // do same modifications to change lists as was done during update + do delayed notifications @@ -394,17 +389,13 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec myWorker.takeData(changeListWorker); } - if (takeChanges && updateUnversionedFiles) { - boolean statusChanged = !myComposite.equals(composite); + if (takeChanges) { + final boolean statusChanged = ! myComposite.equals(composite); myComposite = composite; if (statusChanged) { myDelayedNotificator.getProxyDispatcher().unchangedFileStatusChanged(); } } - - if (takeChanges) { - updateIgnoredFiles(false); - } myShowLocalChangesInvalidated = false; } myChangesViewManager.scheduleRefresh(); @@ -431,6 +422,15 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + private static void reThrowRuntime(final Throwable t) { + if (t instanceof Error) { + throw (Error) t; + } else if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } + throw new RuntimeException(t); + } + private void actualUpdate(final boolean wasEverythingDirty, final FileHolderComposite composite, final UpdatingChangeListBuilder builder, final VcsDirtyScope scope, final AbstractVcs vcs, final ChangeListWorker changeListWorker, final ChangeListManagerGate gate) { @@ -499,35 +499,49 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } public List getUnversionedFiles() { - return myComposite.getVFHolder(FileHolder.HolderType.UNVERSIONED).getFiles(); + synchronized (myDataLock) { + return myComposite.getVFHolder(FileHolder.HolderType.UNVERSIONED).getFiles(); + } } Pair getUnversionedFilesSize() { - final VirtualFileHolder holder = myComposite.getVFHolder(FileHolder.HolderType.UNVERSIONED); - return new Pair(holder.getSize(), holder.getNumDirs()); + synchronized (myDataLock) { + final VirtualFileHolder holder = myComposite.getVFHolder(FileHolder.HolderType.UNVERSIONED); + return new Pair(holder.getSize(), holder.getNumDirs()); + } } List getModifiedWithoutEditing() { - return new ArrayList(myComposite.getVFHolder(FileHolder.HolderType.MODIFIED_WITHOUT_EDITING).getFiles()); + synchronized (myDataLock) { + return myComposite.getVFHolder(FileHolder.HolderType.MODIFIED_WITHOUT_EDITING).getFiles(); + } } /** * @return only roots for ignored folders, and ignored files */ List getIgnoredFiles() { - return new ArrayList(myComposite.getIgnoredFileHolder().values()); + synchronized (myDataLock) { + return new ArrayList(myComposite.getIgnoredFileHolder().values()); + } } public List getLockedFolders() { - return new ArrayList(myComposite.getVFHolder(FileHolder.HolderType.LOCKED).getFiles()); + synchronized (myDataLock) { + return myComposite.getVFHolder(FileHolder.HolderType.LOCKED).getFiles(); + } } Map getLogicallyLockedFolders() { - return new HashMap(((LogicallyLockedHolder) myComposite.get(FileHolder.HolderType.LOGICALLY_LOCKED)).getMap()); + synchronized (myDataLock) { + return new HashMap(((LogicallyLockedHolder) myComposite.get(FileHolder.HolderType.LOGICALLY_LOCKED)).getMap()); + } } public boolean isLogicallyLocked(final VirtualFile file) { - return ((LogicallyLockedHolder) myComposite.get(FileHolder.HolderType.LOGICALLY_LOCKED)).getMap().containsKey(file); + synchronized (myDataLock) { + return ((LogicallyLockedHolder) myComposite.get(FileHolder.HolderType.LOGICALLY_LOCKED)).containsKey(file); + } } public boolean isContainedInLocallyDeleted(final FilePath filePath) { @@ -732,7 +746,9 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } public boolean isUnversioned(VirtualFile file) { - return myComposite.getVFHolder(FileHolder.HolderType.UNVERSIONED).containsFile(file); + synchronized (myDataLock) { + return myComposite.getVFHolder(FileHolder.HolderType.UNVERSIONED).containsFile(file); + } } @NotNull @@ -912,39 +928,21 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec public void addFilesToIgnore(final IgnoredFileBean... filesToIgnore) { myIgnoredIdeaLevel.add(filesToIgnore); - updateIgnoredFiles(true); + scheduleUpdate(); } public void setFilesToIgnore(final IgnoredFileBean... filesToIgnore) { myIgnoredIdeaLevel.set(filesToIgnore); - // todo!!!!!! dont synchronously - updateIgnoredFiles(true); + scheduleUpdate(); } - private void updateIgnoredFiles(final boolean checkIgnored) { - synchronized (myDataLock) { - List unversionedFiles = myComposite.getVFHolder(FileHolder.HolderType.UNVERSIONED).getFiles(); - //List ignoredFiles = myComposite.getVFHolder(FileHolder.HolderType.IGNORED).getFiles(); - boolean somethingChanged = false; - for(VirtualFile file: unversionedFiles) { - if (isIgnoredFile(file)) { - somethingChanged = true; - myComposite.getVFHolder(FileHolder.HolderType.UNVERSIONED).removeFile(file); - myComposite.getIgnoredFileHolder().addFile(file); - } - } - /*if (checkIgnored) { - for(VirtualFile file: ignoredFiles) { - if (!isIgnoredFile(file)) { - somethingChanged = true; - // the file may have been reported as ignored by the VCS, so we can't directly move it to unversioned files - VcsDirtyScopeManager.getInstance(myProject).fileDirty(file); - } - } - }*/ - if (somethingChanged) { - myFileStatusManager.fileStatusesChanged(); - myChangesViewManager.scheduleRefresh(); + private void updateIgnoredFiles(final FileHolderComposite composite) { + List unversionedFiles = composite.getVFHolder(FileHolder.HolderType.UNVERSIONED).getFiles(); + + for(VirtualFile file: unversionedFiles) { + if (isIgnoredFile(file)) { + composite.getVFHolder(FileHolder.HolderType.UNVERSIONED).removeFile(file); + composite.getIgnoredFileHolder().addFile(file); } } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java index dae601bbd706..d9921669e26d 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java @@ -370,8 +370,8 @@ public class ChangeListWorker implements ChangeListsWriteOperations { // scope should be modified for correct moves tracking correctScopeForMoves(scope, oldChanges); - myLocallyDeleted.cleanScope(scope); - mySwitchedHolder.cleanScope(scope); + myLocallyDeleted.cleanAndAdjustScope(scope); + mySwitchedHolder.cleanAndAdjustScope(scope); } private void correctScopeForMoves(final VcsAppendableDirtyScope scope, final Collection changes) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DeletedFilesHolder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DeletedFilesHolder.java index acb851894f4e..9ec482df5e6e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DeletedFilesHolder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DeletedFilesHolder.java @@ -37,7 +37,7 @@ public class DeletedFilesHolder implements FileHolder { myFiles.putAll(holder.myFiles); } - public void cleanScope(final VcsDirtyScope scope) { + public void cleanAndAdjustScope(final VcsAppendableDirtyScope scope) { if (scope == null) { myFiles.clear(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FileHolder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FileHolder.java index a081d0cc8475..da3b5938fca4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FileHolder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FileHolder.java @@ -17,7 +17,7 @@ package com.intellij.openapi.vcs.changes; interface FileHolder { void cleanAll(); - void cleanScope(VcsDirtyScope scope); + void cleanAndAdjustScope(VcsAppendableDirtyScope scope); FileHolder copy(); HolderType getType(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FileHolderComposite.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FileHolderComposite.java index 39da87ecb5d4..6be42f7d88f3 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FileHolderComposite.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FileHolderComposite.java @@ -53,9 +53,9 @@ public class FileHolderComposite implements FileHolder { } } - public void cleanScope(final VcsDirtyScope scope) { + public void cleanAndAdjustScope(final VcsAppendableDirtyScope scope) { for (FileHolder holder : myHolders.values()) { - holder.cleanScope(scope); + holder.cleanAndAdjustScope(scope); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LocalChangesUpdater.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LocalChangesUpdater.java index 8214f1e625d9..b287818abc91 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LocalChangesUpdater.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LocalChangesUpdater.java @@ -18,5 +18,5 @@ package com.intellij.openapi.vcs.changes; import com.intellij.lifecycle.AtomicSectionsAware; public interface LocalChangesUpdater { - void execute(boolean updateUnversioned, AtomicSectionsAware atomicSectionsAware); + void execute(AtomicSectionsAware atomicSectionsAware); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LogicallyLockedHolder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LogicallyLockedHolder.java index fbd5b9ee7d27..17e0e93ffef6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LogicallyLockedHolder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LogicallyLockedHolder.java @@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.changes; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -38,7 +39,7 @@ public class LogicallyLockedHolder implements FileHolder { myMap.put(file, lock); } - public void cleanScope(VcsDirtyScope scope) { + public void cleanAndAdjustScope(VcsAppendableDirtyScope scope) { VirtualFileHolder.cleanScope(myProject, myMap.keySet(), scope); } @@ -52,7 +53,28 @@ public class LogicallyLockedHolder implements FileHolder { return HolderType.LOGICALLY_LOCKED; } + public boolean containsKey(final VirtualFile vf) { + return myMap.containsKey(vf); + } + public Map getMap() { - return myMap; + return Collections.unmodifiableMap(myMap); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + LogicallyLockedHolder that = (LogicallyLockedHolder)o; + + if (!myMap.equals(that.myMap)) return false; + + return true; + } + + @Override + public int hashCode() { + return myMap.hashCode(); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RecursiveFileHolder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RecursiveFileHolder.java index cd559def71b6..3d39ab050826 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RecursiveFileHolder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RecursiveFileHolder.java @@ -43,7 +43,7 @@ public class RecursiveFileHolder implements FileHolder { myMap.clear(); } - public void cleanScope(final VcsDirtyScope scope) { + public void cleanAndAdjustScope(final VcsAppendableDirtyScope scope) { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { // to avoid deadlocks caused by incorrect lock ordering, need to lock on this after taking read action @@ -94,4 +94,19 @@ public class RecursiveFileHolder implements FileHolder { public synchronized Collection values() { return myMap.keySet(); } + + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final RecursiveFileHolder that = (RecursiveFileHolder)o; + + if (!myMap.equals(that.myMap)) return false; + + return true; + } + + public int hashCode() { + return myMap.hashCode(); + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java index 817253f3635b..5497cc04077a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java @@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.util.Consumer; +import com.intellij.util.io.storage.HeavyProcessLatch; import org.jetbrains.annotations.NonNls; import javax.swing.*; @@ -41,6 +42,7 @@ import java.util.concurrent.TimeUnit; @SomeQueue public class UpdateRequestsQueue { private final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.UpdateRequestsQueue"); + private final static String ourHeavyLatchOptimization = "vcs.local.changes.track.heavy.latch"; private final Project myProject; private final ScheduledExecutorService myExecutor; private final LocalChangesUpdater myDelegate; @@ -51,15 +53,16 @@ public class UpdateRequestsQueue { private boolean myRequestSubmitted; private final List myWaitingUpdateCompletionQueue; private final ProjectLevelVcsManager myPlVcsManager; - private boolean myUpdateUnversionedRequested; //private final ScheduledSlowlyClosingAlarm mySharedExecutor; private final StartupManager myStartupManager; private final ExecutorWrapper myExecutorWrapper; @NonNls public static final String LOCAL_CHANGES_UPDATE = "Local changes update"; + private final boolean myTrackHeavyLatch; public UpdateRequestsQueue(final Project project, final ScheduledExecutorService executor, final LocalChangesUpdater delegate) { myProject = project; myExecutor = executor; + myTrackHeavyLatch = Boolean.parseBoolean(System.getProperty(ourHeavyLatchOptimization)); //mySharedExecutor = ControlledAlarmFactory.createScheduledOnSharedThread(project, LOCAL_CHANGES_UPDATE, executor); myExecutorWrapper = new ExecutorWrapper(myProject, LOCAL_CHANGES_UPDATE); @@ -72,7 +75,6 @@ public class UpdateRequestsQueue { // not initialized myStarted = false; myStopped = false; - myUpdateUnversionedRequested = false; } public void initialized() { @@ -84,7 +86,7 @@ public class UpdateRequestsQueue { return myStopped; } - public void schedule(final boolean updateUnversionedFiles) { + public void schedule() { synchronized (myLock) { if (! myStarted && ApplicationManager.getApplication().isUnitTestMode()) return; @@ -94,9 +96,6 @@ public class UpdateRequestsQueue { myRequestSubmitted = true; myExecutor.schedule(runnable, 300, TimeUnit.MILLISECONDS); LOG.debug("Scheduled for project: " + myProject.getName() + ", runnable: " + runnable.hashCode()); - myUpdateUnversionedRequested |= updateUnversionedFiles; - } else if (updateUnversionedFiles && (! myUpdateUnversionedRequested)) { - myUpdateUnversionedRequested = true; } } } @@ -136,7 +135,7 @@ public class UpdateRequestsQueue { } myWaitingUpdateCompletionQueue.add(data.getCallback()); - schedule(true); + schedule(); } } // do not run under lock; stopped cannot be switched into not stopped - can check without lock @@ -165,11 +164,11 @@ public class UpdateRequestsQueue { try { synchronized (myLock) { if ((! myStopped) && ((! myStarted) || myPlVcsManager.isBackgroundVcsOperationRunning()) || - (! ((StartupManagerImpl) myStartupManager).startupActivityPassed())) { + (! ((StartupManagerImpl) myStartupManager).startupActivityPassed()) || myTrackHeavyLatch && HeavyProcessLatch.INSTANCE.isRunning()) { LOG.debug("MyRunnable: not started, not stopped, reschedule, project: " + myProject.getName() + ", runnable: " + hashCode()); myRequestSubmitted = false; // try again after time - schedule(myUpdateUnversionedRequested); + schedule(); return; } @@ -180,17 +179,12 @@ public class UpdateRequestsQueue { LOG.debug("MyRunnable: STOPPED, project: " + myProject.getName() + ", runnable: " + hashCode()); return; } - - // take it under lock - updateUnversioned = myUpdateUnversionedRequested; - // for concurrent schedules to tigger flag correctly - myUpdateUnversionedRequested = false; } LOG.debug("MyRunnable: INVOKE, project: " + myProject.getName() + ", runnable: " + hashCode()); myExecutorWrapper.submit(new Consumer() { public void consume(AtomicSectionsAware atomicSectionsAware) { - myDelegate.execute(updateUnversioned, atomicSectionsAware); + myDelegate.execute(atomicSectionsAware); } }); LOG.debug("MyRunnable: invokeD, project: " + myProject.getName() + ", runnable: " + hashCode()); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java index d97f4ad18b3b..1cfc7eea25e4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java @@ -34,7 +34,6 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { private final Getter myDisposedGetter; private VcsDirtyScope myScope; private FoldersCutDownWorker myFoldersCutDownWorker; - private final boolean myUpdateUnversioned; private final IgnoredFilesComponent myIgnoredFilesComponent; private final ExcludedFileIndex myIndex; private final ChangeListManagerGate myGate; @@ -42,12 +41,10 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { UpdatingChangeListBuilder(final ChangeListWorker changeListWorker, final FileHolderComposite composite, final Getter disposedGetter, - final boolean updateUnversioned, final IgnoredFilesComponent ignoredFilesComponent, final ChangeListManagerGate gate) { myChangeListWorker = changeListWorker; myComposite = composite; myDisposedGetter = disposedGetter; - myUpdateUnversioned = updateUnversioned; myIgnoredFilesComponent = ignoredFilesComponent; myGate = gate; myIndex = ExcludedFileIndex.getInstance(changeListWorker.getProject()); @@ -112,7 +109,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { } public void processUnversionedFile(final VirtualFile file) { - if (file == null || ! myUpdateUnversioned) return; + if (file == null) return; checkIfDisposed(); if (isExcluded(file)) return; if (myScope.belongsTo(new FilePathImpl(file))) { @@ -134,7 +131,6 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { } public void processLocallyDeletedFile(LocallyDeletedChange locallyDeletedChange) { - if (! myUpdateUnversioned) return; checkIfDisposed(); final FilePath file = locallyDeletedChange.getPath(); if (FileTypeManager.getInstance().isFileIgnored(file.getName())) return; @@ -144,7 +140,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { } public void processModifiedWithoutCheckout(final VirtualFile file) { - if (file == null || ! myUpdateUnversioned) return; + if (file == null) return; checkIfDisposed(); if (isExcluded(file)) return; if (myScope.belongsTo(new FilePathImpl(file))) { @@ -153,7 +149,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { } public void processIgnoredFile(final VirtualFile file) { - if (file == null || ! myUpdateUnversioned) return; + if (file == null) return; checkIfDisposed(); if (isExcluded(file)) return; if (myScope.belongsTo(new FilePathImpl(file))) { @@ -180,7 +176,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { } public void processSwitchedFile(final VirtualFile file, final String branch, final boolean recursive) { - if (file == null || ! myUpdateUnversioned) return; + if (file == null) return; checkIfDisposed(); if (isExcluded(file)) return; if (myScope.belongsTo(new FilePathImpl(file))) { @@ -196,10 +192,6 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { } } - public boolean isUpdatingUnversionedFiles() { - return myUpdateUnversioned; - } - public boolean reportChangesOutsideProject() { return false; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VirtualFileHolder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VirtualFileHolder.java index de483f58930d..2218fdf83f76 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VirtualFileHolder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VirtualFileHolder.java @@ -20,7 +20,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.FilePathImpl; -import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vfs.VirtualFile; import java.util.*; @@ -49,16 +48,17 @@ public class VirtualFileHolder implements FileHolder { } // returns number of removed directories - static int cleanScope(final Project project, final Collection files, final VcsDirtyScope scope) { + static int cleanScope(final Project project, final Collection files, final VcsAppendableDirtyScope scope) { return ApplicationManager.getApplication().runReadAction(new Computable() { public Integer compute() { int result = 0; // to avoid deadlocks caused by incorrect lock ordering, need to lock on this after taking read action if (project.isDisposed() || files.isEmpty()) return 0; - final List currentFiles = new ArrayList(files); + if (scope.getRecursivelyDirtyDirectories().size() == 0) { final Set dirtyFiles = scope.getDirtyFiles(); - boolean cleanedDroppedFiles = false; + boolean cleanDroppedFiles = false; + for(FilePath dirtyFile: dirtyFiles) { VirtualFile f = dirtyFile.getVirtualFile(); if (f != null) { @@ -66,22 +66,30 @@ public class VirtualFileHolder implements FileHolder { if (f.isDirectory()) ++ result; } else { - if (!cleanedDroppedFiles) { - cleanedDroppedFiles = true; - for(VirtualFile file: currentFiles) { - if (fileDropped(project, file)) { - files.remove(file); - if (file.isDirectory()) ++ result; - } + cleanDroppedFiles = true; + } + + if (cleanDroppedFiles) { + for (Iterator iterator = files.iterator(); iterator.hasNext();) { + final VirtualFile file = iterator.next(); + if (fileDropped(file)) { + iterator.remove(); + scope.addDirtyFile(new FilePathImpl(file)); + if (file.isDirectory()) ++ result; } } } } } else { - for (VirtualFile file : currentFiles) { - if (fileDropped(project, file) || scope.belongsTo(new FilePathImpl(file))) { - files.remove(file); + for (Iterator iterator = files.iterator(); iterator.hasNext();) { + final VirtualFile file = iterator.next(); + final boolean fileDropped = fileDropped(file); + if (fileDropped) { + scope.addDirtyFile(new FilePathImpl(file)); + } + if (fileDropped || scope.belongsTo(new FilePathImpl(file))) { + iterator.remove(); if (file.isDirectory()) ++ result; } } @@ -91,12 +99,12 @@ public class VirtualFileHolder implements FileHolder { }); } - public void cleanScope(final VcsDirtyScope scope) { + public void cleanAndAdjustScope(final VcsAppendableDirtyScope scope) { myNumDirs -= cleanScope(myProject, myFiles, scope); } - private static boolean fileDropped(final Project project, final VirtualFile file) { - return !file.isValid() || ProjectLevelVcsManager.getInstance(project).getVcsFor(file) == null; + private static boolean fileDropped(final VirtualFile file) { + return ! file.isValid(); } public void addFile(VirtualFile file) { @@ -109,6 +117,7 @@ public class VirtualFileHolder implements FileHolder { if (file.isDirectory()) -- myNumDirs; } + // todo track number of copies made public List getFiles() { return new ArrayList(myFiles); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java index 50b9ff7866ce..c55fbc1f8c1d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java @@ -126,10 +126,6 @@ public class GatheringChangelistBuilder implements ChangelistBuilder { public void processRootSwitch(VirtualFile file, String branch) { } - public boolean isUpdatingUnversionedFiles() { - return false; - } - public boolean reportChangesOutsideProject() { return true; }