根本原因是.gitignore对已跟踪文件无效;配置文件一旦被git add过即进入“已跟踪”状态,后续合并时仍参与diff与提交,必须用git rm --cached解除跟踪并提交变更。

git merge 时为什么总把测试配置带进主分支?
根本原因是 .gitignore 不影响已跟踪文件。一旦某个配置文件(比如 config.local.json)被 git add 过,它就进入 Git 的“已跟踪”状态,此后无论你加多少条规则到 .gitignore,Git 都会继续监控、提交、合并它。
分支特有配置该放哪儿?别放项目根目录
直接把 dev.env 或 secrets.js 放在项目根目录下,等于默认邀请 Git 跟踪它们——尤其当团队用 git add . 时几乎必中招。
- 把分支专属配置放到
.git/info/exclude:只对当前仓库生效,不提交,适合临时调试用的密钥或路径 - 用模板文件 +
.gitignore组合:比如提供config.example.json,再在.gitignore加config.local.json,确保没人误提 - 避免在
main分支写死开发配置路径:有些框架(如 Next.js)会读.env.development,但它若被提交,就会随git merge feature/login一起进主干
如何让 Git 彻底“忘记”已跟踪的配置文件?
执行 git rm --cached <file></file> 是唯一可靠方式。注意不是 rm,也不是 --force ——--cached 表示只从索引删除,保留工作区文件,这样既解除 Git 管控,又不影响本地运行。
- 批量清理:用
git rm -r --cached config/删除整个目录的跟踪状态 - 确认是否成功:运行
git status,如果该文件不再出现在 “Changes to be committed” 区域,说明已脱离跟踪 - 必须提交这次变更:
git commit -m "stop tracking config.local.json",否则下次别人拉代码仍会继承旧状态
不同分支共用同一份 .gitignore,但配置逻辑要隔离
.gitignore 本身是普通 tracked 文件,所有分支共享一份。真正需要隔离的是“谁生成配置”和“谁读取配置”的逻辑。
- 用构建时环境变量区分行为:比如
process.env.NODE_ENV === 'production'才加载prod.config.js,开发分支即使含该文件也不会触发 - 禁止在代码里硬编码分支名判断:像
if (branch === 'dev') {...}会导致逻辑污染,CI 构建时容易出错 - CI/CD 中显式覆盖:GitHub Actions 可通过
secrets注入变量,而不是靠 Git 合并来传递配置
分支合并干扰的本质不是忽略没写对,而是混淆了“代码”和“配置”的生命周期。配置不该靠 Git 传递,而该靠部署时注入——这点比 .gitignore 写十行规则都管用。











