diff --git a/plugins/git4idea/src/git4idea/roots/GitRootDetector.java b/plugins/git4idea/src/git4idea/roots/GitRootDetector.java index 22566b1aecb4..4c9df519ec33 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootDetector.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootDetector.java @@ -16,14 +16,14 @@ package git4idea.roots; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Processor; import git4idea.PlatformFacade; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; /** *

@@ -86,20 +86,30 @@ public class GitRootDetector { } @NotNull - private static Set scanForRootsInsideDir(@NotNull VirtualFile projectDir) { - final Set roots = new HashSet(); - VfsUtil.processFilesRecursively(projectDir, new Processor() { - @Override - public boolean process(VirtualFile virtualFile) { - if (virtualFile.isDirectory() && hasGitDir(virtualFile)) { - roots.add(virtualFile); - } - return true; - } - }); + private static Set scanForRootsInsideDir(@NotNull VirtualFile dir, int depth) { + Set roots = new HashSet(); + if (depth > 2) { + // performance optimization via limitation: don't scan deep though the whole VFS, 2 levels under a content root is enough + return roots; + } + if (!dir.isDirectory()) { + return roots; + } + + if (hasGitDir(dir)) { + roots.add(dir); + } + for (VirtualFile child: dir.getChildren()) { + roots.addAll(scanForRootsInsideDir(child, depth + 1)); + } return roots; } + @NotNull + private static Set scanForRootsInsideDir(@NotNull VirtualFile projectDir) { + return scanForRootsInsideDir(projectDir, 0); + } + @Nullable private static VirtualFile scanForSingleRootAboveDir(@NotNull VirtualFile projectDir) { VirtualFile parent = projectDir.getParent(); diff --git a/plugins/git4idea/tests/git4idea/roots/GitRootDetectorTest.groovy b/plugins/git4idea/tests/git4idea/roots/GitRootDetectorTest.groovy index dd46e89acb6e..fc8d15dd262a 100644 --- a/plugins/git4idea/tests/git4idea/roots/GitRootDetectorTest.groovy +++ b/plugins/git4idea/tests/git4idea/roots/GitRootDetectorTest.groovy @@ -145,6 +145,16 @@ class GitRootDetectorTest extends AbstractGitRootTest { below: false } + @Test + // This is a test of performance optimization via limitation: don't scan deep though the whole VFS + void "don't scan deeper than 2 levels below a content root"() { + doTest linked_roots: ["content_root"], + gits: ["community", "content_root/lev1/lev2", "content_root2/lev1/lev2/lev3"], + expected: ["community", "content_root/lev1/lev2"], + full: false, + below: false + } + /** * Perform test. Map contains actual Git repositories to be created on disk, * and Git repositories expected to be detected by the GitRootDetector.