一個 repo 只有一個資料夾:分身住 repo 裡面的 .worktrees/,收工由同一支閘收掉(inkstone/ISEP#147)
leo 2026-09-07:「一個 repo 只看得到一個資料夾」「禁止這樣產出一大堆資料夾」。 根因:line-needs-own-worktree.sh 教工人開在 repo 旁邊,「收工 remove」只寫在閘訊息裡、沒機制驗, 每條線留一份 ⇒ tech_projects/ 長出 ISEP-wt-117/InkStoneCo-wt-112…一排。規則在文字裡不在機器上。 - scripts/worktree(新):open/close/list/sweep 四個動詞。分身住 <repo>/.worktrees/<票 repo>-<N> (走 .git/info/exclude,不動被追蹤的檔);「推了沒」只有這一份判準(三態:有/沒有/問不到, 問不到不當成沒推也不收);sweep 預設只列不動,--apply 只收「推了且乾淨」,--skip 是操作者點名。 - hooks/line-needs-own-worktree.sh:擋下時印 `scripts/worktree open`(絕對路徑,貼了就跑); 同一支多掛 PostToolUse Agent|Task——從【工單】認出分身,推了收、沒推點名分支+路徑(exit 2), 不 force、不刪。+0 支、+1 條(61 支/86 條,當場數的)。 - docs/governance/worktree-placement.md(新)+ principles 一行:禁令與閘互指。 - 測試:line-needs-own-worktree.test.sh 77→110(G 群:閘印的 open 那行原樣跑、旁邊不多任何東西; H 群:PostToolUse 推了收/沒推點名/安靜的方向);scripts/test-worktree.sh 42 條(七個分身的 fixture, 名字照 leo 看到的那排)。舊閘跑新測試 90/110,紅的 20 條正是這次改到的行為。 - permissions-allow.json 加 worktree 四種形狀(出路在雲端被分類器擋就走不通)。 - README/plugin.json/hooks-inventory 的數字在這棵樹上實數:61 支、86 條、62 支腳本。 待總管定版(改了會被載入的東西)。沒碰 hooks/lib/mainline.py。 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0178ef1fGw3XeZtpN7LaZrm4
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# 一個 repo 只有一個資料夾:分身住 `.worktrees/`,收工就被收(inkstone/ISEP#147)
|
||||
|
||||
> leo 2026-09-07(兩則,一字不改):
|
||||
> 「我看到的是一個 repo,你會產生大量的同一個頭不同尾巴的 repo,全部拆開就更亂了,
|
||||
> 為什麼要產出新的 repo?這個 repo 的目的就是收納所有相關的內容,這樣散開造成凌亂,
|
||||
> ISEP, Inkstoneco, Course Gen 這些都產出好多個資料夾,這要整理回去」
|
||||
> 「另外要在 ISEP 裡寫明,禁止這樣產出一大堆資料夾」
|
||||
|
||||
## 規約(三句)
|
||||
|
||||
1. 🔴 **禁止在專案目錄旁邊產出分身資料夾。** `tech_projects/` 底下一個 repo 只能有一個資料夾;
|
||||
`ISEP-wt-117`、`InkStoneCo-wt-112`、`course_gen-ticket-3-notes` 這種同頭不同尾的東西不准再長出來。
|
||||
2. **一條線要隔離工作目錄,分身住 repo 裡面**:`<repo>/.worktrees/<票的 repo 名>-<票號>`。
|
||||
Finder 看不到(點開頭)、`git status` 看不到(寫進 `.git/info/exclude`)、`git worktree list` 找得到。
|
||||
3. **分身是借的,收工要還**:分支推上遠端且工作樹乾淨 ⇒ 收掉;沒推 ⇒ 點名分支與路徑,等人決定。
|
||||
**絕不 force、絕不刪沒推的 commit。**
|
||||
|
||||
## 為什麼會長成那樣(根因,不是誰疏忽)
|
||||
|
||||
`hooks/line-needs-own-worktree.sh`(inkstone/ISEP#109,08-29 立)擋下線在共用目錄切分支,教它
|
||||
「開一份在 repo 旁邊、不要在 /tmp、收工時 `worktree remove`」。
|
||||
|
||||
那時比較的只有「旁邊 vs /tmp」——/tmp 會被系統清掉、登記簿說謊;旁邊的一份都沒掉。
|
||||
**一份都沒掉,也一份都沒收**:`remove` 那一步只寫在閘訊息裡,沒有任何機制驗。
|
||||
每個工人留一份,`tech_projects/` 就長成那排。**規則在文字裡,不在機器上**
|
||||
(同日 ISEP#109 comment 6629 是同一種病:出路寫在訊息裡,機器讀不到)。
|
||||
|
||||
## 機器上的兩端
|
||||
|
||||
| 端 | 在哪 | 做什麼 |
|
||||
|---|---|---|
|
||||
| 開 | `hooks/line-needs-own-worktree.sh`(PreToolUse Bash) | 擋下共用目錄裡的 checkout,印出 `scripts/worktree open …`(絕對路徑,貼了就能跑) |
|
||||
| 收 | **同一支閘**多掛 PostToolUse `Agent\|Task` | 從派工單 `【工單】owner/repo#N` 認出分身名字,跑 `scripts/worktree close`:推了收、沒推點名(exit 2) |
|
||||
| 工具 | `scripts/worktree` | `open`/`close`/`list`/`sweep` 四個動詞;「推了沒」只有這一份判準(三態:有/沒有/問不到,問不到不當成沒推) |
|
||||
|
||||
為什麼收的那一半不另開一支閘:教你開的和替你收的是同一件事的兩半,拆成兩支就又是「規則在兩個地方」
|
||||
(`countdown-guard.sh` 同一種形狀:注入與查核是一支閘掛兩個事件)。
|
||||
|
||||
為什麼掛 PostToolUse 不掛 SubagentStop:票號在派工單(Agent 的 `tool_input.prompt`)裡,SubagentStop 拿不到
|
||||
(`baton-handback-guard.sh` 檔頭那段實撞)。
|
||||
|
||||
## 工人怎麼用
|
||||
|
||||
```
|
||||
python3 <plugin>/scripts/worktree open inkstone/ISEP#147 --repo <repo> -b feat/147-xxx # 開
|
||||
cd <repo>/.worktrees/ISEP-147 # 在裡面做事
|
||||
python3 <plugin>/scripts/worktree close inkstone/ISEP#147 --repo <repo> # 收(推了才收得掉)
|
||||
```
|
||||
|
||||
忘了 `close` 也沒關係——線收工那一刻閘會替你跑;但**沒推的它不會替你收**,只會點名。
|
||||
不要用 `git worktree add <repo>/../<repo>-wt-…` 這條老路;閘訊息已經不印它了。
|
||||
|
||||
## leo 在 Mac 上整理現場(一次)
|
||||
|
||||
```
|
||||
python3 ~/.claude/plugins/cache/inkstone/isep/<版本>/scripts/worktree sweep ~/tech_projects # 只列,不動
|
||||
python3 ~/.claude/plugins/cache/inkstone/isep/<版本>/scripts/worktree sweep ~/tech_projects --apply --skip course_gen
|
||||
```
|
||||
|
||||
- 預設**只列不動**;`--apply` 才收,而且只收「推了且乾淨」的。
|
||||
- 沒推的、有未 commit 的、問不到遠端的、沒有任何 repo 登記它的:**全部列出來、一個都不動**,等他決定。
|
||||
- `--skip <repo 名>` 是操作者點名不碰的 repo(09-07:`course_gen` 地端正在處理,列可以、不收不動)。
|
||||
它是操作者的明示指令,不是判準——判準永遠是「這個目錄是不是某個 repo 的 worktree、分支推了沒、乾不乾淨」。
|
||||
|
||||
## 測試
|
||||
|
||||
- `hooks/tests/line-needs-own-worktree.test.sh` G 群(開在裡面、旁邊不多任何東西、閘印的那行原樣跑得動)
|
||||
與 H 群(PostToolUse:推了收掉、沒推點名、沒工單/沒分身安靜)。
|
||||
- `scripts/test-worktree.sh`:七個分身的 fixture(照 leo 09-07 看到的那排)跑 `sweep`——
|
||||
dry-run 不動任何東西;`--apply` 只收已推的、`--skip` 的一根寒毛不動、沒推的印分支與路徑。
|
||||
Reference in New Issue
Block a user