diff --git a/platform/lang-api/src/com/intellij/openapi/project/ProjectUtil.java b/platform/lang-api/src/com/intellij/openapi/project/ProjectUtil.java index 20effd6324ea..dec2bfb9fdb1 100644 --- a/platform/lang-api/src/com/intellij/openapi/project/ProjectUtil.java +++ b/platform/lang-api/src/com/intellij/openapi/project/ProjectUtil.java @@ -21,14 +21,49 @@ package com.intellij.openapi.project; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFilePathWrapper; +import com.intellij.util.SystemProperties; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.File; +import java.io.IOException; + public class ProjectUtil { private ProjectUtil() { } + @Nullable + public static String getProjectLocationString(@NotNull final Project project) { + String projectPath = project.getLocation(); + return getLocationRelativeToUserHome(projectPath); + } + + @Nullable + public static String getLocationRelativeToUserHome(final String path) { + if (path == null) return null; + + String _path = path; + + if ((SystemInfo.isLinux || SystemInfo.isMac)) { + final File projectDir = new File(path); + final File userHomeDir = new File(SystemProperties.getUserHome()); + try { + if (FileUtil.isAncestor(userHomeDir, projectDir, true)) { + _path = "~/" + FileUtil.getRelativePath(userHomeDir, projectDir); + } + } + catch (IOException e) { + // nothing + } + } + + return _path; + } + public static String calcRelativeToProjectPath(final VirtualFile file, final Project project) { if (file instanceof VirtualFilePathWrapper) { return ((VirtualFilePathWrapper)file).getPresentablePath(); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java index c31486f261e7..841518078327 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java @@ -27,6 +27,7 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; @@ -81,7 +82,11 @@ public class PsiDirectoryNode extends BasePsiNode implements Navig } if (parentValue instanceof Project || parentValue instanceof Module) { - data.addText(" (" + directoryFile.getPresentableUrl() + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES); + if (parentValue instanceof Project) { + data.addText(" (" + ProjectUtil.getLocationRelativeToUserHome(directoryFile.getPresentableUrl()) + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES); + } else { + data.addText(" (" + directoryFile.getPresentableUrl() + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES); + } } else if (ProjectRootsUtil.isSourceOrTestRoot(directoryFile, project)) { if (ProjectRootsUtil.isInTestSource(directoryFile, project)) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/MultiRootSelfElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/MultiRootSelfElementInfo.java new file mode 100644 index 000000000000..77a650a565f8 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/MultiRootSelfElementInfo.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl.smartPointers; + +import com.intellij.lang.Language; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; + +/** + * User: cdr + */ +public class MultiRootSelfElementInfo extends SelfElementInfo { + private final Language myLanguage; + + public MultiRootSelfElementInfo(@NotNull Project project, + @NotNull TextRange anchor, + @NotNull Class anchorClass, + @NotNull PsiFile containingFile, + @NotNull Language language) { + super(project, anchor, anchorClass, containingFile); + myLanguage = language; + } + + @Override + protected PsiFile restoreFile() { + PsiFile mainRoot = super.restoreFile(); + if (mainRoot == null) return null; + return mainRoot.getViewProvider().getPsi(myLanguage); + } +} diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java index f347c6b0cd15..17d4f454f1c9 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java @@ -151,7 +151,7 @@ public class SelfElementInfo implements SmartPointerElementInfo { public PsiElement restoreElement() { if (!mySyncMarkerIsValid) return null; - PsiFile file = restoreFileFromVirtual(myVirtualFile, myProject); + PsiFile file = restoreFile(); if (file == null || !file.isValid()) return null; final int syncStartOffset = getSyncStartOffset(); @@ -160,6 +160,10 @@ public class SelfElementInfo implements SmartPointerElementInfo { return findElementInside(file, syncStartOffset, syncEndOffset, myType); } + protected PsiFile restoreFile() { + return restoreFileFromVirtual(myVirtualFile, myProject); + } + protected static PsiElement findElementInside(PsiFile file, int syncStartOffset, int syncEndOffset, Class type) { PsiElement anchor = file.getViewProvider().findElementAt(syncStartOffset, file.getLanguage()); if (anchor == null) return null; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java index 7401a1664a07..09eb11b42a5b 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java @@ -164,6 +164,12 @@ class SmartPsiElementPointerImpl implements SmartPointerEx LOG.assertTrue(element.isPhysical()); LOG.assertTrue(element.isValid()); + boolean isMultiRoot = viewProvider.getAllFiles().size() > 1; + VirtualFile virtualFile = containingFile.getVirtualFile(); + boolean isElementInMainRoot = virtualFile == null || containingFile.getManager().findFile(virtualFile) == containingFile; + if (isMultiRoot && !isElementInMainRoot) { + return new MultiRootSelfElementInfo(project, element.getTextRange(), element.getClass(), containingFile, containingFile.getLanguage()); + } return new SelfElementInfo(project, element.getTextRange(), element.getClass(), containingFile); } diff --git a/platform/platform-api/src/com/intellij/openapi/progress/Task.java b/platform/platform-api/src/com/intellij/openapi/progress/Task.java index 9aacc6a03b8a..b956b48c3c33 100644 --- a/platform/platform-api/src/com/intellij/openapi/progress/Task.java +++ b/platform/platform-api/src/com/intellij/openapi/progress/Task.java @@ -17,10 +17,13 @@ package com.intellij.openapi.progress; import com.intellij.CommonBundle; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbModeAction; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import sun.util.LocaleServiceProviderPool; /** * Intended to run tasks, both modal and non-modal (backgroundable) @@ -39,7 +42,7 @@ import org.jetbrains.annotations.Nullable; * @see com.intellij.openapi.progress.ProgressManager#run(Task) */ public abstract class Task implements TaskInfo, Progressive { - + private final static Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.Task"); protected final Project myProject; protected String myTitle; private final boolean myCanBeCancelled; @@ -134,6 +137,9 @@ public abstract class Task implements TaskInfo, Progressive { public Backgroundable(@Nullable final Project project, @NotNull final String title, final boolean canBeCancelled, @Nullable final PerformInBackgroundOption backgroundOption) { super(project, title, canBeCancelled); myBackgroundOption = backgroundOption; + if (StringUtil.isEmptyOrSpaces(title)) { + LOG.warn("Empty title for backgroundable task.", new Throwable()); + } } public Backgroundable(@Nullable final Project project, @NotNull final String title, final boolean canBeCancelled) { diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java b/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java index 7c50d43de762..8f052e97839d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java @@ -27,6 +27,7 @@ import com.intellij.openapi.util.Getter; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.PairConsumer; +import com.intellij.util.PlusMinus; import com.intellij.util.concurrency.QueueProcessor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,21 +42,24 @@ import org.jetbrains.annotations.Nullable; */ @SomeQueue public class BackgroundTaskQueue { + private final static String ourMonitorFlag = "monitor.background.queue.load"; private static final Logger LOG = Logger.getInstance(BackgroundTaskQueue.class.getName()); //private final Project myProject; private final QueueProcessor>> myProcessor; private Boolean myForcedTestMode; + private final PlusMinus myMonitor; public BackgroundTaskQueue(@Nullable Project project, @NotNull String title) { this(project, title, null); } public BackgroundTaskQueue(@Nullable final Project project, @NotNull String title, final Boolean forcedHeadlessMode) { + myMonitor = Boolean.TRUE.equals(Boolean.getBoolean(ourMonitorFlag)) ? new BackgroundTasksMonitor(title) : new PlusMinus.Empty(); final boolean headless = forcedHeadlessMode != null ? forcedHeadlessMode : ApplicationManager.getApplication().isHeadlessEnvironment(); final QueueProcessor.ThreadToUse threadToUse = headless ? QueueProcessor.ThreadToUse.POOLED : QueueProcessor.ThreadToUse.AWT; final PairConsumer>, Runnable> consumer - = headless ? new BackgroundableHeadlessRunner() : new BackgroundableUnderProgressRunner(title, project); + = headless ? new BackgroundableHeadlessRunner() : new BackgroundableUnderProgressRunner(title, project, myMonitor); myProcessor = new QueueProcessor>>(consumer, true, threadToUse, new Condition() { @@ -83,6 +87,7 @@ public class BackgroundTaskQueue { } public void run(Task.Backgroundable task, final ModalityState state, final Getter pi) { + myMonitor.plus(task.getTitle()); if (isTestMode()) { // test tasks are executed in this thread without the progress manager RunBackgroundable.runIfBackgroundThread(task, new EmptyProgressIndicator(), null); } else { @@ -103,14 +108,17 @@ public class BackgroundTaskQueue { private static class BackgroundableUnderProgressRunner implements PairConsumer>, Runnable> { private final String myTitle; private final Project myProject; + private final PlusMinus myMonitor; - public BackgroundableUnderProgressRunner(String title, final Project project) { + public BackgroundableUnderProgressRunner(String title, final Project project, PlusMinus monitor) { myTitle = title; myProject = project; + myMonitor = monitor; } @Override public void consume(final Pair> pair, final Runnable runnable) { + myMonitor.minus(pair.getFirst().getTitle()); final Task.Backgroundable backgroundable = pair.getFirst(); final ProgressIndicator[] pi = new ProgressIndicator[1]; final boolean taskTitleIsEmpty = StringUtil.isEmptyOrSpaces(backgroundable.getTitle()); @@ -133,11 +141,11 @@ public class BackgroundTaskQueue { pi[0] = pair.getSecond().get(); } if (pi[0] == null) { + if (taskTitleIsEmpty) { + backgroundable.setTitle(myTitle); + } pi[0] = new BackgroundableProcessIndicator(backgroundable); } - if (taskTitleIsEmpty) { - ((BackgroundableProcessIndicator) pi[0]).setTitle(myTitle); - } ProgressManagerImpl.runProcessWithProgressAsynchronously(backgroundable, pi[0], runnable); } diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTasksMonitor.java b/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTasksMonitor.java new file mode 100644 index 000000000000..ab1040eb3f7e --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTasksMonitor.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.progress; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.PlusMinus; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author irengrig + * Date: 4/13/11 + * Time: 5:32 PM + */ +public class BackgroundTasksMonitor implements PlusMinus { + private final static Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.BackgroundTasksMonitor"); + private static final long ourStatInterval = 300000; + private long myRecentTime; + private final Map myMap; + private final Map myMaxMap; + private final Object myLock; + private final String myQueueTitle; + + public BackgroundTasksMonitor(final String queueTitle) { + myQueueTitle = queueTitle; + myMap = new HashMap(); + myMaxMap = new HashMap(); + myLock = new Object(); + myRecentTime = 0; + } + + @Override + public void plus(String title) { + synchronized (myLock) { + final Integer previous = myMap.get(title); + final int newVal = previous == null ? 1 : (previous + 1); + myMap.put(title, newVal); + final Integer max = myMaxMap.get(title); + if (max == null || max < newVal) { + myMaxMap.put(title, newVal); + } + reportStatistics(); + } + } + + + @Override + public void minus(String title) { + synchronized (myLock) { + final Integer integer = myMap.get(title); + assert integer != null; + if (integer == 1) { + myMap.remove(title); + } else { + myMap.put(title, integer - 1); + } + reportStatistics(); + } + } + + private void reportStatistics() { + final long time = System.currentTimeMillis(); + if (time - ourStatInterval < myRecentTime) return; + final StringBuilder sb = new StringBuilder("BackgroundTaskQueue '" + myQueueTitle + "' usage statistics\n"); + sb.append("----------------------------------------------------\n"); + sb.append("Current Values:"); + for (Map.Entry entry : myMap.entrySet()) { + sb.append(entry.getKey()).append(": ").append(entry.getValue()); + } + sb.append("\nMaximum Values:"); + for (Map.Entry entry : myMaxMap.entrySet()) { + sb.append('\n').append(entry.getKey()).append(": ").append(entry.getValue()); + } + sb.append("----------------------------------------------------\n"); + LOG.info(sb.toString()); + myRecentTime = time; + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/PlatformFrameTitleBuilder.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/PlatformFrameTitleBuilder.java index 831969c7a75b..a4a23b5732fc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/PlatformFrameTitleBuilder.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/PlatformFrameTitleBuilder.java @@ -16,6 +16,7 @@ package com.intellij.openapi.wm.impl; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFilePathWrapper; import com.intellij.platform.ProjectBaseDirectory; @@ -27,7 +28,7 @@ public class PlatformFrameTitleBuilder extends FrameTitleBuilder { public String getProjectTitle(final Project project) { final VirtualFile baseDir = project.getBaseDir(); if (baseDir != null) { - return project.getName() + " - [" + baseDir.getPresentableUrl() + "]"; + return project.getName() + " - [" + ProjectUtil.getLocationRelativeToUserHome(baseDir.getPresentableUrl()) + "]"; } return project.getName(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PlusMinus.java b/platform/util/src/com/intellij/util/PlusMinus.java similarity index 79% rename from platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PlusMinus.java rename to platform/util/src/com/intellij/util/PlusMinus.java index 47779e91da9e..7971dfd2f19e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PlusMinus.java +++ b/platform/util/src/com/intellij/util/PlusMinus.java @@ -13,9 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.vcs.changes; +package com.intellij.util; public interface PlusMinus { + class Empty implements PlusMinus { + @Override + public void plus(T t) { + } + @Override + public void minus(T t) { + } + } + void plus(final T t); void minus(final T t); } 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 0517740f2f0c..5e73e2795f4a 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 @@ -44,10 +44,7 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.EditorNotifications; -import com.intellij.util.ConcurrencyUtil; -import com.intellij.util.Consumer; -import com.intellij.util.EventDispatcher; -import com.intellij.util.NullableFunction; +import com.intellij.util.*; import com.intellij.util.containers.MultiMap; import com.intellij.util.messages.Topic; import com.intellij.vcsUtil.Rethrow; 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 2236cd0fd2cd..10f9b4893c29 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 @@ -23,6 +23,7 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.PlusMinus; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java index fcb32c5f88d6..5106db481e47 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java @@ -20,7 +20,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsKey; -import com.intellij.openapi.vcs.impl.CollectionsDelta; +import com.intellij.util.PlusMinus; import java.util.Collection; import java.util.HashSet; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesOnServerTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesOnServerTracker.java index 3690ba3ee9cd..519a251de0bb 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesOnServerTracker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesOnServerTracker.java @@ -19,6 +19,7 @@ import com.intellij.lifecycle.AtomicSectionsAware; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.VcsListener; +import com.intellij.util.PlusMinus; import java.util.Collection; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java index 4d7be3aeefe9..73c70c4a9fb5 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java @@ -30,6 +30,7 @@ import com.intellij.openapi.vcs.impl.VcsInitObject; import com.intellij.openapi.vcs.update.UpdateFilesHelper; import com.intellij.openapi.vcs.update.UpdatedFiles; import com.intellij.util.Consumer; +import com.intellij.util.PlusMinus; import com.intellij.util.messages.Topic; import java.util.Collection; diff --git a/plugins/git4idea/src/git4idea/branch/GitBranches.java b/plugins/git4idea/src/git4idea/branch/GitBranches.java index 9c576cdfb290..f8d2760a029a 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBranches.java +++ b/plugins/git4idea/src/git4idea/branch/GitBranches.java @@ -38,6 +38,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; /** * Container and tracker of git branches information. @@ -55,11 +56,13 @@ public class GitBranches implements GitReferenceListener { private final Object myCurrentBranchesLock = new Object(); private ChangeListManager myChangeListManager; private GitVcs myVcs; + private final AtomicBoolean mySoleUseControl; public GitBranches(Project project, ChangeListManager changeListManager, ProjectLevelVcsManager vcsManager) { myProject = project; myChangeListManager = changeListManager; myVcsManager = vcsManager; + mySoleUseControl = new AtomicBoolean(false); } public static GitBranches getInstance(Project project) { @@ -121,8 +124,10 @@ public class GitBranches implements GitReferenceListener { return; } - final Task.Backgroundable task = new Task.Backgroundable(myProject, "") { + final Task.Backgroundable task = new Task.Backgroundable(myProject, "Git: refresh current branch") { @Override public void run(@NotNull ProgressIndicator indicator) { + assert ! mySoleUseControl.get(); + mySoleUseControl.set(true); try { GitBranch currentBranch = GitBranch.current(myProject, root); synchronized (myCurrentBranchesLock) { @@ -132,6 +137,8 @@ public class GitBranches implements GitReferenceListener { } catch (VcsException e) { LOG.info("Exception while trying to get current branch for root " + root, e); // doing nothing - null will be set to myCurrentBranchName + } finally { + mySoleUseControl.set(false); } } }; @@ -140,8 +147,11 @@ public class GitBranches implements GitReferenceListener { private void fullyUpdateBranchesInfo(final Collection roots) { if (roots == null) { return; } - final Task.Backgroundable task = new Task.Backgroundable(myProject, "") { + final Task.Backgroundable task = new Task.Backgroundable(myProject, "Git: refresh current branches") { @Override public void run(@NotNull ProgressIndicator indicator) { + assert ! mySoleUseControl.get(); + mySoleUseControl.set(true); + try { Map currentBranches = new HashMap(); for (VirtualFile root : roots) { try { @@ -156,6 +166,9 @@ public class GitBranches implements GitReferenceListener { synchronized (myCurrentBranchesLock) { myCurrentBranches = currentBranches; } + } finally { + mySoleUseControl.set(false); + } } }; GitVcs.runInBackground(task);