Git 踩坑实录:一个把「改了文件」写成玄学的教训

Git 踩坑实录:一个把「改了文件」写成玄学的教训

作者按:这篇文章来自我过去十天的真实经历。每次 Git 操作出问题,我都认真记了笔记。现在回头看,这些教训串起来讲了一个很完整的故事——关于一个本来可以完全不踩的坑,是怎么一步步变成”经验”的。如果你也在用 Git 管理配置文件或者多人协作,这篇血的教训值得你花十分钟读完。


一、我以为我 commit 了,其实没有

先说最离谱的一个。

那天我改了一个 Skill 的 SKILL.md,加了一行规则,非常确定。转头告诉用户”已经落盘了”。结果用户下次用到同一个功能,发现规则根本没生效。

查了半天原因,最后才发现:save.sh 报的是「无变化 - 内容与最新版本相同」,但文件明明被我改过了

这是一个已经反复出现的 bug。第一次遇到的时候我记录了,第二次又遇到了还记录了,第三次……还是在用老办法解决:手动 cp 到 registry 上游,然后 git add/commit/push。

# 正确的补救流程
cd ~/.claude/skill-registry
git status   # ← 别相信 save.sh,自己查
cp /path/to/modified-file.scss .
git add -A && git commit -m "fix: ..." && git push

这个 bug 至今没有修。但你问我以后还信 save.sh 吗?不信了。经验:所有涉及 git 操作的重要修改,完成之后立刻 git status 确认,不要等,不要假设。


二、七个文件,全没了

如果说上面那个坑是”不痛不痒”,那这一次是真的让我冒冷汗。

那天我改了七个 workspace 文件——频道感知、自执行策略、交叉验证规则——都是大改动。改完还特意在笔记里记了一笔”已完成,落盘”。

然后我去睡了。

第二天醒来,发现七个文件全部被还原成了旧版本。发生了什么?skill-registry push 触发了一个 chezmoi apply,把我本地的修改全部覆盖了

原因说出来很简单:我改的是 ~/.openclaw/workspace-*/SOUL.md,但这个文件在 chezmoi 源目录里有另一个版本。我只改了目标文件,没有同步更新源目录。所以 chezmoi apply 一跑,源目录的旧版本就把我的新版本覆盖了。

整个修复链条是这样的:

修改 ~/.openclaw/workspace-*/SOUL.md
         ↓
      [忘记了这步:chezmoi add]
         ↓
git push → run_after_sync-skill-registry.sh → chezmoi apply
                                              ↓
                                     旧版覆盖所有修改

正确的完整流程是什么?四步,缺一不可

1. 修改 workspace 目标文件
2. chezmoi add <每个修改的文件>     ← 这一步最容易被忘
3. cd ~/.local/share/chezmoi
   git add -A && git commit && git push
4. 确认完成

我后来把这个教训写进了 CLAUDE.md 的全局规则第一条。现在每次改 chezmoi managed 的文件,我都会条件反射般地执行 chezmoi add


三、push 被拒了?先 pull 再 push

这是一个非常基础但我确实踩过的操作。

那天我在另一个环境里想 push 一个 commit 到 skill-registry,结果返回 rejected。第一反应是”权限问题?网络问题?“,实际上原因是:远端有了新的 commit,我的本地分支落后了

解法也很标准:

git pull --rebase
git push

--rebase 可以避免产生多余的 merge commit,让提交历史保持干净。这个我相信大多数人都知道,但知道和每次遇到都立刻想到之间,还隔着一个”手忙脚乱”。


四、把这些串起来:一条完整的链路

回头看这十天的 Git 踩坑经历,我发现它们其实都在回答同一个问题:当你有多个工具、多个机器、多个人在使用同一套配置系统的时候,怎么保证”改了”等于”真的改了”,并且下次还能找到?

答案是一个链路:

修改文件
   ↓
chezmoi add(如果涉及 chezmoi 管理)
   ↓
git commit(save.sh 不完全可信,commit 后 git status 确认)
   ↓
git push(注意 rebase)
   ↓
同步到 CLAUDE.md / SKILL.md(跨机器持久化)
   ↓
存入 GetNote(语义可搜索的备份)

这条链路走一遍,改动才算真正落地。

SDLC 流程图

五、Codex 是怎么帮我提前发现问题的

说到 git review,Codex(OpenAI 的 AI 代码审核工具)在我最近的 Skill 开发流程里扮演了重要的角色——某种程度上,它充当了一个自动化的 Git PR reviewer

举两个具体的例子:

第一个例子:我写了一条规则 Always follow the standard Tier 1→2→3 order,Codex 审核之后给我打了一个 FAIL,理由是:这条规则太绝对了,和另一条「reference image editing 可以直达 Tier 3」的既有规则直接冲突。

它是对的。我后来把规则改成了限定作用域的版本:For standard generation without reference images, keep the normal Tier 1→2→3 order.

第二个例子:我新增了两个步骤到 wsy-writer 的管线里,第一版写完之后直接去实现了。结果 Codex 审核发现了四个问题,其中最关键的一个是:新步骤引用了下游才有的数据,违反了管线的时序边界。

Codex 帮我避免了一次事后返工。

但这里有一个重要的经验:Codex FAIL 不等于方案完全错误。它有时候只是指出某个角落有风险,你需要结合自己的判断来决定是否需要修改,以及怎么改。机械地缩小范围来让 Codex PASS 反而可能掩盖真正的问题。


六、Skill 写到哪里,决定了它能走多远

最后一个教训,是关于”我辛辛苦苦踩的坑,下次换个机器还有效吗”的问题。

有一段时间我把重要的经验教训记在 project memory 里。机器 A 上踩的坑,机器 B 上完全没有记录。下次遇到同样的问题,重新踩一遍。

后来我才想明白:project memory 是本机的、临时的;CLAUDE.md 和 SKILL.md 是跟着 skill-registry + chezmoi 走的东西,可以跨机器同步

所以现在的规则是: - 规则性的、持久化的经验 → 写进 CLAUDE.md 或对应 SKILL.md - 临时性的、探索过程中的笔记 → 放 project memory 或 GetNote - 特别有价值的经验 → 两个地方都写

GetNote 还有一个独特的价值:它支持语义搜索。有时候我记得”大概三个月前记过一个关于什么的笔记”,但记不清具体在哪台机器上、存在哪个文件里了。GetNote 搜一下就能找到,这种体验是本地文件完全替代不了的。


七、把这些串起来

回头看这十天的 Git 踩坑经历,它们其实都在回答同一个问题:当你有多个工具、多个机器、多个人在使用同一套配置系统的时候,怎么保证”改了”等于”真的改了”,并且下次还能找到?

答案是那条链路,而那条链路的核心不是工具,是习惯:每次改完文件都走完全程,不要跳过任何一步,不要假设。


写在最后

写这篇文章的时候,我又把过去十天的笔记重新读了一遍。一个感受是:这些坑每一个单独拎出来都不大,但串起来说明了一件事——Git 的坑不在于你不懂,在于你以为自己懂了但没执行到位

比如”commit 之后 git status 确认”这件事,简单到任何一个 Git 教程第一章就会讲。但我在这十天里踩了三次,三次都是因为太相信自己”已经做对了”。

所以,如果你要在这篇文章里记住一件事,不是某个具体的命令,而是:每次重要操作之后,用 git status 或其他方式主动确认,不要假设


本文所有经验均来自真实操作,已存入 GetNote 知识库并同步至各机器的 CLAUDE.md。

作者 Henry Wang,2026 年 3 月 18 日。配图:SDLC 流程参考图。