Files
aerologic-app/.claude/skills/sync-air-cargo/SKILL.md
YANG JIANKUAN 5b217ab032 feat(sync-air-cargo): 以 Synced-From trailer 记录同步点,同步后自动在 air-cargo 本地提交
- 默认区间模式:基线取 air-cargo 最近的 Synced-From,目标为 main,内容取自提交对象
- 无记录时按内容反推基线(仅预览,apply 须 --base 确认),每次预览做基线校验
- 新增三方校验,列出将覆盖的 air-cargo 侧独立修改;分支/工作区/祖先关系保护
- --worktree 同步未提交变更且不推进同步点;提交信息仅「<Label> <日期>」+ trailer,不 push
- 新增 config(main → feature/hefei,air-cargo 位于项目根目录)
- 排除清单补充 .mcp.json、.claude.*、CLAUDE.local.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:20:55 -07:00

7.2 KiB
Raw Blame History

name, description
name description
sync-air-cargo 将 aerologic-app 的变更以文件级 cp/rm 方式同步到项目根目录下的 air-cargo/ 仓库并在其本地提交(不 push)——两者是同一份源码的两个独立 git 仓库副本,分别推送到不同的远程地址。同步点记录在 air-cargo 提交信息的 Synced-From trailer 中,自动从上次同步点同步到 main 最新提交(覆盖已提交未 push、已 push 的变更),也支持只同步未提交的工作区变更。只做文件复制/删除,不对内容做任何二次编辑或转换。每当用户提到"同步到 air-cargo"、"同步到另一个仓库/项目"、"推送/复制到 cargo 项目"、"两个项目要保持一致"、"把某几个 commit 同步过去",或者在 aerologic-app 里改完代码后问要不要同步/推送到另一个仓库时,应主动使用此 skill,而不是手动逐个 cp 文件。

同步变更到 air-cargo

背景

aerologic-app 和 air-cargo 是同一份项目源码的两个独立 git 仓库副本,分别推送到不同的远程仓库地址。日常开发只在 aerologic-app 中进行,完成后把变更同步到 air-cargo 并在本地提交,push 由用户自己做。

  • 位置:air-cargo 在 aerologic-app 根目录下(/Users/tim/Development/Projects/aerologic-app/air-cargo/),已在 aerologic-app 的 .gitignore 中忽略
  • 分支映射(config 文件):aerologic-app main → air-cargo feature/hefei。air-cargo 的 develop 是 2023 年的旧快照,不能往上同步;当前分支不是 feature/hefei 时脚本直接报错
  • 不参与同步:CLAUDE.md / CLAUDE.local.md、.claude/ 目录、根目录 .claude.*(如 .claude.local.md)与 .mcp.json(Claude Code 的配置/记忆),不复制也不删除。air-cargo 中不应存在任何 Claude / Agent 相关文件,其本地 .git/info/exclude 已屏蔽这些文件名,防止误提交
  • air-cargo 只是提交通道:不参与本项目开发,代码扫描、功能实现、查历史时都忽略它(见 CLAUDE.md「air-cargo 目录」一节)

同步点:air-cargo 提交信息里的 Synced-From trailer

每次同步提交的信息只有一句带日期的通用语句加一个 trailer,不写修改明细:

Update 20261012

Synced-From: aerologic-app@388d6058696c05cfd5892018f52120880a440524

脚本以 air-cargo 当前分支上最近一个 Synced-From 作为基线,把 基线..main 的变更同步过去。记录跟着 air-cargo 的提交历史走,只有真正提交了才算数。

  • 区间模式(默认):基线 = 最近的 Synced-From,目标 = aerologic-app main 最新提交。文件内容从目标提交对象中读取,与 aerologic-app 工作区无关,因此已 commit 未 push、已 push 的变更都用它。提交时写入新的 Synced-From
  • 工作区模式(--worktree):同步 aerologic-app 未提交的变更。提交信息不写 Synced-From,因为这份内容不对应任何提交,不能推进同步点。之后这些改动在 aerologic-app 提交后,下次区间同步会再覆盖一次(内容相同,无副作用)
  • 兜底:按内容反推:找不到 Synced-From 时(首次同步,或有人手工提交时丢了 trailer),在 main 的第一父链上找与 air-cargo HEAD 内容差异最少的提交作为候选基线。只用于预览,apply 必须显式传 --base
  • 基线校验:每次预览都会比较 air-cargo HEAD 和基线的内容。正常情况下只剩 air-cargo 自己的 6 个元文件:.gitignore(air-cargo 额外忽略 *.jks)、key密码、CONTRIBUTING.md、备忘录.md、国际出港进港权限对照表.xlsx、.docs/大写字母数字输入过滤器使用指南.md。超过 50 个会提示基线或分支可能不对

