From 52eb927cd657f62ec2d78fcd9509e3cf91f8aeda Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 2 Mar 2020 16:39:42 +0300 Subject: [PATCH] vcs: skip ignored directories in VcsRootScanner listener GitOrigin-RevId: 6e9ac9d26b12127c20f7a4bbe3707b428480ee53 --- .../vcs/roots/VcsRootDetectorImpl.java | 35 ++-------------- .../openapi/vcs/roots/VcsRootScanner.java | 42 +++++++++++++++++-- 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java index 263dfc235a8e..2771cf9ea208 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java @@ -5,7 +5,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsRoot; @@ -16,12 +15,12 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; import static com.intellij.openapi.vfs.VirtualFileVisitor.CONTINUE; -import static com.intellij.openapi.vfs.VirtualFileVisitor.SKIP_CHILDREN; public class VcsRootDetectorImpl implements VcsRootDetector { private static final Logger LOG = Logger.getInstance(VcsRootDetectorImpl.class); @@ -29,19 +28,6 @@ public class VcsRootDetectorImpl implements VcsRootDetector { @NotNull private final Project myProject; @NotNull private final ProjectLevelVcsManager myVcsManager; - private final Pattern myIgnorePattern = parseIgnorePattern(); - - @NotNull - private static Pattern parseIgnorePattern() { - try { - return Pattern.compile(Registry.stringValue("vcs.root.detector.ignore.pattern")); - } - catch (MissingResourceException | PatternSyntaxException e) { - LOG.warn(e); - return Pattern.compile(".{0}"); // match nothing - } - } - @Nullable private Collection myDetectedRoots; @NotNull private final Object LOCK = new Object(); @@ -114,7 +100,6 @@ public class VcsRootDetectorImpl implements VcsRootDetector { private Set scanForRootsInsideDir(@NotNull VirtualFile root) { Set roots = new HashSet<>(); VcsRootScanner.visitDirsRecursivelyWithoutExcluded(myProject, ProjectRootManager.getInstance(myProject), root, dir -> { - if (isIgnoredDirectory(dir)) return SKIP_CHILDREN; VcsRoot vcsRoot = getVcsRootFor(dir); if (vcsRoot != null) { LOG.debug("Found VCS " + vcsRoot.getVcs() + " in " + vcsRoot.getPath()); @@ -129,18 +114,6 @@ public class VcsRootDetectorImpl implements VcsRootDetector { return rootsInsideDir.stream().noneMatch(it -> startDir.equals(it.getPath())); } - private boolean isIgnoredDirectory(@NotNull VirtualFile dir) { - if (myVcsManager.isIgnored(dir)) { - LOG.debug("Skipping ignored dir: ", dir); - return true; - } - if (myIgnorePattern.matcher(dir.getName()).matches()) { - LOG.debug("Skipping dir by pattern: ", dir); - return true; - } - return false; - } - @Nullable private VcsRoot scanForSingleRootAboveDir(@NotNull final VirtualFile dir) { if (myProject.isDisposed()) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootScanner.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootScanner.java index aba3849f78e3..209075b678e8 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootScanner.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootScanner.java @@ -16,12 +16,14 @@ package com.intellij.openapi.vcs.roots; import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.util.BackgroundTaskUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsRootChecker; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; @@ -31,14 +33,20 @@ import com.intellij.util.Alarm; import com.intellij.vfs.AsyncVfsEventsListener; import com.intellij.vfs.AsyncVfsEventsPostProcessor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.MissingResourceException; import java.util.concurrent.TimeUnit; import java.util.function.Function; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import static com.intellij.openapi.diagnostic.Logger.getInstance; import static com.intellij.openapi.vfs.VirtualFileVisitor.*; public class VcsRootScanner implements AsyncVfsEventsListener { + private static final Logger LOG = getInstance(VcsRootScanner.class); @NotNull private final VcsRootProblemNotifier myRootProblemNotifier; @NotNull private final Project myProject; @@ -85,6 +93,7 @@ public class VcsRootScanner implements AsyncVfsEventsListener { @NotNull Function dirFound) { ProjectFileIndex fileIndex = projectRootManager.getFileIndex(); Option depthLimit = limit(Registry.intValue("vcs.root.detector.folder.depth")); + Pattern ignorePattern = parseDirIgnorePattern(); VfsUtilCore.visitChildrenRecursively(root, new VirtualFileVisitor(NO_FOLLOW_SYMLINKS, depthLimit) { @NotNull @Override @@ -94,6 +103,10 @@ public class VcsRootScanner implements AsyncVfsEventsListener { return CONTINUE; } + if (isIgnoredDirectory(project, ignorePattern, file)) { + return SKIP_CHILDREN; + } + VirtualFileVisitor.Result result = dirFound.apply(file); if (result != CONTINUE) { return result; @@ -118,8 +131,31 @@ public class VcsRootScanner implements AsyncVfsEventsListener { } myAlarm.cancelAllRequests(); // one scan is enough, no need to queue, they all do the same - myAlarm.addRequest(() -> - BackgroundTaskUtil.runUnderDisposeAwareIndicator(myAlarm, () -> - myRootProblemNotifier.rescanAndNotifyIfNeeded()), WAIT_BEFORE_SCAN); + myAlarm.addRequest(() -> BackgroundTaskUtil.runUnderDisposeAwareIndicator(myAlarm, () -> + myRootProblemNotifier.rescanAndNotifyIfNeeded()), WAIT_BEFORE_SCAN); + } + + + private static boolean isIgnoredDirectory(@NotNull Project project, @Nullable Pattern ignorePattern, @NotNull VirtualFile dir) { + if (ProjectLevelVcsManager.getInstance(project).isIgnored(dir)) { + LOG.debug("Skipping ignored dir: ", dir); + return true; + } + if (ignorePattern != null && ignorePattern.matcher(dir.getName()).matches()) { + LOG.debug("Skipping dir by pattern: ", dir); + return true; + } + return false; + } + + @Nullable + private static Pattern parseDirIgnorePattern() { + try { + return Pattern.compile(Registry.stringValue("vcs.root.detector.ignore.pattern")); + } + catch (MissingResourceException | PatternSyntaxException e) { + LOG.warn(e); + return null; + } } }