Files
atlas/git-sync/SKILL.md

4.8 KiB
Raw Blame History

name, description, category, metadata
name description category metadata
git-sync Use when 用户说"对xxx目录做一次 git 同步/提交推送/同步一下xxx"。对指定 git 仓库执行 pull→冲突检查→拟提交说明→commit→push 全流程。 custom
author last_updated
Hermes Agent 2026-09-15

Git Sync — 指定仓库一键同步

触发器:"对 xxx 目录做一次 git 同步" 或等效说法("同步一下 xxx 目录 / 提交推送 xxx")。目录无需是仓库根目录,脚本自动定位。

工作流

  1. 分析现状(必先做):

    bash ~/.hermes/skills/custom/git-sync/scripts/git-sync.sh <repo> status
    

    脚本会 fetch 远端并输出:ahead/behind 计数、未提交变更清单、diff --stat、未跟踪文件 —— 既是拟提交说明的依据,也用于判断是否分叉。

  2. 全流程同步(拟好提交说明后):

    bash ~/.hermes/skills/custom/git-sync/scripts/git-sync.sh <repo> sync -m "<提交说明>"
    

    自动执行:fetch → 仅落后则 pull --ff-only → add -A → commit → push → 打印提交 hash / 标题 / 文件统计 / 远端确认。

  3. 按退出码分支处理:

    • 3 DIVERGED(本地与远端分叉)→ 必须用 clarify 问用户选哪边:
      • merge 合并:resolve merge(产生合并提交,两边内容都保留)
      • 以远程为主:resolve remote(丢弃本地提交,破坏性)
      • 以本地为主:resolve local(force push 覆盖远端,破坏性)
    • 4 CONFLICT:先跑 git status 看冲突文件,向用户报告是"pull 时本地改动与远端更新冲突"还是"merge 后的 unmerged paths";按用户指示解决后(编辑文件 / 选边 / git add + git commit)再重跑 sync
    • 5 NO_CHANGES:如实报告"工作区干净、无变更",不硬造提交
  4. 汇报结果:提交短 hash(附长 hash)、标题、N files changed, X insertions(+), Y deletions(-)、push 远端确认行。

命令

命令 作用
git-sync.sh <repo> status fetch + 状态 + 变更摘要(拟提交说明用)
git-sync.sh <repo> sync -m "msg" 全流程同步,成功打印提交信息
git-sync.sh <repo> pull-ff 仅 fast-forward pull
git-sync.sh <repo> resolve merge|remote|local 分叉后的处理;remote/local 破坏性操作需 GIT_SYNC_CONFIRM=yes

退出码

码 含义
0 成功
2 参数错误 / 目录不存在
3 分叉,需用户决策(或 push 被拒需重新决策)
4 冲突(pull 被拒 / 存在 unmerged paths)
5 无变更可提交
6 非 git 仓库 / 分支无 upstream / 无远端
7 sync 缺 -m 提交说明
8 破坏性操作缺 GIT_SYNC_CONFIRM=yes

提交说明写法

  • 依据 status 输出的 diff --stat 与文件清单写,句式:<动词+对象>: <做了什么/为什么>,如 feat(blogwatcher): 新增企业 RSS 源并修正去重逻辑
  • 多文件混合改动时突出主体内容,不写 "update" 空话
  • 有破坏性变更或格式整体变化时在说明中点明

坑

  • 先 status 再 sync:提交说明必须基于真实 diff;直接盲跑 sync 无法拟说明
  • 本地有未提交改动且落后于远端时,ff pull 会失败(本地改动将被覆盖)→ 属冲突路径(码 4),去问用户,不要 stash 后盲推
  • sync 检测到 unmerged paths(git ls-files -u)会直接拒绝提交,先解决冲突
  • resolve remote(git reset --hard)与 resolve local(force push)都会丢内容,必须先经 clarify 拿到用户明确选择,脚本侧再加 GIT_SYNC_CONFIRM=yes
  • push 失败(码 3)通常是 pull 后又有人推了东西:重新 status,再走分叉决策
  • pull.rebase=true 的仓库(本机 nexus 即如此):有未暂存改动时 ff-only pull 必失败报 "cannot pull with rebase",哪怕与远端无文件重叠——先用 git diff --name-only HEAD origin/main 确认无重叠,再 git -c pull.rebase=false pull --ff-only,不必惊动用户。脚本遇此会自动打印 hint
  • push 报 could not read Username for 'http://<host>':远端是 HTTP 且本机无该 host 凭据(keychain 里存的端口对不上也照样失败)。同主机若跑了 Gitea SSH,改 git remote set-url origin ssh://git@<host>:2222/<owner>/<repo>.git 即可直推;改前先 git ls-remote <ssh-url> 验证有权限,改后 git push 并用 git ls-remote origin refs/heads/main 核对远端 hash
  • add -A 会把未跟踪的大目录一并提交(实测 node_modules 56MB / 5606 文件):status 里出现这类目录时先补 .gitignore(node_modules/、.DS_Store)再 sync,否则仓库历史被永久撑大
  • 脚本由其他技能/agent 复用时同样适用,别只当本技能专用