返回博客

git status 看不见你的修改?文件是渲染产物,找模板才是正解

写好修改、Edit 返回成功、cat 出来内容也对——然后 git status 一片干净,什么都没有。第一反应往往是"莫非 git 坏了"。实际上这个场景有一个更常见、更隐蔽的原因:你动的那个文件根本不在版本控制里,它是构建脚本从某个模板渲染出来的产物

更危险的是,你可能浑然不觉地继续往下走:确认内容没问题 → 提交不相关的其他文件 → 触发 CI 或本地 build → 构建脚本按模板重新渲染 → 你的改动被无声覆盖 → bug 复现,而你完全找不到原因。

现象

  • Edit 执行成功,磁盘上用 cat 可以看到新内容
  • git status 显示工作区干净,目标文件不在修改列表里
  • git diff HEAD -- <path> 报错:path exists on disk but not in HEAD(文件存在于磁盘,但从未入过版本库)
  • git status --untracked-files=all 也看不到它——说明不是"新建未追踪",而是被 .gitignore 主动屏蔽

根因

.gitignore 会同时屏蔽"已有变更"和"未追踪"两类文件的展示。对于渲染产物来说,这是有意为之:每次 build/release 脚本运行时,这些文件都会被从模板重新生成,包含机器特定路径、环境变量值、或平台差异内容,不应该也没有必要进入版本库。

典型的渲染产物包括:

  • Tauri / Electron 的多环境配置文件(tauri.conf.<env>.json
  • i18n 编译后的语言包
  • OpenAPI / proto 自动生成的客户端 SDK
  • Tailwind / PostCSS 的 dist/css/
  • Next.js / Vite 构建产物(.next/dist/

所以你编辑的那份文件,是下一次 build 会被覆盖的"快照",而不是源头。

坑:直接改渲染产物,下次构建无声覆盖

如果你不检查 .gitignore、不找模板,直接修改渲染产物并以为问题已解决,那么下一次有人运行 build 或 release 脚本,构建系统会从未动过的模板重新生成这个文件,你的修改消失得无影无踪,bug 重现,而 git history 里完全没有任何线索。

排查

用下面这个四步序列锁定真正的 SSoT:

# 1. 确认文件在磁盘上,但 git 看不见
ls -la <path>
git status --short --untracked-files=all <path>
git diff HEAD -- <path>
# 若报 "path exists on disk but not in HEAD" → 继续
 
# 2. 确认是 .gitignore 屏蔽,而非其他原因
grep -n "<文件名模式>" .gitignore
 
# 3. 找同级的 templates/ 目录或模板文件
ls $(dirname <path>)/../templates/ 2>/dev/null
find . -path ./node_modules -prune -o \
  -type d \( -name "templates" -o -name "template" -o -name "_templates" \) -print
 
# 4. 找渲染脚本
grep -rn "<文件名>" scripts/ package.json 2>/dev/null

一旦找到模板文件(常见扩展:.tmpl.template.hbs.ejs.mustache),接下来才是真正的修复入口。

正解

正解:改模板,不改渲染产物

定位到模板文件后,在模板上做修改,然后手动跑一次渲染脚本确认产物内容符合预期,最后只提交模板变更。渲染产物继续留在 .gitignore 屏蔽范围内,由 build 流程自动生成。

# 确认模板路径后,编辑模板
Edit templates/<name>.tmpl  # 或 .hbs / .ejs
 
# 手动触发渲染,验证产物内容
node scripts/render-config.mjs <args>
diff <渲染产物路> <你期望的内>
 
# 提交模板,产物不提交
git add templates/<name>.tmpl
git commit -m "fix: 在模板中修正 XXX 权限配置"

如果项目的渲染脚本就是 build 流程本身(没有独立 renderer),那就找到生成这个文件的代码路径,改生成逻辑,而不是改产物。

快速辨别渲染产物的三个信号
  1. 文件名包含环境/机器标识符(如 .lan..prod..c1.
  2. 同目录有明显模板文件(.tmpl / .template 后缀)
  3. scripts/package.json 里有 "render" / "generate" / "build:config" 关键字

有任何一条,就先检查 .gitignore,再动手。

一句话外卖

git status 干净但文件在磁盘上,先查 .gitignore——改的是渲染产物,下次 build 会覆盖,找到模板文件才是真正的 SSoT。