feat(git): 完善 Worktree 生命周期与发布约定

This commit is contained in:
zhiye.sun
2026-08-31 17:34:27 +08:00
parent e82eb4e857
commit 9c1fb956e4
13 changed files with 249 additions and 25 deletions
@@ -7,6 +7,8 @@
- 当前工作区和目标 worktree 路径没有未处理状态或归属冲突。
- 环境配置风险已按项目规范处理;凭据风险为零。
创建、复用或关闭独立 worktree 时,同时读取 [Worktree 生命周期](worktree-lifecycle.md)。
## 隔离创建
根据项目规范决定预集成分支基于源还是目标。没有规范时说明两种历史形状,由用户选择,不能默认套用固定组织模型。
@@ -32,4 +34,6 @@ git status --short --branch
确认源、目标引用仍等于操作前哈希;只有预集成分支发生变化。记录 merge 提交、测试结果和未验证边界。
保留 worktree 供用户复核。清理 worktree、删除分支或中止 merge 都是独立操作,不属于自动收尾。
必须以目标引用为基准检查 `git diff --check "<target>...HEAD"`、`git diff --stat "<target>...HEAD"`、`git diff --name-status "<target>...HEAD"` 和 `git log --oneline "<target>..HEAD"`。最终文件清单包含本地配置、缓存、IDE 文件或无关需求文件时停止,不得进入交付阶段。
需要人工复核时暂时保留 worktree 并标记为 `delivery-ready`。用户确认仅本地交付,或完成已授权的发布后,生命周期进入 `cleanup-ready`,必须继续执行清理门禁。中止 merge 和删除分支不属于自动收尾。
@@ -23,3 +23,7 @@
- 关联任务或项目文档。
默认只给出标题、描述、命令或网页入口。实际创建 MR/PR 需要新的明确授权;审核、合并、删除远程分支和删除 worktree 均不在本阶段自动执行。
## 发布后收尾
完成用户已授权的推送或 MR/PR 创建后,确认远程结果和本地预集成分支仍可解析,然后将 worktree 标记为 `cleanup-ready`,继续读取 [Worktree 生命周期](worktree-lifecycle.md) 并执行清理门禁。移除额外 worktree 不删除本地或远程分支。
@@ -0,0 +1,103 @@
# Worktree 生命周期
## 适用范围
本规则管理预集成独立 worktree 从创建到安全移除的完整生命周期。主工作区不干净、用户要求不影响当前 checkout、当前分支被 IDE/服务/测试占用、需要复用旧预集成分支或预计发生冲突时,必须使用独立 worktree。
Worktree 只隔离工作目录;所有 worktree 共享仓库对象和本地分支引用。同一个本地分支不能同时被两个 worktree 签出。
## 生命周期状态
- `planned`:已确认仓库、分支、基准和绝对路径,尚未创建。
- `active`:worktree 已创建,开发、合并或验证正在进行。
- `delivery-ready`:差异和验证完成,等待本地交付确认或发布。
- `cleanup-ready`:本地交付已确认,或用户要求的发布已经完成,可以清理。
- `cleanup-blocked`:存在未提交内容、进行中的 Git 操作、引用风险或需要保留的现场。
- `removed`:额外 worktree 已移除,分支和提交仍存在。
## 创建和占用记录
创建前确认目标绝对路径不存在、目标分支未被其他 worktree 占用、基准引用可解析并记录完整哈希。分支名可能包含中文时始终加引号,不使用 `$HOME`、`$home` 或 `$CODEX_HOME` 作为任务变量。
创建后记录并报告:
- 主仓库绝对路径;
- worktree 绝对路径;
- worktree 当前分支和 HEAD;
- 主工作区当前分支、HEAD 和未提交状态;
- 该分支已被额外 worktree 占用,主工作区不能同时签出;
- 后续操作目录和生命周期结束后的清理义务。
## 新建或复用预集成
旧预集成已经合入目标分支时,默认新建增量预集成分支,使交付历史易于审计。只有用户明确选择复用,并且旧预集成可解析、上次源分支基线已包含、旧预集成与目标分支关系已查清、最终 `<target>...HEAD` 可收敛为本次需求文件时,才能继续复用。
历史中存在直接合入错误版本分支、无关需求或异常大量文件时,不得只因引用可解析就复用。复用时推荐先合入源分支最新增量,再合入最新目标分支;项目规范规定其他拓扑时以项目规范为准。
## 交付范围和结束条件
Merge 输出出现大量目标分支文件不等于 MR/PR 包含这些文件。必须检查:
```text
git diff --check "<target>...HEAD"
git diff --stat "<target>...HEAD"
git diff --name-status "<target>...HEAD"
git log --oneline "<target>..HEAD"
git log --first-parent --oneline -20
```
只有同时满足以下条件,生命周期才可进入 `cleanup-ready`:
- 本次开发或预集成已经完成;
- 用户要求的验证已经完成;
- 用户确认仅本地交付,或用户要求的发布已经完成;
- worktree 没有未提交或未跟踪文件;
- 没有进行中的 merge、rebase、cherry-pick 或 revert;
- 当前 HEAD 已被预期本地分支引用;
- 用户不再要求保留现场。
用户要求保留现场时标记为 `delivery-ready`,明确说明生命周期尚未结束以及分支仍被该 worktree 占用。
## 清理门禁
移除前展示主仓库和 worktree 的准确绝对路径、分支、HEAD、状态、分支引用验证和唯一清理命令。检查至少包括:
```text
git -C "<worktree>" status --porcelain
git -C "<worktree>" branch --show-current
git -C "<worktree>" rev-parse HEAD
git -C "<worktree>" rev-parse -q --verify MERGE_HEAD
git -C "<main-repository>" worktree list --porcelain
git -C "<main-repository>" branch --contains "<head-sha>"
```
`MERGE_HEAD` 不存在是预期结果。还要依据 Git 状态确认不存在 rebase、cherry-pick 或 revert;任一操作未结束时标记为 `cleanup-blocked`。
用户确认准确清理信息后执行:
```text
git -C "<main-repository>" worktree remove "<absolute-worktree-path>"
```
不得直接删除目录,不得默认使用 `--force`,不得为解除占用而删除或重置分支,也不得批量清理其他 worktree。
## 清理后验证
```text
Test-Path -LiteralPath "<absolute-worktree-path>"
git -C "<main-repository>" rev-parse --verify "<branch>"
git -C "<main-repository>" worktree list --porcelain
git -C "<main-repository>" status --short --branch
```
只有目录不存在、worktree 列表已释放占用、分支和提交仍存在、主工作区原有状态未变化时,才能标记为 `removed`。
## 分支已被占用
出现以下错误表示目标分支仍由额外 worktree 签出:
```text
fatal: '<branch>' is already used by worktree at '<path>'
```
继续在错误给出的 worktree 中操作,或者在其生命周期结束并通过清理门禁后移除。不得强制 checkout、直接删除目录或删除分支绕过 Git 的占用保护。