From 3d6f3140e277445db6b77dee6f0a5971556e5f3d Mon Sep 17 00:00:00 2001 From: Noah S-C Date: Thu, 23 Nov 2023 12:10:31 +0000 Subject: [PATCH] Handle race between querying for VCS repositories and them being loaded by IntelliJ (#110) Context: * https://sourcegraph.slack.com/archives/C059N5FRYG3/p1699545417832259?thread_ts=1699461891.240879&cid=C059N5FRYG3 * https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000667650-Ensure-initialization-of-GitRepositoryManager-before-doing-plugin-operation * https://intellij-support.jetbrains.com/hc/en-us/community/posts/206105769-Get-project-git-repositories-in-a-project-component --- .../java/com/sourcegraph/vcs/RepoUtil.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/sourcegraph/vcs/RepoUtil.java b/src/main/java/com/sourcegraph/vcs/RepoUtil.java index 33a33f0dd0..f02610cfc0 100644 --- a/src/main/java/com/sourcegraph/vcs/RepoUtil.java +++ b/src/main/java/com/sourcegraph/vcs/RepoUtil.java @@ -4,6 +4,7 @@ import com.intellij.dvcs.repo.VcsRepositoryManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.vcsUtil.VcsUtil; import com.sourcegraph.cody.agent.CodyAgent; @@ -223,11 +224,22 @@ public static VCSType getVcsType(@NotNull Project project, @NotNull VirtualFile } private static Optional getRootFileFromFirstGitRepository(@NotNull Project project) { + // https://intellij-support.jetbrains.com/hc/en-us/community/posts/206105769/comments/206091565 + Object lock = new Object(); + ProjectLevelVcsManager.getInstance(project) + .runAfterInitialization( + () -> { + synchronized (lock) { + lock.notify(); + } + }); + synchronized (lock) { + try { + lock.wait(); + } catch (InterruptedException ignored) { + } + } Optional firstFoundRepository = - // NOTE(olafurpg): getRepositories() returns an empty stream in most cases. I made multiple - // failed attempts to infer the repository from a project. Ideally, we should just persist - // the codebase per project so that we only have to wait until the user has opened a file - // once for any given project. VcsRepositoryManager.getInstance(project).getRepositories().stream() .filter(it -> it.getVcs().getName().equals(GitVcs.NAME)) .findFirst();