VirtualFile (@NotNull Project project, @NotNull VirtualFile file) { ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); // For a file inside .jar/.zip, check VCS for the .jar/.zip file itself VirtualFile root = vcsManager.getVcsRootFor(VfsUtilCore.getVirtualFileForJar(file)); if (root != null) { LOG.debug("Found root for zip/jar file: " + root); return root; } // For libraries, check VCS for the owner module List<OrderEntry> entries = ProjectRootManager.getInstance(project).getFileIndex().getOrderEntriesForFile(file); Set<VirtualFile> modulesVcsRoots = new HashSet<>(); for (OrderEntry entry : entries) { if (entry instanceof LibraryOrderEntry || entry instanceof JdkOrderEntry) { VirtualFile moduleVcsRoot = vcsManager.getVcsRootFor(entry.getOwnerModule().getModuleFile()); if (moduleVcsRoot != null) { modulesVcsRoots.add(moduleVcsRoot); } } } if (modulesVcsRoots.isEmpty()) { LOG.debug("No library roots"); return null; } // If the lib is used in several modules under different VCS roots, take the topmost one. // For modules not sharing ancestry, we can't guess anything => take the first one. VirtualFile topRoot = null; for (VirtualFile vcsRoot : modulesVcsRoots) { if (topRoot == null || VfsUtilCore.isAncestor(vcsRoot, topRoot, true)) { topRoot = vcsRoot; } } LOG.debug("Several library roots, returning " + topRoot); return topRoot; }