.gitignore 只对未跟踪文件生效;已提交文件需先执行 git rm --cached 忽略,再确保规则正确。斜杠位置影响匹配范围,调试用 git check-ignore -v 验证。

直接说结论:.gitignore 只能忽略「未被 Git 跟踪」的文件;已提交过的文件,加了规则也没用,必须先取消跟踪。
为什么 .gitignore 加了规则却还在 git status 里?
常见现象是:明明写了 *.log,但 app.log 仍显示为 “modified” 或出现在 git status 中。这是因为该文件早已被 git add 过、进入过暂存区,Git 已将其标记为“已跟踪(tracked)”。.gitignore 对已跟踪文件完全无效。
- 判断一个文件是否已被跟踪:运行
git ls-files --error-unmatch filename,若返回路径说明已被跟踪 - 已跟踪文件的修改、删除都会被 Git 记录,忽略规则不生效
- 新克隆的仓库中,该文件不会自动出现,但本地已有历史记录,所以规则不触发
如何真正忽略已提交的文件?
必须分两步:先让 Git 停止跟踪,再确保它被 .gitignore 捕获。
- 执行
git rm --cached <file></file>(如git rm --cached config.local.yml),这会从暂存区移除但保留在工作区 - 确认
.gitignore中有对应规则(例如config.local.yml或config.*) - 提交这次变更:
git commit -m "stop tracking config.local.yml" - 后续该文件的改动将不再出现在
git status中
注意:--cached 是关键参数,漏掉就会连本地文件一起删。
/ 开头、结尾、不加 / 的区别很关键
斜杠位置直接影响匹配范围,写错会导致规则失效或误伤:
-
logs/:只忽略名为logs的目录(及其所有内容),不忽略logs.txt文件 -
/logs/:只忽略项目根目录下的logs/目录,不忽略src/logs/ -
logs(无斜杠):同时匹配logs文件和logs/目录,且在任意层级(如build/logs也会被忽略) -
**/logs/:忽略所有层级中的logs/目录(推荐用于深度嵌套场景)
实际调试时,可用 git check-ignore -v filename 查看哪条规则命中、来自哪个 .gitignore 文件。
全局忽略 vs 项目级忽略 vs 本地临时忽略
三种方式适用不同场景,混用容易冲突:
- 项目共享规则 → 放
.gitignore(根目录),可提交,团队共用 - 纯本地不共享的忽略(如 IDE 临时文件、个人 debug 日志)→ 编辑
.git/info/exclude,不进版本库 - 全系统统一忽略(如 macOS 的
.DS_Store)→ 配置全局core.excludesfile:git config --global core.excludesfile ~/.gitignore_global,然后往该文件里写规则
优先级顺序是:命令行 > .git/info/exclude > .gitignore(就近) > 全局 core.excludesfile。同名规则以高优先级为准。
最常被忽略的其实是“已跟踪文件”的状态切换逻辑——不是加了规则就万事大吉,得先清缓存再补规则,而且斜杠位置一错,整个规则就跑偏。建议每次改完 .gitignore 都用 git check-ignore -v 验证一次。











