Cursor 索引一直跑不完

索引进度条转了几个小时没动——多半是仓库太大、ignore 配置错、symlink 环、或工作目录权限不足。

Settings → Features → Codebase Indexing 顶上写 “Indexing… 3,432 of 1,200,000 files”,半小时后再看还是这个数;或者干脆 spinner 转个不停永远 0%。Cursor 索引死循环的最常见原因不是 bug,而是 .cursorignore 没有覆盖 node_modules / build 产物,本地有 100 万个生成文件的入口被纳入扫描;其次是 symlink 环、网络盘、权限问题。

修法是先看清在 chunk 哪一类文件上卡住,再针对性排除。

常见原因

1. node_modules / dist / .next / build 没被排除

Cursor 默认尊重 .gitignore,但很多团队的 .gitignore 里有 node_modules 但忘了 dist/coverage/.next/.turbo/__pycache__/venv/。一个 Next.js monorepo 的 .next/cache/webpack 一项就能 50 万文件。

如何判断

git status --ignored | head -20
du -sh node_modules .next dist build coverage 2>/dev/null | sort -h

哪个目录最大 + 不在 gitignore,就是嫌疑。

packages/web/node_modules/internal-pkg -> ../../shared,shared 再 symlink 回去,扫描会无限递归。

如何判断

find . -type l 2>/dev/null | head -20

看任何指向上级目录的 symlink。

3. 仓库整体超出 Cursor 默认上限

Cursor 单仓库索引上限大约 1 万-50 万文件(按订阅档),超出后要么静默放弃、要么无限重试。Monorepo 实际 LOC 全算上很容易超。

如何判断

git ls-files | wc -l       # tracked
find . -type f | wc -l     # 全部,含 ignored

如果第二条 > 100k,就是超规模。

4. 权限不足

某个目录是 root owner(系统目录、Docker volume)、Cursor 进程读不进去。索引器死等。

如何判断

find . -not -readable 2>/dev/null | head

5. 网络盘 / WSL 跨边界

项目在 SMB/NFS/Dropbox/iCloud sync 上,文件读写延迟到 100ms+,索引器吞吐降两个数量级。

如何判断df -h . 看挂载类型;或路径是 /mnt/c/...~/Library/Mobile Documents/...

6. Cursor 自身索引服务 hung

extension host 崩了、index worker 进程死了,但 UI 不更新。

如何判断:Cmd+Shift+P → “Developer: Show Running Extensions”,Cursor 自家扩展 / index worker 显示 unresponsive。

动手前先确认

  • 确认是这一个仓库的问题,还是所有仓库都索引不动;后者多半是 Cursor 安装或账号问题。
  • 复现前先 commit 一次 .cursorignore,避免改完没法回滚。
  • 记下 Cursor 版本、仓库总文件数、操作系统、订阅档。

需要收集的信息

  • Cursor 版本、订阅档(Hobby / Pro / Business)。
  • git ls-files | wc -lfind . -type f | wc -l
  • 现有 .cursorignore / .gitignore 全文。
  • Settings → Features → Codebase Indexing 截图(卡住的进度)。
  • Help → Toggle Developer Tools → Console 里和 indexing 相关日志。

最短修复路径

按收益最高排序。

Step 1:写一份合格的 .cursorignore

仓库根新建或编辑 .cursorignore

# 依赖
node_modules
.pnpm
.yarn
vendor
__pycache__
venv
.venv

# 构建产物
dist
build
out
.next
.nuxt
.turbo
.svelte-kit
coverage
target
.gradle

# 缓存
.cache
.parcel-cache
.eslintcache
*.tsbuildinfo

# 数据文件
*.parquet
*.bin
*.gz
*.zip
*.sqlite

# 日志
*.log
logs

# Lock 文件(可选——它们很大但有时模型需要看)
# package-lock.json
# pnpm-lock.yaml

Step 2:触发 reindex

Cmd+Shift+P → “Cursor: Resync Index”(或 “Rebuild Codebase Index”)。然后 Cmd+Shift+P → “Developer: Reload Window”。等 5-30 分钟看进度。

find . -type l -exec ls -l {} \; 2>/dev/null | grep -E "\.\./.*\.\./"

找到回指上级的 symlink,要么把它移到 .cursorignore,要么改成 npm/yarn workspaces 之类原生 monorepo 链接。

Step 4:缩小 working directory

不要在 5 万文件 monorepo 根打开 Cursor。File → Open Folder → 选你这周实际工作的那个包 apps/web。索引面立刻小一个量级。

Step 5:从网络盘 / WSL 跨边界搬到原生

git clone~/repo(macOS APFS、WSL ext4、Linux 本地盘)。Dropbox / iCloud 同步目录别放 active 项目。

Step 6:清缓存彻底重建

# macOS / Linux
rm -rf ~/Library/Application\ Support/Cursor/User/workspaceStorage/*
# Windows
# rmdir /s %APPDATA%\Cursor\User\workspaceStorage

注意:这会清掉所有 workspace 的索引缓存,下次打开每个仓库都要重新索引。万不得已用。

怎么确认已经修好

  • 重启 Cursor 后再触发一次原操作,确认不是会话内的临时状态。
  • 索引进度条在合理时间内(≤ 30 分钟)走到 100%。
  • Composer 问”列出 src/api/ 目录下所有文件”能给出真实列表,说明索引覆盖到了。

如果还是没修好

  • 把复现缩到最小:新开一个空仓库,看是否也卡。
  • 回滚最近一次 Cursor 升级或 .cursorignore 改动。
  • 在 forum.cursor.com 搜 “indexing never completes”;附文件数 + OS + ignore 全文。
  • 抓 Developer Tools → Console 里 indexing 相关日志贴 Bug Reports。

预防建议

  • 新仓库第一件事就放好 .cursorignore,不要等卡住再补。
  • .cursorignore.gitignore 维护差异:generated/types/schema 等 git ignored 但模型需要看的留下;node_modules 等永远排除。
  • 不要把数据集(parquet / sqlite / 大 json)放仓库里,用 git-lfs 或 S3。
  • 项目永远放原生文件系统,不要放 iCloud / Dropbox / 网络盘。
  • 每 quarter 跑一次 git ls-files | wc -l 看仓库规模,超 5 万文件考虑拆。

相关阅读

标签: #排查 #Cursor #排查 #indexing 卡住