diff --git a/plugins/git4idea/src/git4idea/GitRootConverter.java b/plugins/git4idea/src/git4idea/GitRootConverter.java index 1e29fde47f51..862ea923ac68 100644 --- a/plugins/git4idea/src/git4idea/GitRootConverter.java +++ b/plugins/git4idea/src/git4idea/GitRootConverter.java @@ -21,40 +21,50 @@ import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.VcsDirectoryMapping; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.HashSet; -import git4idea.roots.GitRootDetectInfo; +import git4idea.repo.GitRepositoryManager; import git4idea.roots.GitRootDetector; +import git4idea.roots.GitRootsListener; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** * Given VFS content roots, filters them and returns only those, which are actual Git roots. */ -public class GitRootConverter implements AbstractVcs.RootsConvertor { +public class GitRootConverter implements AbstractVcs.RootsConvertor, GitRootsListener { @NotNull private final Project myProject; @NotNull private final PlatformFacade myPlatformFacade; + @Nullable private Collection myDetectedRoots; + public GitRootConverter(@NotNull Project project, @NotNull PlatformFacade facade) { myProject = project; myPlatformFacade = facade; + myProject.getMessageBus().connect().subscribe(GitRepositoryManager.GIT_ROOTS_CHANGE, this); } @NotNull public List convertRoots(@NotNull List result) { - GitRootDetectInfo detectInfo = new GitRootDetector(myProject, myPlatformFacade).detect(); + if (myDetectedRoots == null) { + myDetectedRoots = new GitRootDetector(myProject, myPlatformFacade).detect().getRoots(); + } ArrayList roots = new ArrayList(); if (hasProjectMapping()) { - roots.addAll(detectInfo.getRoots()); + roots.addAll(myDetectedRoots); } HashSet listed = new HashSet(); for (VirtualFile f : result) { VirtualFile r = GitUtil.gitRootOrNull(f); if (r != null && listed.add(r)) { - roots.add(r); + if (!roots.contains(r)) { + roots.add(r); + } } } return roots; @@ -69,4 +79,9 @@ public class GitRootConverter implements AbstractVcs.RootsConvertor { return false; } + @Override + public void gitRootsChanged(Collection roots) { + myDetectedRoots = roots; + } + } diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java index e75e8583e8d3..e1c95222d77b 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java @@ -16,6 +16,8 @@ package git4idea.repo; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.messages.Topic; +import git4idea.roots.GitRootsListener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,6 +29,8 @@ import java.util.List; */ public interface GitRepositoryManager { + Topic GIT_ROOTS_CHANGE = Topic.create("Git Roots change", GitRootsListener.class); + /** * Returns the {@link GitRepository} which tracks the Git repository located in the given directory, * or {@code null} if the given file is not a Git root known to this {@link com.intellij.openapi.project.Project}. diff --git a/plugins/git4idea/src/git4idea/roots/GitRootChecker.java b/plugins/git4idea/src/git4idea/roots/GitRootChecker.java index ec5e97cf4efe..bfd046344ea4 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootChecker.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootChecker.java @@ -35,7 +35,7 @@ public class GitRootChecker implements VcsRootChecker { private final boolean myProjectMappingIsInvalid; public GitRootChecker(@NotNull Project project, @NotNull PlatformFacade platformFacade) { - myErrors = new GitRootErrorsFinder(project, platformFacade).find(); + myErrors = new GitRootErrorsFinder(project, platformFacade).find(new GitRootDetector(project, platformFacade).detect()); myProjectMappingIsInvalid = isProjectMappingInvalid(); } diff --git a/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java b/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java index 8f68c17ef72f..1ca0ffb9053d 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java @@ -48,9 +48,9 @@ public class GitRootErrorsFinder { } @NotNull - public Collection find() { + public Collection find(@NotNull GitRootDetectInfo rootDetectInfo) { List mappings = myVcsManager.getDirectoryMappings(myVcs); - Collection gitRoots = new GitRootDetector(myProject, myPlatformFacade).detect().getRoots(); + Collection gitRoots = rootDetectInfo.getRoots(); Collection errors = new ArrayList(); Collection gitPaths = rootsToPaths(gitRoots); diff --git a/plugins/git4idea/src/git4idea/roots/GitRootProblemNotifier.java b/plugins/git4idea/src/git4idea/roots/GitRootProblemNotifier.java index 9f2d4bb17de3..13665681761e 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootProblemNotifier.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootProblemNotifier.java @@ -67,17 +67,19 @@ public class GitRootProblemNotifier { mySettings = VcsConfiguration.getInstance(myProject); } - public void rescanAndNotifyIfNeeded() { + public GitRootDetectInfo rescanAndNotifyIfNeeded() { + GitRootDetectInfo detectInfo = new GitRootDetector(myProject, myPlatformFacade).detect(); + if (!mySettings.SHOW_VCS_ERROR_NOTIFICATIONS) { - return; + return detectInfo; } - Collection errors = scan(); + Collection errors = scan(detectInfo); if (errors.isEmpty()) { synchronized (NOTIFICATION_LOCK) { expireNotification(); } - return; + return detectInfo; } Collection unregisteredRoots = getUnregisteredRoots(errors); @@ -89,9 +91,10 @@ public class GitRootProblemNotifier { synchronized (NOTIFICATION_LOCK) { expireNotification(); myNotification = createNotification(IMPORTANT_ERROR_NOTIFICATION, title, description, ERROR, - new MyNotificationListener(myProject, mySettings)); + new MyNotificationListener(myProject, mySettings, myPlatformFacade)); myPlatformFacade.getNotificator(myProject).notify(myNotification); } + return detectInfo; } private void expireNotification() { @@ -109,8 +112,8 @@ public class GitRootProblemNotifier { } @NotNull - private Collection scan() { - return new GitRootErrorsFinder(myProject, myPlatformFacade).find(); + private Collection scan(GitRootDetectInfo detectInfo) { + return new GitRootErrorsFinder(myProject, myPlatformFacade).find(detectInfo); } @SuppressWarnings("StringConcatenationInsideStringBufferAppend") @@ -195,10 +198,12 @@ public class GitRootProblemNotifier { @NotNull private final Project myProject; @NotNull private final VcsConfiguration mySettings; + @NotNull private final PlatformFacade myPlatformFacade; - private MyNotificationListener(@NotNull Project project, @NotNull VcsConfiguration settings) { + private MyNotificationListener(@NotNull Project project, @NotNull VcsConfiguration settings, @NotNull PlatformFacade facade) { myProject = project; mySettings = settings; + myPlatformFacade = facade; } @Override @@ -206,7 +211,8 @@ public class GitRootProblemNotifier { if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { if (event.getDescription().equals("configure")) { ShowSettingsUtil.getInstance().showSettingsDialog(myProject, ActionsBundle.message("group.VcsGroup.text")); - Collection errorsAfterPossibleFix = GitRootProblemNotifier.getInstance(myProject).scan(); + Collection errorsAfterPossibleFix = GitRootProblemNotifier.getInstance(myProject).scan( + new GitRootDetector(myProject, myPlatformFacade).detect()); if (errorsAfterPossibleFix.isEmpty() && !notification.isExpired()) { notification.expire(); } diff --git a/plugins/git4idea/src/git4idea/roots/GitRootScanner.java b/plugins/git4idea/src/git4idea/roots/GitRootScanner.java index 9c0c37bdffca..28846df88e02 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootScanner.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootScanner.java @@ -30,6 +30,7 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.util.messages.MessageBus; +import git4idea.repo.GitRepositoryManager; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -40,6 +41,7 @@ import java.util.List; */ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Disposable, VcsListener { + @NotNull private final Project myProject; @NotNull private final Runnable myExecuteAfterScan; @NotNull private final GitRootProblemNotifier myRootProblemNotifier; @@ -49,6 +51,7 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis @NotNull private final Object SCAN_LOCK = new Object(); public GitRootScanner(@NotNull Project project, @NotNull Runnable executeAfterScan) { + myProject = project; myExecuteAfterScan = executeAfterScan; StartupManager.getInstance(project).runWhenProjectIsInitialized(new DumbAwareRunnable() { @@ -129,7 +132,8 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis return; } myScanning = true; - myRootProblemNotifier.rescanAndNotifyIfNeeded(); + GitRootDetectInfo detectInfo = myRootProblemNotifier.rescanAndNotifyIfNeeded(); + myProject.getMessageBus().syncPublisher(GitRepositoryManager.GIT_ROOTS_CHANGE).gitRootsChanged(detectInfo.getRoots()); myExecuteAfterScan.run(); myScanning = false; } diff --git a/plugins/git4idea/src/git4idea/roots/GitRootsListener.java b/plugins/git4idea/src/git4idea/roots/GitRootsListener.java new file mode 100644 index 000000000000..62c07c802fcf --- /dev/null +++ b/plugins/git4idea/src/git4idea/roots/GitRootsListener.java @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2012 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 git4idea.roots; + +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.Collection; + +/** + * @author Kirill Likhodedov + */ +public interface GitRootsListener { + + void gitRootsChanged(Collection roots); + +} diff --git a/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy b/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy index cf002e7a74b6..74bffd57c458 100644 --- a/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy +++ b/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy @@ -172,7 +172,8 @@ class GitRootErrorsFinderTest extends AbstractGitRootTest { expected.addAll map.errors.unreg.collect { unreg(it) } expected.addAll map.errors.extra.collect { extra(it) } - Collection actual = new GitRootErrorsFinder(myProject, myPlatformFacade).find() + Collection actual = new GitRootErrorsFinder(myProject, myPlatformFacade).find( + new GitRootDetector(myProject, myPlatformFacade).detect()) assertEquals expected.toSet(), actual.toSet() }