JianFeeeee
c4a8c98b9d
跨端: AGC 闹钟**只枚举一条 ref** 而声称"整个远端" —— 改成对全部远端 ref 判
pi 2026-09-15 抓到的**第三个洞**,而且他说得对:这是**同一句话换一根轴**。
## 一、洞:我在"可达性"那侧立了"问不到 ⇒ 红",却在"覆盖面"那侧"看不到 ⇒ 绿"
```js
const branch = rb ? rb[1] : 'main';
const lsr = git(['ls-remote', 'origin', `refs/heads/${branch}`]); // ← 只有一条
```
判据标题写的是"从未进过**远端**",实际只问**当前分支**一条 ref。于是
**把受污染历史推到旁支、或推一个指向它的 tag** ⇒ 凭证出去了,而这条判据**照样绿**。
上一轮我刚立下"问不到 ⇒ 红,这是**不知道**不是**安全**",**同一句判据在覆盖面这一侧
却把"我没枚举到的 ref"静默当成干净** —— **"看不到 ⇒ 绿"**。
和"把不知道读成安全"是同一句话,只是**宾语换成了覆盖面**而不是可达性。
## 二、修法(pi 给的,**不需要 fetch 任何对象**)
`ls-remote` 问**全部 ref**,对**每一条**的 tip 查该路径是否在其可达历史里。
查明"远端有哪些 ref"是 `ls-remote` 的免费信息,没有理由只问一条。
`git log <sha> -- <路径>` 查的正是"**从该 sha 可达的全部历史**",所以未 fetch 的对象也在其列 ——
**这一点我实测过才这么写**(不是照着 pi 的话抄)。
## 三、★ 我**没有**把"ref 集合恰好等于 HEAD + refs/heads/main"写成不变量
pi 提了两个选项(断言集合恰好已知 / 未枚举的报 unknown)。我选第三条:
**判"有没有哪条 ref 的可达历史里有那个 blob"** —— 它对**任意** ref 集合都成立。
理由是 `pre-push` 删 ref 那次的教训:**一道闸消费了不属于它管辖的东西**。
把"远端只有一条分支"写成不变量,会在**加第一个 tag / 第一条正常旁支**时误红 ——
那是**为了抓泄露而给日常操作设卡**。要判的性质是"泄露",不是"ref 集合的形态"。
## 四、验证:四态 + 一对照,全在**独立 bare 仓 + 独立 clone** 里做
| 情形 | 结果 |
|---|---|
| 干净远端(main + 干净旁支 `feature-clean`) | **ok 6**(不误红) |
| 旁支 `refs/heads/other` 指向含该路径的提交 | **not ok**(红,点名 `[refs/heads/other]`) |
| tag `refs/tags/leak` 指向含该路径的提交 | **not ok**(红) |
| annotated tag(指向 tag 对象) | **not ok**(红;`ls-remote` 同时给 tag 对象与 `^{}` 解引用,两条都查到) |
| **对照**:把副本改回"只问 `refs/heads/main`" | **ok 6** —— **旧写法在同一个泄露远端上是绿的** |
最后那行是这次的关键:**旧判据在"凭证已经推出去了"的远端上报绿**,与 pi 的推断一致。
`unresolved` 那一支(`git log <sha>` 解析不了的 ref)也留着了:**报 unknown 红,不当绿** ——
**查不了 ≠ 干净**。
## 五、与上一轮的交叉(pi §四 说两条"仍活着")
他复核的是 `4d78fc1`,那两条我已在**它的下一个提交 `239f919`** 里修掉:
`unreportedFiles += 1` 现在只有一处(语句位置),`checks` 取 `# tests` 而非 `# pass`。
现测:`checks=400 pass=399 fail=1 red=4` —— 与他算的 400/399 逐字一致。**内容以 `239f919` 为准。**
2026-09-15 12:58:19 +08:00
..
2026-09-13 06:16:59 +08:00
2026-09-14 11:07:03 +08:00
2026-09-14 16:49:08 +08:00
2026-09-15 08:51:18 +08:00
2026-09-15 12:58:19 +08:00
2026-09-08 19:16:35 +08:00
2026-09-14 14:57:18 +08:00
2026-09-14 11:07:03 +08:00
2026-09-08 19:16:35 +08:00
2026-09-14 16:00:34 +08:00
2026-09-08 19:16:35 +08:00
2026-09-12 09:54:31 +08:00
2026-09-08 19:16:35 +08:00
2026-09-14 09:11:36 +08:00
2026-09-12 08:02:30 +08:00