mcpField
A
aep-git-ref

aep-git-ref

github.com/memorysaver开发1858 次安装6 周前更新
代码仓库

关于 aep-git-ref

aep-git-ref 是 AEP Agent 工作流的 Git 与 worktree 规范参考,供其他技能和并行开发流程使用。它集中说明集成分支解析、worktree 生命周期、提交、PR 与恢复约定。

主要功能

  1. 01自动解析集成分支
  2. 02管理 worktree 生命周期
  3. 03规定分支命名与提交模式
  4. 04说明推送及 PR 约定
  5. 05提供 Git 故障恢复步骤

适用场景

  1. 01为并行 Agent 创建隔离工作区
  2. 02统一功能分支的提交与合并方式
  3. 03处理 worktree 或提交丢失问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/memorysaver/agentic-engineering-patterns --skill aep-git-ref

安装后在 Claude Code 中输入/aep-git-ref确认已加载。

详细介绍

Git + 工作树参考(AEP)

/aep-launch、/aep-build 和 /aep-wrap 使用普通 git 仓库和 git worktree 实现 Agent 并行隔离 — 这些技能提到“提交”时,指的就是 git commit。本技能是 AEP git 约定的权威来源:所有其他技能都会通过引用这里来解析 $BASE、创建/移除工作树和发起 PR,而不会重复写入这些代码块。选择普通 git 的理由(Agent 训练数据、通用工具):docs/decisions/migrate-from-jj-to-git.md。


集成分支

每项 AEP git 操作都针对集成分支 — 功能工作树从该分支创建、变基到该分支、向其发起 PR、合并到该分支;控制平面提交(/aep-dispatch、/aep-design、/aep-wrap 归档)也会落在该分支上。在本技能以及 /aep-launch、/aep-build、/aep-wrap 和产品上下文技能中的 bash 代码块里,此分支均记作 $BASE。

AEP 会自动检测以下两种模式之一 — 常见情况无需配置:

模式条件集成分支($BASE)生产分支
单分支(默认)不存在 develop 分支mainmain(同一分支)
双分支存在 develop 分支develop(暂存)main(仅用于发布)

只需创建 develop 分支,项目就能从单分支模式扩展为双分支模式 — 无需重新配置。在双分支模式下,AEP 绝不触碰生产分支(main):从集成分支发布到生产分支(develop → main)由用户负责,与部署一样,这本来就不属于 AEP 的范围。

解析 $BASE

每个涉及 git 操作的技能都会在首个 bash 代码块的开头解析集成分支:

# Resolve AEP integration branch ($BASE): override → auto-detect develop → main
BASE=$(git config --get aep.integration-branch 2>/dev/null || true)
if [ -z "$BASE" ]; then
  if git show-ref --verify --quiet refs/heads/develop \
     || git show-ref --verify --quiet refs/remotes/origin/develop; then
    BASE=develop
  else
    BASE=main
  fi
fi

解析顺序:

  1. 显式覆盖 — git config --get aep.integration-branch。这仅用于覆盖默认值,适用于非标准集成分支名称(例如 staging、integration)。标准的 main/develop 情况不需要设置 — 系统会自动检测。/aep-onboard 会报告检测到的模式,且仅在使用非标准名称时写入此配置项 (git config aep.integration-branch <name>;使用 git config --unset aep.integration-branch 取消设置)。
  2. 自动检测 — 如果本地或 origin 上存在 develop,则使用 develop。
  3. 默认值 — main(单分支模式)。

由于标准情况会自动检测(而非固定指定),项目可以无需重新配置,从单分支模式扩展为双分支模式:创建 develop 后,每项技能在下次运行时都会将 $BASE 解析为该分支。(如果你曾将 aep.integration-branch=main 固定为覆盖值,该设置会优先生效并阻止升级 — 因此设置过程不会固定默认值。)

git config --get aep.integration-branch 是仓库本地配置,通过共享的 .git/config 在所有工作树间通用,因此 $BASE 在主会话和任何 .feature-workspaces/<name> 工作树中解析结果一致。


工作树生命周期

