补踩坑:第四类索引事故——git add <路径> 会把同一文件里别人的 hunk 一起暂存
- 记录 28781a420 的事故形态:该笔除我新增的用例(@@ -1260,6 +1260,51 @@)外,还混入了 peer 对「所有资源」测试期望的在途改动(@@ -9562,37 +9607,83 @@),提交描述与实际内容不符,且对方那份文件随即显示为干净、容易被误判为已收口;内容未丢
- 写清正确护栏:对可能被他人同时编辑的文件,把 git add <path> + git diff --cached(看内容、不只看文件名)+ git commit 压进同一条命令,并逐 hunk 确认每一个都是自己这次要写的;发现混入他人 hunk 后保持现状并立即上报,不在共享树里用 --amend/reset/checkout --/revert 做手术
- 写清状态信号:M (已暂存且工作区与索引一致)/ MM(add 后又改过)/ M(仅工作区),并点明「M 只能说明 add 之后没人再动过,不能说明这份文件里只有我的改动」
- 写清同类隐患:pre-commit 的 lint-staged 会对它格式化过的文件做 git add(prettier --write 之后 Applying modifications from tasks),与 npx lint-staged --diff=… 属同类反向 git add
- 与前三类索引事故(git add -A 卷走别人的文件 / stash pop 弹出别人的 stash / lint-staged --diff 反向 add)并列,指明本类正是「按文件名校验」这道护栏的失效点
- 门禁:npm run check:encoding exit 0(4399 file(s))
This commit is contained in:
@@ -5335,3 +5335,15 @@
|
||||
- **原因/处理**:补扫让"漏掉"这个**症状**立刻消失,但触发条件仍在,于是每次补扫又制造出新的待补项,形成自激回路;根因(第一次为什么会漏)始终没被定位。正确做法是回到触发条件本身(为什么同一份输入会漏),而不是在读取侧再叠一层重试/补扫。判断这类"修复"是否只是掩盖,可以问一句:**把补扫去掉,症状会不会回来?会回来就说明根因没动。**
|
||||
- **验证**:⚠️ **本条由并行工作线报告,本排障线(AGC 资源画布 / Direct Codex)未独立复核**——没有拿到该线的 file:line、命令或 CI 输出。**引用本条前先向该线取证据**,不要把它当已复核结论使用。
|
||||
- **关联**:待并行线回填(提交/文件/命令)。
|
||||
|
||||
## 2026-09-11 第四类索引事故:`git add <路径>` 会把「同一文件里别人的 hunk」一起暂存(按文件名校验抓不到)
|
||||
|
||||
- **现象**:在多个 Agent 共用同一 worktree 时,我的一次提交 `28781a420` 里出现两个 hunk:一个是我这次新增的用例(`@@ -1260,6 +1260,51 @@`),另一个是**别人的在途改动**(`@@ -9562,37 +9607,83 @@`:他们改「所有资源」测试的期望)。该笔 `107 insertions(+), 16 deletions(-)` 里只有约 45 行是我的。**没有丢内容**(对方的改动只是被冻在我名下的提交里),但**提交描述与实际内容不符**,而且对方那份文件立刻变成"干净",很容易被误以为已经收口。
|
||||
- **原因**:`git add <路径>` 暂存的是该文件**当前工作区的整份内容**,不是"我这一份 diff"。只要对方的编辑已经落在工作区,`git add` 就会连带暂存。**事后回看 `git status --short` 那一行是 `M `(第一列 `M`、第二列空格)——这正是"对方编辑早于我的 `git add` 就已进入工作区"的特征**:索引与工作区一致,所以从状态行上看不出任何异样;若是 `MM`(add 之后工作区又被改过)反而更容易察觉。
|
||||
- **与前三类的区别**:前三类索引事故都是「**别人的文件**被卷走」——① `git add -A` 卷走别人的在途文件;② `stash pop` 弹出别人的 stash;③ `npx lint-staged --diff=…` 在收尾反向 `git add`。本类是「**同一个文件里别人的 hunk** 被卷走」,而**按文件名做校验的护栏在这里失效**:文件名本来就是我该提交的那一个,`git diff --cached --name-only` 必然通过。
|
||||
- **处理(正确护栏)**:对"可能被他人同时编辑的文件",把 **`git add <path>` + `git diff --cached`(看**内容**,不只看文件名)+ `git commit` 压进**同一条命令**——窗口越小,对方编辑撞进来的概率越低;并在 `git diff --cached` 的输出里**逐 hunk** 确认"每一个 hunk 都是我这次要写的"。发现混入他人 hunk 后,**不要**在共享树里用 `--amend` / `reset` / `checkout --` / `revert` 做手术(本仓库会话明令禁止),**保持现状并立即上报**,由对方在自己的新提交里接着改(零风险,内容也没丢)。
|
||||
- **状态信号速查**:`M ` = 已暂存且工作区与索引一致;`MM` = 已暂存 + 工作区又改过;` M` = 只有工作区改动(未暂存)。**`M ` 只能说明"我 add 之后没人再动过",不能说明"这份文件里只有我的改动"**——判断后者唯一可靠的办法是看 `git diff --cached` 的内容。
|
||||
- **同类隐患(pre-commit 的 lint-staged)**:`lint-staged` 会对**它格式化过的文件**做 `git add`(日志里的 `prettier --write` 之后紧跟 `Applying modifications from tasks`)。因此"把可能有他人 hunk 的文件交给 lint-staged 格式化"与 `npx lint-staged --diff=…` 是同一类反向 `git add`;要么先与对方约定谁提交该文件,要么等它干净再动。
|
||||
- **验证**:用内容级复核定案——`git show 28781a420 -- <file> | Select-String '^@@'` 得到两个 hunk;`git show` 的 `^-` 行里出现对方特有的 `data-resource-book-all-page` / `allSections` 字样。这同时排除了另一种解释("只是 prettier 重排"):重排会表现为 `-`/`+` 成对出现且**语义相同**,而这里 `-` 掉的断言在 `+` 侧并不存在。
|
||||
- **关联**:提交 `28781a420`、`apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts`、`package.json` 的 `format:staged`(lint-staged 配置)。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user