refactor(dev-infra): narrow worktree hook safety checks

This commit is contained in:
Tianyi Cui
2026-07-28 00:05:31 +08:00
parent 95bba22f84
commit c982cf7805
9 changed files with 93 additions and 317 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: f1a853acfd1e89104b8013a5b5e9c4032979234f
development.zh.md: 493284e38ad68768b1159778d5dd50aecfe9ccd1
development.md: 32339fa2af8c1b6005d9e0b8165d57966a4145ca
development.zh.md: c74a81346639c6f95568cbd86b401d134d5eb7fc

View File

@@ -27,7 +27,11 @@ 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 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 upgrading a format-0 repository, existing `extensions.*` keys in the common config or a conditional target require manual audit and migration because format 1 activates them. Before enabling the worktree-config extension, conditional common-config targets that may contain `core.worktree` or `core.bare=true` require manual migration. A dormant `config.worktree` in any registered worktree also requires inspection and explicit migration or removal before the extension can be enabled without changing that worktree. The common repository config and every active or dormant worktree config must be regular files. The owned hook directory may contain only unaliased regular files; replace a reported symlink, hard link, or non-file entry before retrying. After moving the checkout, rerun the wrapper so its ownership marker can replace the exact stale path it installed and regenerate hooks at the new Git directory. If the installer reports a stale or invalid lock, confirm no installer is running, remove the reported lock manually, and rerun the command. If Lefthook installation and automatic hook-path rollback both fail, the diagnostic preserves both failures; inspect the worktree config and remove the new path manually before retrying.
The wrapper refuses user-owned `core.hooksPath` values. An inherited system, global, or common-repository path requires `DSH_LEFTHOOK_ALLOW_HOOKS_PATH_OVERRIDE=1`; command-scoped and worktree-scoped custom paths must be integrated or removed explicitly.
Before enabling worktree config, migrate direct `extensions.*` in a format-0 common config, direct `core.worktree` or `core.bare=true`, and any non-empty dormant `config.worktree`. The common config and every worktree config must be regular files, while the owned hook directory may contain only unaliased regular files.
After moving a checkout, rerun the wrapper to relocate its owned path and regenerate hooks. For a stale or invalid installer lock, first confirm no installer is running, then remove the reported lock and retry. If installation and hook-path rollback both fail, inspect the reported worktree config before retrying. The [worktree-local hooks Agent Note](../.agents/notes/implemented/process/2026-07-27-worktree-local-lefthook.md) owns the full safety contract.
Run typecheck once after a fresh clone:

View File

@@ -27,7 +27,11 @@ pnpm install
node scripts/install-lefthook.mjs
```
包装脚本拒绝替换现有且由用户自行管理`core.hooksPath`若要让继承自系统、全局或共用仓库配置的路径在其他 worktree 中继续生效,同时让当前 worktree 显式启用 lefthook请先检查该路径设置 `DSH_LEFTHOOK_ALLOW_HOOKS_PATH_OVERRIDE=1` 重新运行;命令作用域和 worktree 作用域的自定义路径绝不会被覆盖,必须显式集成或移除。当前未生效的 `includeIf` 可能提供钩子路径时,同样适用这些规则;与钩子无关的 `includeIf` 仍然有效。升级格式版本为 0 的仓库之前,若共用配置或条件目标中已有 `extensions.*` 键,就需要手动审计和迁移,因为格式 1 会激活这些键。worktree 配置扩展启用之前,可能包含 `core.worktree``core.bare=true` 的共用配置 `includeIf` 目标需要手动迁移。任一已注册 worktree 中尚未生效的 `config.worktree` 也必须先经过检查并显式迁移或移除,才能在不改变该 worktree 的前提下启用扩展。共用仓库配置以及每个生效或尚未生效的 worktree 配置都必须是常规文件。自有钩子目录只能包含不带别名的常规文件;请先替换诊断中报告的符号链接、硬链接或非文件条目,再重试。检出目录移动后,请重新运行包装脚本,使其所有权标记可以替换之前写入的确切陈旧路径,并在新的 Git 目录中重新生成钩子。若安装程序报告陈旧锁或无效锁,请先确认没有安装程序正在运行,手动移除诊断中报告的锁,再重新运行命令。若 Lefthook 安装和钩子路径自动回滚都失败,诊断会保留两次失败;请检查 worktree 配置并手动移除新路径,再重试。
包装层会拒绝用户自有`core.hooksPath`。继承自系统、全局或共用仓库配置的路径必须设置 `DSH_LEFTHOOK_ALLOW_HOOKS_PATH_OVERRIDE=1`;命令作用域和 worktree 作用域的自定义路径必须显式集成或移除。
启用 worktree 配置之前,请迁移格式 0 共用配置中直接设置的 `extensions.*`,并迁移直接设置的 `core.worktree``core.bare=true`,以及任何非空且尚未生效的 `config.worktree`。共用配置和每个 worktree 配置都必须是常规文件,而自有钩子目录只能包含不带别名的常规文件。
检出目录移动后,请重新运行包装层,使其重新定位自有路径并重新生成钩子。对于陈旧或无效的安装程序锁,请先确认没有安装程序正在运行,再移除报告的锁并重试。若安装和钩子路径回滚都失败,请在重试前检查报告的 worktree 配置。完整安全契约由 [worktree 本地钩子 Agent Note](../.agents/notes/implemented/process/2026-07-27-worktree-local-lefthook.md) 统一定义。
新克隆后请先运行一次类型检查: