Community编程与开发github.com

Ao — 分支同步更新

将分支与其基础分支保持同步——当分支未发布时使用变基,已发布时使用合并;自动解决机械化冲突,并在遇到语义冲突时展示双方差异并停止。

Ao — 分支同步更新 是什么?

Ao 是一个 Git 操作工具,专门用于将特性分支与其基础分支(如 main)同步更新。它自动判断使用变基(rebase)还是合并(merge):如果分支内容尚未发布到远程,则使用变基(重写本地提交历史);如果已发布,则使用合并(保留提交历史)。该工具的核心原则是区分“文本冲突”(可由工具自动解决)和“语义冲突”(需要人工判断业务意图)。对于文本冲突,如锁文件、自动生成文件或格式化差异,它会按照仓库规则自动解决并重新生成。对于语义冲突,如一方删除、另一方修改的文件(UD/DU),或双方修改同一逻辑的代码,它会展示双方的差异内容并停止,等待人工决策。Ao 从不推送或强制推送任何结果,也从不重写远程已存在的提交。

兼容平台✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/zheref/hatsu/tree/HEAD/surfaces/codex/ao

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

共享策略位置: docs/DISCOVERY.md、docs/WORKFLOW.md、 docs/LAUNCH-MIGRATION.md、docs/STANDALONE-ENTRY.md、docs/PROCESS.md、docs/using/README.md 和 docs/using/mirrors.md 属于解析后的 Hatsu 插件 根目录,而不是消费仓库。在已安装的仿射面上,使用 ten 打印的绝对根路径来读取这些文件(如果该技能不可用,则通过该技能重新解析)。下面的相对链接标识源位置;缺少消费仓库的 docs/ 副本并不表示缺少策略,且不得在目标仓库中触发重复归档。切勿复制或在目标仓库中凭空创建第二个策略。


Ao — 分支,已同步

性质:操作系。 将分支与其基础分支进行协调是对工作主体的 Git 操作,该工作主体不仅属于你,无论差异是由何种性质创造的。

将基础分支置于我之下,仅解决文本问题,然后将任何涉及含义的问题交给我处理。

Ao 是 $murasaki 的第一步,$aka 的第三步, 以及 $en 在 PR 落后时执行的步骤。它也可以独立调用。 其整个规范只有一个区分——文本与含义——以及一个拒绝:它从不推送它产生的结果。


0. 独立入口——已完备

Ao 直接读取检出目录而非调用者。 § 2 在操作任何内容之前读取当前状态,§ 3 根据是否有内容已发布来决定变基还是合并,并且 from <base> 通过 nen/workflow.json → branch.base 携带基础分支。 docs/STANDALONE-ENTRY.md § 4 将其列为已完备;适用的条款是 P1 —— 当没有组合技能运行它时,使用 $ten ao 来同步此阶段的先决条件(ten § 6)—— 以及基础分支解析到 已获取的 origin/ 引用,§ 3 已要求这样做。

独立调用不会放宽 § 6 的任何条款:一个语义冲突是 G5 停止点,展示双方差异,并且绝不能通过选择使运行继续的一方来解决。Ao 仍然从不推送、从不强制推送、也从不重写远程上已有的提交。

交还。 在预编排的运行流程中下一步是:需要分支保持最新的调用者 — $murasaki、$aka 或 $en。没有推入任何内容,并且如果任何受跟踪的路径发生了移动,则在本次同步之前获取的证据已失效。


1. 调用方式

$ao [from <base>]
nen parse ao --grammar "from [<base>]" --line "<调用内容,去掉 $ao 前缀>"

在 v0.3.0 版本已实体验证(docs/ab/ao.md § 2.1):from release/1.4 → base: release/1.4;单独的 from 解析时该子句不存在,退出码为 0。该子句锚定在一个字面量之后,原因记录在 $spiritual-message § 1 中。

如果不带子句,基础分支为 nen/workflow.json → branch.base,当该键或文件不存在时默认为 main。在获取之前要大声说出基础分支的名称——一个静默地针对错误基础分支进行同步的分支会产生没人能理解的差异。

缺失的参数或配置项会被询问并即时设置(missing-argument、missing-configuration;WORKFLOW.md § 4 询问、设置、继续)。

2. 先读取检出状态

nen wc classify --repo <path> --base <base> --json

在 v0.3.0 版本已实体验证(docs/ab/ao.md § 2.2),--json 在操作任何内容之前精确携带此技能所需的信息:state.branch、state.isTrunk、state.dirty、state.aheadOfBase、state.existingCommitSubjects[]、state.uncommittedPaths[]。

nen wc classify 的情况Ao 的操作
must-move — 在主干上拒绝。 没有需要同步的内容:主干就是基础分支。说明情况并将处理权交给 $breath 或 $tensho,根据情况选择
on-branch-dirty拒绝,并列出该命令打印的未提交路径。 在未提交的工作上进行合并或变基要么会被 Git 自身拒绝,要么会将工作埋入无人能解的冲突中。请先提交(使用 $kokusen)或有意暂存,然后重新运行
on-branch-clean继续执行 § 3

