Skip to content

docs(skills): worktree 路径改为基于仓库根的绝对路径 (#336) - #341

Open
Casper-Mars wants to merge 2 commits into
Terry-Mao:mainfrom
Casper-Mars:task/w_01M6J6HY9W7DW3CYVWGG4HP6P4
Open

Casper-Mars wants to merge 2 commits into
Terry-Mao:mainfrom
Casper-Mars:task/w_01M6J6HY9W7DW3CYVWGG4HP6P4

Conversation

@Casper-Mars

Copy link
Copy Markdown

Fixes #336

Summary

git-worktree 的 SKILL 把目标写成相对路径 .worktrees/<branch-name>,既没要求先确认在仓库根,也没用 git rev-parse --show-toplevel 构造路径。在 monorepo 子目录(如 packages/app)调用会建到 <subdir>/.worktrees/:根目录的 ignore 规则覆盖不到,形成未跟踪的嵌套 worktree,且报告里的 cd .worktrees/<branch-name> 指引失效。

Testing

fixture B:monorepo(main + 远端 origin/main + 根 .gitignore 含 .worktrees/),在 packages/app 子目录里执行;测试片段全部从 SKILL.md 现场抽取后顺序执行(占位符 <branch-name> 替换为 feat/demo-336)。

########## fixture B:在 packages/app 子目录执行
pwd = /tmp/…/mono/packages/app
从 SKILL.md 抽取的片段行数:48
repo_root   = /tmp/…/mono
target      = /tmp/…/mono/.worktrees/feat/demo-336
PASS: repo_root 是仓库根而不是子目录
PASS: 根目录 .worktrees/feat/demo-336 已创建
PASS: packages/app/.worktrees 不存在
PASS: git status --porcelain 无新增未跟踪条目
PASS: worktree HEAD == origin/main
PASS: cd 指引可用(worktree 自身即 toplevel)

########## 边界 1:目标已存在 → 不覆盖、非零退出
Worktree target already exists: /tmp/…/mono/.worktrees/feat/demo-336
Pick another branch name, or remove the existing worktree yourself; this skill never overwrites.
PASS: 重复创建非零退出
PASS: 明确报错拒绝覆盖
PASS: 已存在的 worktree 未被改动

########## 边界 2:不在 git 仓库内 → 明确报错、非零退出
fatal: not a git repository (or any parent up to mount point /)
Not inside a Git repository; run this from a repository checkout.
PASS: 非仓库内非零退出
PASS: 报错文案明确

########## 边界 3:.worktrees/ 未被忽略 → 只提示,不改 .gitignore
warning: /tmp/…/mono2/.worktrees/feat/demo-336 is not covered by .gitignore
Add '.worktrees/' to the repository root .gitignore before creating the worktree.
PASS: 未忽略时仍可创建(只警告)
PASS: 未自行修改 .gitignore

结果:ALL FIXTURES PASS(脚本 exit 0)

仓库回归(python:3.12-slim + git,Python 3.12.16,与 CI 同版本):

$ python3 -m unittest discover -s .github/aicodingflow-tests   → exit 0,Ran 526 tests … OK
$ python3 -m unittest discover -s .github/tests                → exit 0,Ran 14 tests … OK (skipped=12)
$ python3 -m py_compile .github/scripts/*.py                   → exit 0

Risk

How to revert

Revert 本 PR 的 merge commit;无数据、配置或安装脚本迁移。

echuan-agent added 2 commits November 4, 2026 06:28
原因:git-worktree 把 base 硬编码为 main,默认分支是 master/trunk 的仓库
要么选错(陈旧 main)要么选不到(无 main);两处各自表述也必然漂移。

改动:
- git-branch 新增 ## Base 段作为唯一事实源:documented base → origin/HEAD →
  用户指定 → main 兜底,每级先用 git rev-parse --verify --quiet 校验 ref
- 给出可执行片段 ref_exists / resolve_base
- git-worktree base 段改为引用 git-branch 规则,片段逐字节复制;
  创建时 origin/<base> 优先、其次本地 <base>;解析失败列候选、提示
  --base <branch>、非零退出,禁止静默按不存在的 main 继续

验证:fixture A(master 默认分支 + origin/HEAD + 无 main)worktree HEAD ==
origin/master;陈旧 main 不误选;无可用 base 非零退出;两文件片段 diff 为空;
.github 两个 unittest 目录 533 + 14 条全绿
原因:SKILL 把路径写成相对 `.worktrees/<branch-name>`,在 monorepo 子目录
(如 packages/app)调用时会建到 `<subdir>/.worktrees/`:根目录 ignore 覆盖不到,
产生未跟踪的嵌套 worktree,且报告里的 `cd .worktrees/...` 指引失效。

改动:
- 新增 ## Repository root 段:先 `git rev-parse --show-toplevel` 取根,
  非仓库内明确报错并非零退出,不回落到相对路径
- Naming / Create 的目标改为绝对路径 "$repo_root/.worktrees/<branch-name>"
- 边界:目标已存在不覆盖并非零退出;`git check-ignore -q` 只提示不改 .gitignore
- Report 段 cd 指引改为 `cd "$repo_root/.worktrees/<branch-name>"`

验证:fixture B(packages/app 内执行)根目录建出 worktree、
子目录无 .worktrees、git status --porcelain 为空、worktree HEAD == origin/main、
cd 指引可用;非仓库内报错退出;重复创建拒绝覆盖;未忽略时只警告

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: 从仓库子目录调用 git-worktree 会把 worktree 创建到错误目录

1 participant