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),那就找到生成这个文件的代码路径,改生成逻辑,而不是改产物。
- 文件名包含环境/机器标识符(如
.lan.、.prod.、.c1.) - 同目录有明显模板文件(
.tmpl/.template后缀) scripts/或package.json里有 "render" / "generate" / "build:config" 关键字
有任何一条,就先检查 .gitignore,再动手。
一句话外卖
git status干净但文件在磁盘上,先查.gitignore——改的是渲染产物,下次 build 会覆盖,找到模板文件才是真正的 SSoT。