.gitignore 不生效的排查方法
.gitignore 不生效最常见原因:文件已被 Git 跟踪(需 git rm --cached 移出索引)。其他原因:规则语法错误、文件路径层级不对、有后续或更高优先级的 ! 取反规则覆盖。用 git check-ignore -v <文件> 定位匹配的规则行。
最常见的原因只有一个:文件已经被 Git 跟踪了。 .gitignore 只对"未跟踪"文件生效——已进索引的文件加进 gitignore 照样被跟踪。解决:git rm --cached <文件> 移出索引后提交。其次才是规则写法问题,用 git check-ignore -v 定位。
原因一:文件已被跟踪
# 移出索引但保留本地文件
git rm --cached secret.env
git rm -r --cached node_modules/ # 目录递归
git commit -m "停止跟踪已被 gitignore 排除的文件"
移出索引后忽略规则即可影响工作区中的未跟踪副本;提交是为了将停止跟踪的变更分享给其他克隆。
原因二:规则写法问题
# 匹配任何层级的 log 文件或目录
log
# 只匹配根目录下的 log
/log
# 只匹配目录
logs/
# 匹配所有 .log 结尾
*.log
# 只匹配 logs 直接子级,不含更深层
logs/*.log
# 匹配 logs 下所有层级
logs/**/*.log
原因三:规则被覆盖
后面的规则覆盖前面的,! 取反可能把你刚排除的又放行了:
*.log
# 这条让 important.log 不被忽略
!important.log
定位工具
git check-ignore -v path/to/file
# 输出:.gitignore:12:*.log path/to/file
# 含义:.gitignore 第 12 行的 *.log 规则匹配了它
已跟踪文件默认不参与 check-ignore,必要时用 --no-index 检查规则;-v 输出的否定规则(!)表示重新包含,不等于被忽略。git status --ignored 可总览全仓被忽略的文件。
常见问题(FAQ)
Q:为什么子目录里的 .gitignore 管不了别的目录?
设计如此:每个 .gitignore 只作用于它所在目录及其子目录。根目录的 .gitignore 才能覆盖全仓。
Q:全局 gitignore 不生效?
确认配置了路径:git config --global core.excludesFile ~/.gitignore_global;同样只作用于未跟踪文件。
Q:想让 Git 暂时忽略某个已跟踪文件的本地改动?
Git 没有可靠的“忽略已跟踪文件本地修改”开关,skip-worktree 主要服务于稀疏检出。配置文件可改成已跟踪模板和被忽略的本地覆盖文件。