nen wc classify 不是冲突检测器,并且未完成的合并会被视为普通脏状态——已实体验证(docs/ab/ao.md § 2.2)。 在未解决的合并内部运行它会报告 on-branch-dirty,并将冲突路径计入“未提交的路径”中,而不提及正在进行的合并。因此,在分类之前先询问 Git 一次,不要查看磁盘上的 .git/(在链接的工作树中 .git 是一个文件):git rev-parse -q --verify MERGE_HEAD 解析成功,或 git rebase --show-current-patch 退出码为 0(变基停在某个补丁上:表示冲突或 edit 停止点),意味着先前的操作在此停止,本次运行报告该状态并且不启动任何操作——永远不要在它之上进行第二次操作,也绝不要从此处重新运行 wc catch-up,因为那将使用 Git 的默认消息提交一个合并,且无需重新验证构建(§ 5)。探测的其它结果:1(某个变基暂停但没有当前补丁,位于 break 或失败的 exec 处)不属于 Ao 处理范围,因此本次运行报告它并附上 Git 自己的 --continue / --abort 命令然后在此停止,绝不依赖 catch-up 来拒绝它(因为仍在使用 nen 0.18.0 或 0.18.1 的主机不会拒绝它,zheref/hatsu#182);128 表示没有变基,因此进行分类;其它任何情况留给 § 3 的未应答探测行处理。

3. 执行哪种操作——变基还是合并,由是否有内容已发布决定

当此分支上没有任何内容被发布时使用变基。当有内容被发布时使用合并。 重写可能已被其他人获取的提交是唯一会给他人带来额外工作的 Git 操作,本地层面绝不执行它。

nen wc catch-up --repo <path> --base <base> [--strategy rebase|merge|auto] [--dry-run] [--json]

该命令首先进行获取,然后做出决定,并且该决定是针对 origin 现在所说的内容做出的,而不是针对此检出上次听到的内容。auto(Ao 所传递的参数)在分支内容不在 @{upstream} 上时进行变基,否则进行合并;--strategy rebase|merge 仅在调用者有明确理由时才指定其中一种,并且该理由需大声说出。退出码 0 报告 {base, strategy, before, after, behindBefore, aheadBefore, noOp},并且 noOp: true 仍然会伴随两个 SHA 一起报告,绝不报告为“无需操作”。其他所有退出码,根据 nen v0.20.0 读取:

退出码含义Ao 的操作
1,附带一个 conflicted[] 非空的报告冲突;中止信息已打印§ 4 接管
3,一个 conflicted[] 路径全部位于 nen/contract.json 顶层 mechanical 块(v0.20.0)中的报告nen 归类为清单、变更日志或镜像的冲突;中止信息和每个类别的命令已打印,未执行§ 4 接管,将 nen 的分类和命令作为证据引用;§ 4 仍然会对每个路径自行分类
1,没有报告获取、状态或 HEAD 读取失败,变基或合并失败但没有冲突,或者 --continue 失败停止:逐字引用 nen 的 stderr 信息,说明树处于 Git 留下的状态;绝不执行 § 4
2,变基暂停在 break 或失败的 exec 处(v0.18.2)不是 Ao 发起的变基引用 nen 的信息,该信息指出了 git rebase --continue / --abort;绝不继续或中止它
2,变基探测 Git 未应答(v0.18.2)可能根本没有变基引用 nen 的信息并停止,不指定任何 Git 命令
2,其他任何情况在任何变更之前的拒绝:脏树、--base 被 Git 拒绝、--strategy 与进行中的操作不一致、Git 版本太旧不支持 --end-of-options、找不到仓库根目录逐字引用它并停止
任何其他退出码意外情况停止并引用它
  • strategy: merge → 分支存在于远程上 → 合并基础分支。
  • strategy: rebase → 未发布任何内容 → 分支在 origin/<base> 之上重放。

一个没有实际可基于内容的重放仍然会重写 SHA,这是预期的行为。 已实体验证:一个已经直接位于 origin/<base> 尖端的分支会回答 "Successfully rebased and updated" 并将 HEAD 从 c8826c7 移动到 84b0444 —— 相同的树、相同的消息、新的提交对象,因为变基重放了提交而没有注意到它不需要这样做。在此处且仅在此处是无害的:§ 3 仅对未发布的分支进行变基,因此被重写的提交是没有人获取过的。将其报告为“无需操作”则不是无害的 — § 7 询问基础分支及其解析后的 SHA,如果一个声称 没有变化 的运行却移动了 HEAD,那么后续对旧 SHA 的所有引用都会静默地出错。

说出命令选择了哪种策略以及原因,使用其报告中的一行,并指明刷新操作: "origin 已获取;该分支位于 @{upstream} 上,因此使用 strategy: merge,而非变基。"

在 nen 0.5 版本已退役,在 0.13 版本被取代。 合并部分曾经通过 nen pr cascade-main --repo <path> --trunk <base> --no-push 执行(在 v0.5.0,docs/ab/ao.md § Retired at nen 0.5 已实体验证),而变基部分在任何标志下都没有命令。现在两部分的执行者都是 nen wc catch-up,它从不推送。cascade-main 在 izanami 的自动化表中保留了它的 mutating 行(包含 --no-push),但不再是 Ao 调用的内容。

4. 在解决任何冲突路径之前,先对每个冲突路径进行分类

git -C <path> status --porcelain                    # 冲突行
git -C <path> diff --name-only --diff-filter=U      # 冲突路径,单独列出
git -C <path> ls-files -u                           # 每个路径有哪些阶段

已针对一个包含每种类型的构造夹具进行实体验证(docs/ab/ao.md § 2.4):

Porcelain种类存在的阶段
UU双方修改 — 双方都更改了同一个文件1 基础、2 我们的、3 他们的
AA双方添加 — 双方都创建了相同的路径2 我们的、3 他们的;无基础
UD / DU删除-修改 — 一方删除了另一方编辑的内容仅存续的一方
DD、AU、UA较罕见的类型;使用相同表格分类并命名它们按 Git 报告的方式

nen wc catch-up --json 在退出码为 1 或 3 时携带 conflicted[],每个未合并路径一个条目,包含 ours 和 theirs 逐字内容(并且,从 nen.wc.catch-up/v0.2 开始,包含 nen 的 class)。它不携带的是种类,因此仍需要阅读上面的 porcelain 表格,并且 § 6 会将 ours/theirs 精确地按照命令打印的方式展示。该命令自身的规则(它从不选择任何一方)是值得在相关处引用的:它从不选择任何一方。

在解决任何路径之前,先对每个路径进行分类,并打印表格。 一个先解决前三个冲突然后在第四个发现是语义冲突的运行,已经在开头三个冲突上消耗了维护者的信任。

5. 机械化冲突,或语义冲突

机械化冲突 — 解决方案是确定的,由仓库决定,而非由任何人选择:

  • 一个双方都追加内容的仅追加区域(导入块、.gitignore、变更日志列表) — 保留两者,按照文件自身约定的顺序;
  • 一个由仓库重新生成的生成文件或锁定文件(锁文件、快照、镜像) — 采用基础分支的版本并重新生成(Hatsu 镜像:bash scripts/surface_mirror_regenerate.sh),然后使用声明的构建进行验证(nen shu build;退出码表格见 $rasengan § 6);
  • 纯粹是格式或空白符差异,无行为变化;
  • 双方做出的相同更改。

Hatsu 版本冲突可能在一次干净的同步后仍然存在: 并行分支可能选择了相同的版本号。每次同步后,将两个实际的清单文件(.claude-plugin/plugin.json 和 .codex-plugin/plugin.json)与最新的基础分支进行比较。如果分支的版本等于或低于基础分支的版本,则在准备就绪之前将两者重新提升到严格高于该基础分支的相同版本;同时更新此工作中现有的 changelog.d/ 片段的版本行。这是 Hatsu 创作,不是自动的 nen wc catch-up 重新提升。在确定下一个版本后,运行 bash scripts/plugin_version_refs.sh --from <old> --to <new> --body-file <local-draft> 以列出跟踪的引用并起草行。添加 --write 以重写声明的跟踪形式以及无歧义草案行上的每个精确旧版本令牌;读取打印的 review 行,这些行保持不变。该辅助工具从不选择版本、重写生成的镜像或编辑远程 PR。使用上面的命令重新生成镜像,然后刷新因同步而失效的主体事实:

主体事实同步后重新推导
插件版本在提交提升后执行 git show HEAD:.claude-plugin/plugin.json 和 git show HEAD:.codex-plugin/plugin.json
头和基础提交在最终提交和获取后执行 git rev-parse HEAD origin/<base>
针对基础分支测量的数据(字节、差异、覆盖率、审查证据)针对该新的基础分支和最终的 HEAD 重新测量
Drive 行中的 PR 编号gh pr list --repo <owner/name> --state open --head <branch> --json number,url;使用返回的当前 PR
变更日志片段先决条件行针对同步后的依赖契约和此工作的实际先决条件重新测量

审查刷新后的本地草稿,然后使用 nen pr edit-body 作为远程写入器。 针对新的基础分支重新运行版本提升检查;原始分支点无法证明此比较。

语义冲突 — 任何人员必须优先选择一种意图而非另一种的情况。UD/DU 总是语义冲突:"已删除"和"仍在编辑中"是关于某事物是否存在的两种信念,没有合并算法能持有这种信念。UU 中双方更改了相同行为的,以及 AA 中两个文件并非同一文件的情况,也是如此。

**教科书案例,已实体验证(docs/ab/ao.md § 2.

…

[已截断]

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

相关技能