diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsRootChecker.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsRootChecker.java index 4c0ea7acc797..a151cfbe7f61 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsRootChecker.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsRootChecker.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.vcs; import com.intellij.openapi.diagnostic.Logger; @@ -100,11 +100,12 @@ public abstract class VcsRootChecker { * @param mappedDirs - roots that have an explicit mappings, and should not be included into detection * @return Detected vcs root mappings for the project * or null if default logic should be used instead (relying on {@link #isRoot} calls). + * @throws VcsException - when detection of project mappings failed (e.g., no internet connection for VCSs that require it). */ @Nullable public Collection detectProjectMappings(@NotNull Project project, @NotNull Collection projectRoots, - @NotNull Set mappedDirs) { + @NotNull Set mappedDirs) throws VcsException { return null; } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleVcsDetector.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleVcsDetector.kt index 21db9bfee7f3..d8be80fdac34 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleVcsDetector.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleVcsDetector.kt @@ -8,6 +8,7 @@ import com.intellij.openapi.extensions.ExtensionNotApplicableException import com.intellij.openapi.project.Project import com.intellij.openapi.vcs.AbstractVcs import com.intellij.openapi.vcs.VcsDirectoryMapping +import com.intellij.openapi.vcs.VcsException import com.intellij.openapi.vcs.VcsRootChecker import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx.MAPPING_DETECTION_LOG import com.intellij.openapi.vfs.VirtualFile @@ -69,7 +70,13 @@ internal class ModuleVcsDetector(private val project: Project) { val directMappings = detectedRoots.map { it.first }.toMutableSet() for (rootChecker in VcsRootChecker.EXTENSION_POINT_NAME.extensionList) { val vcs = vcsManager.findVcsByName(rootChecker.supportedVcs.name) ?: continue - val detectedMappings = rootChecker.detectProjectMappings(project, contentRoots, directMappings) ?: continue + val detectedMappings = try { + rootChecker.detectProjectMappings(project, contentRoots, directMappings) ?: continue + } + catch (e: VcsException) { + MAPPING_DETECTION_LOG.debug("ModuleVcsDetector.autoDetectForContentRoots - exception while detecting mapping", e) + continue + } if (detectedMappings.isEmpty()) continue usedVcses.add(vcs) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java index 7a0e92acd904..c98d68c546fb 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java @@ -263,18 +263,16 @@ public final class NewMappings implements Disposable { private void updateMappedRoots(boolean fireMappingsChangedEvent) { myRootUpdateQueue.cancelAllUpdates(); - if (!myActivated) return; - LOG.debug("updateMappedRoots"); - - List mappings = myMappings; - Mappings newMappedRoots = collectMappedRoots(mappings, null); - - setNewMappedRoots(mappings, newMappedRoots, fireMappingsChangedEvent); + updateMappedRootsImpl(fireMappingsChangedEvent, false); } private void updateMappedRootsFast(boolean fireMappingsChangedEvent) { + updateMappedRootsImpl(fireMappingsChangedEvent, true); + } + + private void updateMappedRootsImpl(boolean fireMappingsChangedEvent, boolean onlyFastUpdate) { if (!myActivated) return; - LOG.debug("updateMappedRootsFast"); + LOG.debug("updateMappedRoots: fastUpdate = " + onlyFastUpdate); List mappings; List mappedRoots; @@ -285,7 +283,7 @@ public final class NewMappings implements Disposable { if (mappedRoots.isEmpty()) { mappedRoots = getCachedMappedRootsIfNeeded(mappings); } - Mappings newMappedRoots = collectMappedRoots(mappings, mappedRoots); + Mappings newMappedRoots = collectMappedRoots(mappings, mappedRoots, onlyFastUpdate); setNewMappedRoots(mappings, newMappedRoots, fireMappingsChangedEvent); } @@ -396,7 +394,8 @@ public final class NewMappings implements Disposable { } private @NotNull Mappings collectMappedRoots(@NotNull List mappings, - @Nullable List reuseMappedRoots) { + @NotNull List reuseMappedRoots, + boolean onlyFastUpdate) { Map mappedRoots = new HashMap<>(); Disposable pointerDisposable = Disposer.newDisposable(); @@ -426,15 +425,21 @@ public final class NewMappings implements Disposable { } List defaultMappings; - if (reuseMappedRoots != null) { + if (onlyFastUpdate) { defaultMappings = reuseDefaultMappingsFrom(mapping, reuseMappedRoots, pointerDisposable); } else { Set directMappingDirs = ContainerUtil.map2Set(mappedRoots.values(), it -> it.root); - defaultMappings = findDefaultMappingsFor(mapping, directMappingDirs, pointerDisposable); + try { + defaultMappings = findDefaultMappingsFor(mapping, directMappingDirs, pointerDisposable); - VcsDirectoryMappingCache.getInstance(myProject).setMappings(mapping.getVcs(), - ContainerUtil.map(defaultMappings, it -> it.root.getPath())); + VcsDirectoryMappingCache.getInstance(myProject).setMappings(mapping.getVcs(), + ContainerUtil.map(defaultMappings, it -> it.root.getPath())); + } + catch (VcsException e) { + LOG.warn("Cannot find default mappings for " + mapping.getVcs(), e); + defaultMappings = reuseDefaultMappingsFrom(mapping, reuseMappedRoots, pointerDisposable); + } } for (MappedRoot mappedRoot : defaultMappings) { mappedRoots.putIfAbsent(mappedRoot.root, mappedRoot); @@ -484,7 +489,7 @@ public final class NewMappings implements Disposable { @NotNull private List findDefaultMappingsFor(@NotNull VcsDirectoryMapping mapping, @NotNull Set directMappingDirs, - @NotNull Disposable pointerDisposable) { + @NotNull Disposable pointerDisposable) throws VcsException { AbstractVcs vcs = getMappingsVcs(mapping); if (vcs == null) { return Collections.emptyList(); @@ -549,7 +554,7 @@ public final class NewMappings implements Disposable { private @NotNull Collection detectDefaultRootsFor(@NotNull AbstractVcs vcs, @NotNull Collection projectRoots, - @NotNull Set mappedDirs) { + @NotNull Set mappedDirs) throws VcsException { try { if (vcs.needsLegacyDefaultMappings()) return projectRoots; @@ -560,7 +565,7 @@ public final class NewMappings implements Disposable { return VcsDefaultMappingUtils.detectProjectMappings(myProject, rootChecker, projectRoots, mappedDirs); } - catch (ProcessCanceledException e) { + catch (ProcessCanceledException | VcsException e) { throw e; } catch (Throwable e) {