fix(dev-infra): harden worktree hook migration

This commit is contained in:
Tianyi Cui
2026-07-27 20:58:19 +08:00
parent 054ee9f2cc
commit 3feaef6ecb
8 changed files with 749 additions and 78 deletions

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write docs/development.md
development.md: fd7f39ae7b5aac2d44572979ca8c8f1d2df0de6f
development.zh.md: 7dd6209bad75d605e0056d2465a35b08aa091780
development.md: 6c927c46b0a25f84295796354e7f49eb9eb7b2e9
development.zh.md: f29d08df18ca9bead7f4c9bf3cf7f749630b1b84

View File

@@ -8,7 +8,7 @@ This onboarding guide helps project contributors get started with the local envi
- Node.js supports 22.19+ and 24+. CI covers 22.19, 24, and 26; see the [Node engine floor Agent Note](../.agents/notes/implemented/process/2026-07-06-node-engine-floor.md).
- Corepack-enabled pnpm. The repo pins `pnpm@11.7.0` in `package.json`; run `corepack enable` if `pnpm --version` does not resolve through Corepack.
- Git 2.20 or newer; hook setup enables Git's worktree-specific configuration extension.
- Git 2.26 or newer; hook setup enables Git's worktree-specific configuration extension.
- Optional: a DeepSeek API key for the TUI, headless, and ACP automation demos and real-API e2e tests.
## First-time setup
@@ -19,7 +19,7 @@ Install dependencies from the repo root:
pnpm install
```
The install also runs the root `postinstall` script, which installs lefthook from the repo dev dependency through `scripts/install-lefthook.mjs`. The wrapper gives the current worktree an explicit hook directory under its own Git directory; linked worktrees therefore use their own lefthook binary and configuration instead of rewriting common hooks. The first install enables Git's worktree-specific configuration extension and repository format 1; see the [worktree-local hooks Agent Note](../.agents/notes/implemented/process/2026-07-27-worktree-local-lefthook.md).
The install also runs the root `postinstall` script, which installs lefthook from the repo dev dependency through `scripts/install-lefthook.mjs`. The wrapper requires Git 2.26 or newer and gives the current worktree an explicit hook directory under its own Git directory; linked worktrees therefore use their own lefthook binary and configuration instead of rewriting common hooks. The first install enables Git's worktree-specific configuration extension and repository format 1; see the [worktree-local hooks Agent Note](../.agents/notes/implemented/process/2026-07-27-worktree-local-lefthook.md).
If hooks are missing because dependencies were restored from cache or `postinstall` was skipped, install them manually:
@@ -27,7 +27,7 @@ If hooks are missing because dependencies were restored from cache or `postinsta
node scripts/install-lefthook.mjs
```
The wrapper refuses to replace an existing user-owned `core.hooksPath`. If an inherited global or repository path should remain active in other worktrees while this worktree opts into lefthook, inspect that path first and rerun with `DSH_LEFTHOOK_ALLOW_HOOKS_PATH_OVERRIDE=1`; a worktree-specific custom path is never overwritten and must be integrated or removed explicitly.
The wrapper refuses to replace an existing user-owned `core.hooksPath`. If an inherited system, global, or common-repository path should remain active in other worktrees while this worktree opts into lefthook, inspect that path first and rerun with `DSH_LEFTHOOK_ALLOW_HOOKS_PATH_OVERRIDE=1`; command-scoped and worktree-scoped custom paths are never overridden and must be integrated or removed explicitly. The same rules apply when a currently inactive conditional include can provide a hook path; unrelated conditional includes remain valid. Before enabling the worktree-config extension, conditional common-config targets that may contain `core.worktree` or `core.bare=true` require manual migration. If the installer reports a stale or invalid lock, confirm no installer is running, remove the reported lock manually, and rerun the command.
Run typecheck once after a fresh clone:

View File

@@ -8,7 +8,7 @@
- Node.js 支持 22.19+ 与 24+。CI 覆盖 22.19、24 和 26见 [Node 引擎下限 Agent Note](../.agents/notes/implemented/process/2026-07-06-node-engine-floor.md)。
- 启用了 Corepack 的 pnpm。仓库在 `package.json` 中固定使用 `pnpm@11.7.0`;如果 `pnpm --version` 无法通过 Corepack 解析,请先运行 `corepack enable`
- Git。
- Git 2.26 或更高版本;钩子设置会启用 Git 的 worktree 专属配置扩展
- 可选:一个 DeepSeek API key用于 TUI、headless 和 ACPAgent Client Protocol自动化 agent智能体演示以及真实 API 的 e2e 测试。
## 首次搭建
@@ -19,14 +19,16 @@
pnpm install
```
安装过程同时会运行根目录的 `postinstall` 脚本,该脚本通过 `scripts/install-lefthook.mjs` 从仓库 dev 依赖安装 lefthook。包装脚本使用 lefthook 经过评审的 `--force` 模式,确保已存在 `core.hooksPath` 的关联 worktree 不会导致正常的 `pnpm run …` 命令失败
安装过程同时会运行根目录的 `postinstall` 脚本,该脚本通过 `scripts/install-lefthook.mjs` 从仓库 dev 依赖安装 lefthook。包装脚本要求使用 Git 2.26 或更高版本,并会为当前 worktree 在其自身的 Git 目录下设置显式钩子目录;因此,关联 worktree 会使用各自的 lefthook 二进制文件和配置,而不会改写共用钩子。首次安装会启用 Git 的 worktree 专属配置扩展和仓库格式 1见 [worktree 本地钩子 Agent Note](../.agents/notes/implemented/process/2026-07-27-worktree-local-lefthook.md)
如果依赖是从缓存恢复或 `postinstall` 被跳过而导致缺少钩子,请手动安装:
```sh
pnpm exec lefthook install --force
node scripts/install-lefthook.mjs
```
包装脚本拒绝替换现有且由用户自行管理的 `core.hooksPath`。若要让继承自系统、全局或共用仓库配置的路径在其他 worktree 中继续生效,同时让当前 worktree 显式启用 lefthook请先检查该路径再设置 `DSH_LEFTHOOK_ALLOW_HOOKS_PATH_OVERRIDE=1` 重新运行;命令作用域和 worktree 作用域的自定义路径绝不会被覆盖,必须显式集成或移除。当前未生效的 `includeIf` 可能提供钩子路径时,同样适用这些规则;与钩子无关的 `includeIf` 仍然有效。worktree 配置扩展启用之前,可能包含 `core.worktree``core.bare=true` 的共用配置 `includeIf` 目标需要手动迁移。若安装程序报告陈旧锁或无效锁,请先确认没有安装程序正在运行,手动移除诊断中报告的锁,再重新运行命令。
新克隆后请先运行一次类型检查:
```sh