rebase 完了、或者刚切了分支、或者刚 pull 了一个大 merge,问 Composer「parseConfig helper 在哪用过?」Cursor 信心十足地指向 src/utils/oldHelpers.ts——一个早就不存在的文件。或者引用的行号来自一个已被大改的文件,它提的 diff 落在错位的行段上。codebase 索引是 Cursor 为了快速回答 @codebase 和语义搜索建的缓存。它大约每 5 分钟自动同步一次、而且只处理变动过的文件,所以 rebase、切分支、大 merge 这种批量改动,可能要等满一个同步周期才落地;在 macOS 上 fsevents 还会合并事件,让索引器看到的变更比实际少。索引落后于 git 状态,模型拿到的是陈旧上下文,于是回得自信而错。
最快的修法: 打开 Cursor Settings → Indexing,点 Resync Index(老版本叫 Re-index),等状态变成已是最新,再开一个全新的 Composer 对话。约 70% 的情况这一下就清掉了陈旧 chunk。剩下关于 worktree、ignore 规则、workspace 存储损坏的更深层修法在后面。菜单路径已于 2026 年 6 月核对——Cursor 把旧的 Settings → Codebase 面板改名成了 Settings → Indexing,所以指向「Codebase」的老教程已经过时。
你属于哪一类
动手前先把症状对到最可能的原因上。
| 症状 | 最可能的原因 | 去看 |
|---|---|---|
@codebase 引用已删/改名的文件 | watcher 漏了批量变更,还没同步 | Step 2,再 Step 3 |
agent 的 read_file / 改动返回旧分支内容 | git checkout 后工具缓存陈旧 | Step 2 |
| rebase 带来的新文件一直不出现 | .cursorignore / .gitignore 排除了 | Step 4 |
| 状态显示 Paused 或 Throttled | 电池/高 CPU 下索引被暂停 | Step 3 |
标题栏路径和终端 pwd 不一致 | 开错了 worktree | Step 1,再 Step 6 |
| re-index 跑了但答案还是错 | workspace 存储损坏 | Step 7 |
常见原因
按命中率从高到低。
1. Watcher 漏掉了批量文件变更
索引器靠文件系统事件加定期同步。rebase 在很短时间里改了很多文件;尤其在 macOS 上 fsevents 会合并事件,索引器看到的变更比实际少,然后要等下一次约 5 分钟的同步才对齐。
怎么判断:Cursor Settings → Indexing → 看「Last synced」/状态那行。早于你 rebase 的时间——就是同步还没追上。
2. agent 或切分支后还在喂旧内容
这是更危险的一种。git checkout 之后,编辑器里打开的文件、以及 agent 的 read_file / search_replace 工具,可能继续返回上一个分支的内容,于是旧分支的代码会渗进 Cursor 接着提交的那次改动里。这在 Cursor 论坛已被确认,官方给出的绕法就是 reload 窗口。
怎么判断:打开一个你确定在切分支时改过的文件。编辑器或 Composer 还显示旧文本——工作副本和工具缓存就是陈旧的。
3. 索引被暂停或限流了
Cursor 检测到高 CPU 或低电量时会暂停后台索引,于是你 rebase 完之后那次 resync 根本没跑。
怎么判断:Cursor Settings → Indexing → status。显示 Paused 或 Throttled 并带电量/CPU 提示——就是没跑。
4. .gitignore 或 .cursorignore 把新文件排除了
rebase 之后新树里有些文件落在你现在 ignore 规则会排除的目录里,索引器跳过、Composer 自然看不到。Cursor 同时遵守 .gitignore 和两个 Cursor 专属文件:.cursorignore(硬屏蔽——文件既不被索引,也不能通过 @Files 引用、不出现在补全里)和 .cursorindexingignore(只排出索引,但仍可用 @Files 引用)。
怎么判断:检查新 HEAD 下的 .cursorignore、.cursorindexingignore 和 .gitignore。新文件路径匹中某条 pattern——就是它。
5. embeddings 缓存按旧内容存的还在
Cursor 把每个文件切块、在服务端算 embedding,并连同一个混淆过的相对路径和行号范围一起存(存在 Turbopuffer 里)——原始代码不保留。rebase 后内容 hash 变了、path 没变,旧 vector 被慢慢淘汰,查询命中陈旧 neighbor。
怎么判断:下面 Step 3 强制 resync 后立刻好转——就是它。
6. 你在用 worktree,Cursor 开的是错的那个
用 git worktree 时,Cursor 开在主仓路径、但你在 worktree 路径里编辑——索引就指向主 worktree。
怎么判断:看标题栏路径,和你终端里 pwd 不一致——你已经走偏了。
开始前
- 把正在改的内容提交或 stash;resync 从磁盘读,不要让它把半成品缓存进去。
- 给 CPU 留一两分钟预算;大仓全量 resync 不是瞬间的事。
- 知道自己代码库规模(文件数、总 LOC),心理预期到位。
需要收集的信息
- Cursor 版本(
Cursor → About Cursor,或 Help → About)。 - 仓库规模:
find . -type f \( -name '*.ts' -o -name '*.js' -o -name '*.py' \) | wc -l。 Cursor Settings → Indexing→ 状态 / last-synced 那行。git log --oneline -10确认 rebase 发生过。- 是不是在用 worktree(
git worktree list)。 .cursorignore、.cursorindexingignore和.gitignore内容。~/.cursor/logs/里最近匹配index或embed的条目。
一步一步修复
Step 1:确认 Cursor 看到的 HEAD 是对的
Cursor 集成终端跑 git rev-parse HEAD,再用外部终端在同一路径跑一遍,要一样。不一样——Cursor 开的是别的路径(worktree、symlink 副本),直接跳 Step 6。
Step 2:reload 窗口
Cmd+Shift+P → 「Developer: Reload Window」。重新扫一遍工作树,这也是 git checkout 后那个「文件/工具缓存陈旧」问题的官方修法。三成左右的过期索引这一步就够,一个同步周期内 indexer 能追上。
Step 3:强制全量 resync
Cursor Settings → Indexing → 点 Resync Index(老版本:Re-index)。把现有 chunk 和 embedding 缓存丢掉、从磁盘重建。10 万文件的仓大概 5-15 分钟;盯着状态那行变成已是最新再信它的回答,别在重建中途就信。
Step 4:核对 ignore 规则
rebase 后多了新目录的话,确认 .cursorignore 和 .cursorindexingignore 没排除它。常见坑:pattern dist/ 会把任何 package 下的 dist/ 都排掉。如果你还想用 @ 引用某文件、只是不想让它进索引,用 .cursorindexingignore(而不是 .cursorignore)。
Step 5:在 Composer 里清掉上下文
新开一个 Composer 对话。已有线程会继续用它先前抓到的文件引用;只有新线程才会对重建后的索引重新抓。
Step 6:worktree 直接开 worktree 路径
退出 Cursor,用 cursor /path/to/the/worktree 或 File → Open Folder 打开。每个 worktree 一个独立 Cursor 窗口、各自独立索引——绝不跨 worktree 共用一份索引。
Step 7:还不对,清掉 workspace 存储
兜底:退出 Cursor,删掉这个 workspace 的存储目录(在意聊天记录的话先备份):
- macOS:
~/Library/Application Support/Cursor/User/workspaceStorage/<hash>/ - Linux:
~/.config/Cursor/User/workspaceStorage/<hash>/ - Windows:
%APPDATA%\Cursor\User\workspaceStorage\<hash>\
重开项目,Cursor 会从零建一份干净 workspace 存储和索引。
怎么确认修好了
- 问 Composer 一个你在 rebase 里改名了的文件路径,它必须回新路径。
- 问一个挪了位置的函数的行号,要和编辑器里看到的一致。
- 用
@codebase跑一个应该命中新加文件的 query,文件应该出现在引用里。 - 在挪过位置的文件上
Cmd-K改一下,diff 要落在正确行段。 Cursor Settings → Indexing状态应显示已是最新,且「last synced」时间在你 rebase 之后。
长期预防
- 任何 rebase 或大 merge 之后点一下 Resync Index。当成 build step 看待。
- 大 diff 的分支切换别开着 Cursor 切——先退出、切完、再启。
- 一个 worktree 一个 Cursor 窗口,不要跨 worktree 共用索引。
.cursorignore写得简洁、明确;过宽的 pattern 会悄悄缩小索引范围。- Cursor 钉在一个已知索引稳定的版本上——新版本不一定更快。
容易踩的坑
- rebase 后立刻信
@codebase的回答。头一个同步周期基本都是 stale。 - 在电池模式下 re-index,会被 throttle,看起来跑完了实际没。
- index 跑着改
.cursorignore,runner 可能还在用老规则,重启才生效。 - 以为「Reload Window」会强制全量 re-index——它只重扫工作树,不重建 embedding,要全量得用 Resync Index。
- 让 Cursor 索引
node_modules之类。vendor 和 build 目录永远 ignore 掉。
常见问答
- re-index 按钮现在在哪?
Cursor Settings → Indexing。Cursor 在 2026 年初把旧的「Codebase」设置面板改名成了「Indexing」,所以指向Settings → Codebase的说法已经过时。 - Cursor 多久同步一次索引? 大约每 5 分钟自动同步一次,只处理变动过的文件。所以 rebase 后会有几分钟看起来是 stale,要等下一个周期。
- 项目放着不动,索引会丢吗? 会。截至 2026 年 6 月,Cursor 在项目闲置 6 周后会删掉它的索引;重新打开项目会触发重新索引。
- 索引会把我的代码上传到云端吗? embedding 在服务端算,并连同混淆过的文件路径和行号范围一起存(存在 Turbopuffer 里),原始源码不保留。
Cursor Settings → Privacy(Privacy Mode)能让一切留在本地,但索引更慢。 - 能从命令行触发 re-index 吗? 没有官方方式。走
Cursor Settings → Indexing → Resync Index。 - 切分支时 Cursor 会自动 re-index 吗? 部分会。文件增删它在下次同步能跟,但大幅原地改写经常漏,而且 agent 的读文件缓存可能还在喂旧分支内容。大 rebase 后 reload 窗口再 resync 才稳。