创建
# Resolve $BASE first — see "Resolving $BASE" above
mkdir -p .feature-workspaces
git worktree add -b feat/<name> .feature-workspaces/<name> "$BASE"
  • 路径始终位于 .feature-workspaces/<name> 下(该目录已加入 git 忽略规则)。
  • 分支始终为 feat/<name> — 对应 OpenSpec 变更名称或故事 ID。
  • 基准始终为集成分支 $BASE。

工作树与主仓库共享 .git/objects,因此创建速度很快,且不会重复存储历史记录。只有工作树文件会在磁盘上重复一份。

检查
git worktree list                            # all worktrees, branches, paths
git -C .feature-workspaces/<name> status     # status inside a specific worktree
git -C .feature-workspaces/<name> log --oneline "$BASE"..HEAD   # commits unique to the feature branch
移除(/aep-wrap 第 6 步)
git worktree remove .feature-workspaces/<name>
git branch -d feat/<name>

如果 git branch -d 警告分支尚未完全合并(很可能是因为 PR 采用 squash 合并,导致提交 SHA 不同),请先通过 gh pr view <number> --json state 确认 PR 状态为 MERGED,然后使用 git branch -D feat/<name> 强制删除。

从损坏的工作区目录中恢复

如果 .feature-workspaces/<name>/ 被手动删除:

git worktree prune                           # forget the orphaned registration
git branch -D feat/<name>                    # delete the orphan branch (if needed)

如果 .git/worktrees/<name>/ 仍引用一个不存在的路径(例如,你移动了父目录):

git worktree repair .feature-workspaces/<name>

分支命名

分支模式创建方式
功能开发feat/<short-name>/aep-launch(每个故事一个)
迁移 / 杂项chore/<short-name>视情况手动创建
从 main 分出的热修复fix/<short-name>手动创建
迁移项目migration/<topic>手动创建

规则:

  • 斜杠后使用 kebab-case。不要使用空格或下划线。
  • 名称应简短(≤ 30 个字符)——它们会显示在标签、信号文件和 PR 标题中。
  • 工作区完全移除后,可以复用已删除的分支名(git worktree prune 会清除悬空引用)。

每项任务一个提交模式(/aep-build 的第 4 阶段)

内容

tasks.md 列出 N 项任务。功能分支最终会有 N 个提交,每项任务一个,顺序一致。采用 Conventional Commits 格式。工作区 Agent 线性实现任务,并在每项任务完成后提交,因此提交数与任务数一致:

# Implement task 1
# ... edit files ...
git add -A
git commit -m "feat(auth): extract auth service"

# Implement task 2
# ... edit files ...
git add -A
git commit -m "feat(auth): add token refresh flow"

# ... etc.

每次提交后,将短 SHA 记录到 .dev-workflow/feature-verification.json 中对应任务条目的 commit_sha 字段。

采用这种模式的原因
  • PR 的提交列表就像目录,与 tasks.md 中的任务一一对应。
  • 每个提交都是一个自包含单元,评估器(第 5 阶段)和审阅者(第 11 阶段)都可以单独执行 git show <sha> 查看。
  • 我们会在合并 PR 时使用 squash merge,因此每个提交的规范性只影响审阅时的可读性——集成分支的历史会自动保持整洁。
  • 这样无需在开发过程中重写历史,而这往往是 Agent 最容易出错的环节。
出现问题时的处理方式
情况操作
忘记在刚提交的任务中包含某个文件git add <file> && git commit --amend --no-edit(仅在下一项任务提交之前安全)
过了几个提交后才发现之前的任务有问题新增一个提交:fix(<scope>): correct <issue from task N>——历史保持只追加
审阅反馈或评估循环 FAIL新增后续提交:fix(<scope>): address review on <topic>
需要基于新的 origin/$BASE 更新git fetch origin && git rebase origin/"$BASE" && git push --force-with-lease origin feat/<name>
变基时发生冲突在工作树中解决冲突,然后运行 git add <files> && git rebase --continue。如果冲突纠缠不清,运行 git rebase --abort,并通过信号文件告知协调器。

推送重写后的分支时,使用 --force-with-lease,不要直接使用 --force:自上次获取以来,如果其他人已经推送了内容,lease 变体会安全地失败。


发布与 PR 约定

推送功能分支
# First push (after Phase 9 cleanup):
git push -u origin feat/<name>