使用方法

cd /Users/tim/Development/Projects/aerologic-app
bash .claude/skills/sync-air-cargo/scripts/sync.sh [preview|apply] [--base <ref>] [--to <ref>] [--worktree] [--label <word>]
参数 说明
preview / apply 默认 preview,只打印计划;apply 复制/删除并在 air-cargo 本地提交
--base <ref> 指定基线:反推结果经确认后传入,或用来纠正错误的同步点
--to <ref> 指定目标提交,默认 main(只同步到某个较早的提交时使用)
--worktree 工作区模式,不能和 --base/--to 同时用
--label <word> 提交信息的通用词,默认 Update。用户要求时可换成 Fixed、Optimized 等

步骤

  1. 预览:先确定模式——用户要同步已提交的代码用默认区间模式;明确说的是"没提交的改动"才加 --worktree。然后执行 sync.sh(区间模式不加参数)。
    • 输出「无需同步」:直接告诉用户,结束
    • 基线来源是「按内容反推」:把候选基线连同基线校验结果一起拿给用户确认(反推可能取到比预期更早的提交,例如 air-cargo 从未同步过的环境配置提交),确认后加 --base <sha> 再预览一次
  2. 用 AskUserQuestion 确认,不要只在文字里问一句。问题描述里要包含:基线 → 目标、区间提交数、待复制/待删除数量(及主要模块分布)、「⚠ 将覆盖 air-cargo 侧独立修改」清单(逐个列出)、提交信息。选项至少包含「确认同步并提交」和「取消」。覆盖清单不为空时要特别说明这些文件是 air-cargo 自己改过的(如 .gitignore 里的 *.jks 忽略),由用户决定。
  3. 执行:把预览时的参数原样带上,preview 换成 apply。脚本会复制/删除文件、精确暂存这些路径并提交,最后输出提交号和变更统计。
  4. 不要 push。向用户报告提交号,并说明 air-cargo 比 origin/feature/hefei 超前几个提交,push 由用户自己做。

脚本的保护措施

  • air-cargo 当前分支不是 config 里的 TARGET_BRANCH → 报错
  • air-cargo 工作区有本次同步范围以外的未提交改动 → 报错;范围内的改动(例如上次同步还没提交)允许,重跑会覆盖成相同内容
  • 基线不是目标的祖先(aerologic-app 被 rebase / force-push 过)→ 报错,用 --base 重新指定
  • 区间内只有不参与同步的文件变化 → 仍然提交一个空提交,推进同步点

注意事项

  • 只同步 git 跟踪的内容,.gitignore 忽略的构建产物(build/、.gradle/)不会同步,air-cargo/ 本身也不在变更清单里
  • 不要在 air-cargo 里手动提交同步内容。如果确实手动提交了,trailer 格式必须完全一致(Synced-From: aerologic-app@<完整 sha>),否则下次只能走反推
  • 首个同步点:2026-10-12,air-cargo 3dd792f9,对应 aerologic-app 388d605(基线选 871fa4c)。跳过的 dda0ff8(vfox→mise)随后在 air-cargo 单独提交 3c76385b 补上:删除 .tool-versions / .vfox.toml / .vfox/,新增与 aerologic-app 相同的 mise.toml。这个提交不带 trailer,同步点不变
  • 两个仓库都用 mise 管理 JDK(mise.toml:java = "17")。air-cargo 位于 aerologic-app 之下,mise 会逐级读取配置,所以 air-cargo 里不能再出现 .tool-versions,否则会覆盖成未安装的旧版本