讲解
项目里总有些文件不该进仓库:依赖目录(node_modules/)、构建产物(dist/)、日志(*.log)、操作系统垃圾文件(.DS_Store)、编辑器配置、以及最重要的——密钥和本地配置(.env)。.gitignore 就是仓库根目录下一个纯文本文件,每行一条匹配规则,Git 会无视匹配到的未跟踪文件:它们不出现在 git status 里,git add . 也不会把它们加进去。
规则语法很直观:node_modules/ 匹配同名目录(结尾的斜杠表示目录);.log 用通配符匹配一类文件;/dist 开头的斜杠表示只匹配根目录下的 dist;build/**/.tmp 用 ** 匹配任意层级;在规则前加 ! 表示「不排除」,可以把被前面规则误伤的文件捞回来,比如 *.log 之后写 !keep.log。加注释用 # 开头。调试规则是否生效用 git check-ignore -v 文件路径,它会告诉你是哪一行规则起了作用。
一个关键限制:.gitignore 只对「未跟踪」的文件有效。如果某个文件已经被提交进历史,再往 .gitignore 里加规则是没有用的——Git 会继续跟踪它的修改。解决办法是先 git rm --cached 文件路径 把它移出跟踪(保留磁盘上的文件),提交这次移除,之后忽略规则才开始生效。所以项目初始化时就该把 .gitignore 写好,各语言生态都有成熟的模板(GitHub 官方维护的 gitignore 仓库可以直接抄)。
示例
演示仓库的 .gitignore 已经包含 node_modules/ 和 *.log 两条规则,看看它们的效果:
echo "调试输出" > debug.log
mkdir -p node_modules/leftpad
echo "module.exports = 1" > node_modules/leftpad/index.js
echo "构建产物" > dist.tmp
git status --short
git check-ignore -v debug.log node_modules/leftpad/index.js
printf 'dist.tmp\n*.tmp\n' >> .gitignore
git status --short
git status --ignored --short
前三个文件里,debug.log 和 node_modules/ 直接被忽略,status 只看到 dist.tmp;把 *.tmp 追加进 .gitignore 后,dist.tmp 也消失了。git status --ignored --short 则用 !! 标记列出被忽略的文件。
常见坑
- 先提交后忽略:文件一旦进过历史,加 .gitignore 无效,必须 git rm --cached 移除跟踪后规则才生效。密钥尤其要注意——它进过历史就可能已经泄露,删文件不够,要换密钥。
- 规则写错层级:dist 会匹配所有层级的 dist 目录,只想忽略根目录的要写 /dist。
- 把 IDE 个人配置提交进仓库:.idea/、.vscode/ 里的个人设置因人而异,通常忽略(或只提交团队共享的推荐配置)。
- 忽略规则不生效就先怀疑顺序:后面的规则覆盖前面的,! 例外要写在通配规则之后;用 git check-ignore -v 定位是第几行在起作用。
小结
.gitignore 用通配规则排除未跟踪文件,项目创建第一天就该写好;已跟踪文件要先 git rm --cached 才能被忽略;check-ignore -v 是调试规则的利器。下一节进入 Git 最强大的功能:分支。