← 返回 Skill 列表
extension
分类: 效率与办公API Key 暂未确认

拉取 · 提交 · 推送(冲突交给人裁决)

Use when 需要把本地改动同步到远端(拉取/提交/push、同步仓库、提交代码、推送代码、pull then commit and push、远端不一致、本地落后或分叉),或整合冲突必须决定取舍时。触发词:拉取提交并push、同步仓库、提交并推送、push 代码、提交代码、git 同步、冲突怎么办、merge conflict。

person作者: Sxgx123hubOpenAPI

拉取 · 提交 · 推送(冲突交给人裁决)

把「拉取 → 提交 → 推送」做成一条可重复的机械流程,并把唯一需要判断力的环节——冲突取舍——留给用户。

核心原则:机器只做没有歧义的事。任何需要"选一个"的动作,都不许替用户选。

确定性内核:scripts/git-sync.sh(判断与升级策略就是下面这些规则;脚本只执行规则)。

铁律

  1. 冲突不裁决:只要脚本报 status=needs_decision(退出码 3),停下来问用户。不允许用 --ours/--theirs 一把梭、不允许把两边内容手工拼成"都能过"的版本、不允许 --skip。唯一例外:git 自己就解掉了(rerere 重放、非重叠自动合并)——那不算冲突。
  2. 未跟踪文件默认不入库:只 git add -u(已跟踪文件的修改)。未跟踪文件在报告里列出即可;要收进版本库必须显式 --include-untracked,且先跟用户确认。
  3. 永不 force push、永不 reset --hard、永不 clean:远端已有别人的提交时,覆盖或丢弃都不是"同步"。
  4. 先 fetch 再判断:本地 origin/* 引用可能是过期的,git status 会谎报"已是最新"(实测发生过,见下)。
  5. 冲突后不留半成品:脚本发现冲突会 git rebase --abort 回到干净态再退出。要就地手工解决冲突才用 --keep-conflict。

用法

# 正常同步(提交信息必填;有改动却没给 -m 会以退出码 6 拒绝)
bash scripts/git-sync.sh -C /path/to/repo -m "feat: 说明这次改了什么"

# 看清会发生什么、不真推
bash scripts/git-sync.sh -C /path/to/repo -m "..." --no-push

# 显式把未跟踪文件也纳入提交(先问过用户)
bash scripts/git-sync.sh -C /path/to/repo -m "..." --include-untracked

# 冲突时就地保留现场(默认是 abort 回干净态)
bash scripts/git-sync.sh -C /path/to/repo -m "..." --keep-conflict

最后一行固定输出 GIT_SYNC_RESULT <json>,直接解析它,别去 grep 人类可读输出。

| 退出码 | 含义 | 该做什么 | |---|---|---| | 0 | 已同步或本来无事可做 | 报告 sha 即可 | | 3 | 需要人工裁决(整合冲突) | 按下面「升级协议」问用户,不要自己动手 | | 4 | 前置条件不满足(detached HEAD / 有进行中的 merge·rebase / 无 upstream / 远端不可达 / push 被拒) | 先修前置条件,别硬来 | | 5 | 安全检查拦截(敏感文件待提交 / 子模块有未推送提交) | 把清单给用户,按他的决定处理 | | 6 | 有改动但没给提交信息 | 先写清楚这次改了什么,再跑一次 |

升级协议(退出码 3 时,问用户什么)

一次问清,别挤牙膏;不要贴整篇 diff:

  1. 一句话结论:哪个仓库、哪个分支、几个文件冲突、本地/远端各领先几个提交。
  2. 每个冲突文件一行:路径 + 冲突类型(both modified / both added / delete-modify / rename)+ 双方各自的意图(取各自 commit message 与几行关键 hunk,不要全文)。
  3. 给 2–3 个可执行选项,例如:① 保留本地改动、把远端提交 rebase 到本地之上;② 放弃本地改动取远端(需用户明确同意);③ 用户手工合并后重跑脚本;④ 改用 merge 保留分叉(当分支是多人共享时比 rebase 安全)。
  4. 等用户选。选完再动手、动完再推。

容易处理 vs 难以处理

  • 可以直接做完:本地领先(直接推);远端领先且本地无改动(快进);双方改的是不同文件/不同区域(git 自动合并);未跟踪文件(默认不动,只报告)。
  • 必须问用户:同一处内容冲突、删除/修改冲突、二进制文件冲突(.uasset/图片/模型)、子模块指针冲突、冲突文件超过 5 个、pull 时远端又变了导致二次冲突。
  • 判断不了就算难以处理——宁可多问一次,也不要替用户在两个语义之间选边。

常见错误(都实测过)

| 错误 | 现实后果 | |---|---| | git add -A 顺手把未跟踪文件提交上去 | 草稿、本地配置、备份文件被推上共享仓库(实测发生:一个 notes-untracked.txt 被当成"本地改动"提交了) | | 冲突时"两边都留"拼成新内容再推 | 这不是合并是发明语义,远端已收下错误内容,别人基于它继续开发 | | 信 git status 的"与上游一致" | 本地引用过期时的谎报;不 fetch 就下结论会漏掉远端提交 | | 冲突后把工作区丢那儿 | 半完成 rebase 会让后续所有 git 操作踩雷(脚本默认 abort 就是为了避免这个) | | 拿 git ls-files --others 的输出直接 git add | git 默认把含非 ASCII 的路径输出成 C 风格转义("Docs/\345\212\237..."),add 匹配不到 → 文件被静默漏掉、脚本照报成功(脚本已修:加 -c core.quotePath=false,失败项记进 untracked_add_failed;自测 S10 守着这条) | | push --force 解决被拒 | 覆盖他人已推送的历史,不可恢复 | | 子模块改了只推父仓库 | 父仓库指针指向子模块里不存在的提交,别人拉下来是坏的 |

自测

bash scripts/selftest.sh          # 建临时测试场,跑 7 个场景(含"冲突必须升级、未跟踪文件不得入库")

改了脚本或本技能后必须重跑;新增场景就加进 selftest.sh,不要靠嘴保证。