# Subsequent pushes (review fixes, rebases):
git push origin feat/<name>
# or after a rebase:
git push --force-with-lease origin feat/<name>
打开 PR — 务必显式设置 base
# $BASE is the integration branch — resolve it first (see "Integration Branch" above)
gh pr create --base "$BASE" --title "<title>" --body "<body>"

--base "$BASE" 标志是必需的:如果不设置,gh 会根据本地分支状态推断 base(一次 dispatch 提交可能会被视为最近的 base),导致 PR 合并到非集成分支,代码也就永远不会进入 $BASE。在双分支模式下,推断出的 base 可能是生产分支 main,而 AEP 绝不会将功能工作合并到该分支。

合并 PR
gh pr merge <number> --squash --delete-branch

我们始终使用 squash 合并。功能分支上针对各项任务的提交会合并为一条提交,进入集成分支($BASE),这样既能让日志保持易读,也能在 PR 的 “Commits” 选项卡中保留各项任务的审查记录。


控制平面提交(在集成分支上)

/aep-design、/aep-dispatch、/aep-envision、/aep-map、/aep-calibrate、/aep-validate、/aep-reflect 和 /aep-wrap 的归档步骤都会直接提交到集成分支($BASE)。操作模式完全相同:

# Resolve $BASE first — see "Resolving $BASE" above
git pull --ff-only origin "$BASE"       # fail-fast if the integration branch has diverged
git add <specific-files>                # never -A on the integration branch; be explicit
git commit -m "<conventional message>"
git push origin "$BASE"

这里有意使用 --ff-only——它会拒绝非快进拉取,这意味着并发推送会被及时发现,而不会被静默合并。如果有人先推送导致拉取失败,请先获取更新,再对你的工作进行变基,然后重试。


恢复

丢失了提交(提交到了错误的分支,或通过 amend 将其移除)
git reflog                              # find the orphaned commit's SHA
git cherry-pick <sha>                   # bring it onto the current branch
# or
git reset --hard <sha>                  # if you want to rewind to that point
丢失了整个分支(使用 -D 删除)
git reflog                              # the deleted branch's tip is in here
git branch <name> <sha>                 # recreate the branch at that tip
丢失了已移除的工作树目录中的工作

如果你在提交前运行了 rm -rf .feature-workspaces/<name>,工作就会丢失——git worktree 只跟踪已提交的历史。.dev-workflow/ 文件(信号、经验教训、进度)也会一并丢失,因为它们被 gitignore 排除了。下次请使用 git worktree remove,而不是 rm -rf;如果工作树中有未提交的更改,该命令会拒绝执行。

变基后 OpenSpec 文件丢失

如果 dispatch 提交中的 OpenSpec 文件在变基或合并期间消失:

git log --oneline -n 30                 # find the dispatch commit SHA
git restore --source=<sha> -- openspec/

这会将 openspec/ 恢复为 dispatch 提交时的状态,不会更改其他内容。


磁盘空间预算

每个工作树大约会在磁盘上增加一份完整的工作树副本。所有工作树共享 .git/objects,因此不会重复存储提交历史。对于典型的 AEP 仓库(工作树约 100 MB,经过多年积累后 .git/objects 达数 GB),三个并发 Agent 会在共享的 .git/ 之外额外占用约 300 MB。

使用以下命令监控:

du -sh .feature-workspaces/             # working-tree footprint
du -sh .git/objects                     # shared history

如果 Agent 完成工作前磁盘空间不足,请优先暂停启动新的 /aep-launch,而不是强制移除正在使用的工作树。


速查表

你想要……运行
创建功能工作树git worktree add -b feat/<n> .feature-workspaces/<n> "$BASE"
列出所有工作树git worktree list
查看功能分支上的提交git log --oneline "$BASE"..HEAD
与最新的 $BASE 同步git fetch origin && git rebase origin/"$BASE"
变基后推送git push --force-with-lease origin feat/<n>
打开 PRgh pr create --base "$BASE"
合并 PRgh pr merge <#> --squash --delete-branch
合并后移除工作树git worktree remove .feature-workspaces/<n> && git branch -d feat/<n>
恢复已删除的提交git reflog 然后运行 git cherry-pick <sha>
恢复丢失的 openspec/ 文件git restore --source=<sha> -- openspec/

评论

支持 Markdown