如果你是 Git 新手,可能还不太理解一个现象:为什么很多项目的根目录下都有一个叫 .gitignore 的隐藏文件?
答案很简单——项目管理中,有些东西你永远不想被 Git 跟踪。node_modules 目录动辄几万个文件、编译生成的二进制文件、IDE 的配置文件、操作系统的隐藏文件……这些东西如果被提交到 Git 仓库里,不仅让仓库臃肿不堪,还会给团队协作带来各种莫名其妙的问题。
我自己刚开始用 Git 的时候就踩过这个坑:一个 Node.js 项目,commit 完之后发现 node_modules 被整个提交了,git push 推了半个小时还没完。后来只能硬着头皮 git rm --cached 挨个清理,教训深刻。
本文就带你从头到尾搞清楚 .gitignore 的完整用法,再结合 .gitignore 生成器 用最少的精力写出最完善的忽略规则。
什么是 .gitignore?理解它的工作原理
.gitignore 是 Git 仓库根目录下的一个纯文本文件。Git 在扫描工作目录时,会读取这个文件中的规则,自动跳过匹配的文件和目录,不对它们进行版本控制。
核心原则:.gitignore 只影响尚未被 Git 跟踪的文件。如果一个文件已经被 git add 或 git commit 过,即使后来在 .gitignore 里加了规则,Git 仍然会继续跟踪它。
这个原则是新手最常犯的错误来源。后面我们会专门讲怎么处理这种情况。
规则语法速查
写 .gitignore 本质上就是写模式匹配规则,语法和 shell 通配符很像。下面是所有你用得到的规则类型:
1. 注释和空行
# 以 # 开头的行是注释
# 空行被忽略,用来分隔不同区域
# 下面是 Python 项目的忽略规则
2. 最简单直接——指定文件名或目录名
# 忽略 node_modules 目录(以及子目录)
node_modules/
# 忽略所有 .log 文件
*.log
# 忽略根目录下的 .env 文件(不管子目录里的)
/.env
| 写法 | 含义 |
|---|---|
node_modules/ | 忽略所有叫 node_modules 的目录 |
*.log | 忽略所有 .log 后缀文件 |
/.env | 只忽略根目录下的 .env 文件 |
build/ | 忽略所有 build 目录 |
!important.log | 不忽略(排除)important.log |
3. 通配符
# * 匹配任意多个字符
*.pyc
# ? 匹配单个字符
temp?.txt
# [abc] 匹配括号中的任意一个字符
photo[1-3].jpg # 匹配 photo1.jpg, photo2.jpg, photo3.jpg
# ** 匹配任意层级的目录
build/**/*.o # 匹配 build 下所有子目录中的 .o 文件
4. 反向排除——用感叹号「取消忽略」
# 忽略所有 .env 文件
.env
# 但保留根目录下的 .env.example
!.env.example
反向排除最常见的用途是:先忽略一类文件,再精准保留其中的个例。
实战:用生成器 30 秒搞定完美配置
理解了规则语法,接下来的问题就是:我要怎么一次性写出覆盖全面的 .gitignore?
答案是——不要自己写。GitHub 上有成千上万个成熟项目积累出来的模板,你只需要选一下自己的开发语言和框架,让 .gitignore 生成器 帮你拼好就行。
操作步骤
第一步:打开工具页面
进入 .gitignore 生成器,你会看到一个大大的多选面板,里面按语言分类列出了几十种模板。
第二步:选择你的技术栈
比如你正在做一个 Vue + Go 的全栈项目,编辑器用 VS Code,操作系统是 macOS,那么你需要勾选以下模板:
- Vue — 忽略
dist/构建产物、临时开发文件 - Go — 忽略编译后的二进制文件
- VisualStudioCode — 忽略
.vscode/配置中的用户特定设置 - macOS — 忽略
.DS_Store等系统文件
第三步:点击生成,复制结果
工具会自动合并你选中的多个模板,去重后输出一份完整的 .gitignore。复制内容到你的项目根目录下的 .gitignore 文件中。
真实项目示例
假设你生成的结果大概长这样:
# Vue
node_modules/
dist/
*.local
# Go
*.exe
*.exe~
*.dll
*.so
*.dylib
*.test
*.out
vendor/
# VS Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# macOS
.DS_Store
*.swp
*.lock
别小看这几行——你保存的这几行规则,背后是无数人踩过的坑。没有 node_modules/,你的仓库会被几万个文件撑爆;没有 .DS_Store,队友的 Git 每次 git status 都会看到一堆莫名其妙的变化。
新手最容易踩的 5 个坑
坑 1:文件已经被跟踪后才加 .gitignore
这是最最常见的错误。你做了以下操作:
git init
git add .
git commit -m "init"
# 突然发现 node_modules 也被 commit 了
# 赶紧补了个 .gitignore 加上 node_modules/
# 但 git status 一看——node_modules 还是在那里!
原因:文件一旦被 Git 跟踪(tracked),.gitignore 就不再生效。
解决方案:
# 从 Git 跟踪中移除 node_modules(不会删除本地文件)
git rm --cached -r node_modules/
# 重新提交
git commit -m "移除 node_modules,改用 .gitignore 管理"
最佳实践:在 git init 之后、第一次 git add 之前,就先配好 .gitignore。这是最简单省事的做法。
坑 2:以为 .gitignore 能阻止文件被推送
.gitignore 只管本地 Git 是否跟踪文件。如果有人把不该提交的文件 push 到远程仓库了,其他成员 git pull 之后,即使你的本地有 .gitignore 规则,那个文件还是会被下载到工作目录。
解决方案:如果已经推送上去了,需要用 git filter-branch 或 BFG Repo-Cleaner 从历史中彻底清理。
坑 3:把 .gitignore 写成了全局生效
.gitignore 默认只对当前仓库生效。如果你想让所有仓库都忽略某个文件(比如 macOS 的 .DS_Store),可以配一个全局的 .gitignore:
# 创建一个全局忽略文件
git config --global core.excludesfile ~/.gitignore_global
# 在里面写上全局规则
echo ".DS_Store" >> ~/.gitignore_global
坑 4:不知道 .gitignore 可以放在子目录
.gitignore 不一定要放在根目录。你可以把不同子模块的忽略规则分散到对应的目录下:
project/
├── .gitignore # 全局规则
├── frontend/
│ ├── .gitignore # 前端特有的规则
│ └── node_modules/
├── backend/
│ ├── .gitignore # 后端特有的规则
│ └── target/
└── docs/
子目录的 .gitignore 规则只影响该目录及子目录,而且优先级高于父目录。
坑 5:把 .gitignore 和 .gitkeep 搞混
.gitkeep 不是 Git 的官方功能,而是社区约定俗成的做法——因为 Git 不会跟踪空目录,如果你想保留一个空目录的结构,就在里面放一个空的 .gitkeep 文件。.gitignore 和 .gitkeep 是两个完全不同的东西,不要混淆:
# 保留 logs/ 目录结构(即使为空)
mkdir -p logs
touch logs/.gitkeep
# .gitignore 保证 logs/ 里的日志文件不被跟踪
echo "*.log" > logs/.gitignore
分技术栈的完整配置参考
下面给出三个最常见技术栈的 .gitignore 完整配置,你可以直接参考使用。
Node.js 项目
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.env
.env.local
.env.*.local
dist/
*.tsbuildinfo
.next/
cache/
coverage/
Python 项目
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
.venv/
*.egg-info/
dist/
build/
.eggs/
*.egg
.mypy_cache/
.pytest_cache/
Go 项目
*.exe
*.exe~
*.dll
*.so
*.dylib
*.test
*.out
vendor/
tmp/
当然,直接用 .gitignore 生成器 选一下你的技术栈就能自动生成,比自己手写靠谱多了。模板覆盖了 Java、Python、Node.js、Go、Rust、C/C++、Ruby、PHP、Swift、Kotlin、Flutter 等几十种语言和框架,支持多选组合,生成的规则来自 GitHub 官方维护的模板库。
进阶技巧
技巧 1:在 CI/CD 中动态切换 .gitignore
你可以为不同的环境准备不同的 .gitignore:
# 开发环境用开发版忽略规则
cp .gitignore.development .gitignore
# 生产构建时用生产版
cp .gitignore.production .gitignore
技巧 2:检查某条规则到底匹配了哪些文件
# 查看哪些文件会被忽略
git status --ignored
# 检查具体某条规则是否生效
git check-ignore -v path/to/file
技巧 3:临时忽略某个文件
如果你某个文件已经被跟踪,但只是暂时不想让它被修改影响到,可以用 assume-unchanged:
git update-index --assume-unchanged config.json
这不会修改 .gitignore,而是告诉 Git「这个文件假装它没变过」。
总结
.gitignore 虽然只是一个文本文件,但它是 Git 项目规范化的第一道防线。在项目初始化的时候花 30 秒配置好 .gitignore,能省去后面数小时的清理工作。
用 .gitignore 生成器 选择你的技术栈,一键生成,然后根据项目实际情况微调。记住三个核心原则:
- 先配 .gitignore,再做 git add——这是最重要的一条
- 多选模板合并——语言 + 编辑器 + 操作系统全选上
- 被跟踪的文件不受 .gitignore 影响——用
git rm --cached来解决
配置好一个干净的 .gitignore,你每次 git status 看到的都是真正需要关心的文件变化,而不是被一堆垃圾文件刷屏。这就是专业开发者和平庸开发者的区别之一。