第8章:.gitignore —— 眼不见心不烦
10 分钟阅读
第8章:.gitignore —— 眼不见心不烦
有些东西,看见了就心烦。比如编译生成的文件、依赖目录、配置文件里的密码…Git 很聪明,但它不会读心术,不知道哪些文件不该提交。这时候,
.gitignore文件就是你的"黑名单"——告诉 Git:这些文件,请假装看不见。
8.1 哪些文件不该提交:密码、依赖、编译产物
在把文件加入 Git 之前,先问问自己:这个文件真的需要版本控制吗?有些东西提交上去,轻则污染仓库,重则泄露机密。
不该提交的文件类型
1. 依赖目录
node_modules/ # Node.js 依赖
vendor/ # PHP Composer 依赖
__pycache__/ # Python 缓存
- 为什么:依赖可以从 package.json 重新安装,没必要提交
- 后果:仓库体积爆炸,clone 慢到怀疑人生
2. 编译产物
dist/ # 构建输出
build/ # 编译结果
*.exe # 可执行文件
*.dll # 动态链接库
- 为什么:源代码才是真理,编译产物随时可生成
- 后果:冲突频发,仓库臃肿
3. 配置文件(含敏感信息)
.env # 环境变量
config.local.js # 本地配置
secrets.json # 密钥文件
- 为什么:包含密码、API 密钥等敏感信息
- 后果:密码泄露,被黑客问候
4. 日志文件
*.log # 日志文件
logs/ # 日志目录
npm-debug.log* # 调试日志
- 为什么:日志随时在变化,没必要版本控制
- 后果:无意义的提交记录
5. 操作系统生成的文件
.DS_Store # macOS
Thumbs.db # Windows
desktop.ini # Windows
- 为什么:系统文件,与项目无关
- 后果:跨平台协作时互相干扰
6. IDE/编辑器配置
.idea/ # JetBrains
.vscode/ # VS Code
*.swp # Vim 交换文件
- 为什么:个人偏好,不应强加给团队
- 后果:每个人的 IDE 配置不同,互相覆盖
提交前的检查清单
| |
8.2 node_modules:永远不要提交的庞然大物
node_modules 是 Node.js 项目的依赖目录,它是 Git 仓库的头号公敌。
为什么不要提交 node_modules?
1. 体积巨大
| |
2. 文件数量爆炸
| |
3. 平台差异
| |
4. 可以重建
| |
正确做法
| |
特殊情况:提交部分依赖
有时候确实需要提交某些依赖:
| |
8.3 .env 文件:你的秘密,别让全世界知道
.env 文件用于存储环境变量,通常包含数据库密码、API 密钥等敏感信息。这是绝对不能提交的文件。
为什么 .env 如此危险?
真实案例:
- 2016年,某公司将 AWS 密钥提交到 GitHub,被黑客利用,损失数万美元
- 某开发者将数据库密码提交到公共仓库,数据库被勒索
正确的环境变量管理
1. 创建 .env.example(模板)
| |
2. 创建 .env(真实配置,不提交)
| |
3. 配置 .gitignore
| |
4. 团队 onboarding 流程
| |
如果已经提交了 .env
| |
8.4 大文件陷阱:Git LFS 处理大文件
Git 不适合管理大文件(>100MB),但有时候确实需要版本控制一些大文件(如图片、视频、二进制资源)。这时候 Git LFS(Large File Storage)登场了。
什么是 Git LFS?
Git LFS 是 Git 的扩展,它将大文件存储在单独的服务器上,仓库中只保存指向这些文件的指针。
安装 Git LFS
| |
配置 Git LFS
| |
这会创建 .gitattributes 文件:
*.psd filter=lfs diff=lfs merge=lfs -text
assets/images/* filter=lfs diff=lfs merge=lfs -text
使用 Git LFS
| |
迁移现有大文件到 LFS
| |
Git LFS 的替代方案
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Git LFS | 大文件版本控制 | 与 Git 集成好 | 需要额外服务器 |
| 云存储 | 静态资源 | 便宜、快速 | 不在版本控制中 |
| CDN | 分发资源 | 全球加速 | 只读 |
| 专用资产管理 | 游戏/设计资源 | 专业功能 | 额外工具 |
8.5 .gitignore 语法:从入门到精通
.gitignore 文件使用特定的模式匹配语法,掌握这些语法,你可以精确控制哪些文件被忽略。
基础语法
| |
通配符规则
| 通配符 | 含义 | 示例 |
|---|---|---|
* | 匹配任意字符(除 /) | *.log 匹配 a.log, b.log |
? | 匹配单个字符 | ?.txt 匹配 a.txt, b.txt |
** | 匹配任意目录 | **/temp 匹配所有 temp 目录 |
[abc] | 匹配括号内任一字符 | [ab].txt 匹配 a.txt, b.txt |
[0-9] | 匹配范围 | file[0-9].txt 匹配 file1.txt |
! | 取反(不忽略) | !important.log |
高级用法
| |
双星号 ** 的用法
| |
注释和空行
| |
8.6 常用模板:Node.js、Python、Java、Go、Rust 一键复制
不同技术栈有不同的忽略模式。以下是常用模板,直接复制粘贴即可。
Node.js 项目
# Dependencies
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Production build
dist/
build/
# Environment variables
.env
.env.local
.env.*.local
# IDE
.idea/
.vscode/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Testing
coverage/
.nyc_output/
# Logs
logs/
*.log
Python 项目
# Byte-compiled
__pycache__/
*.py[cod]
*$py.class
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual environments
venv/
ENV/
env/
.venv
# IDE
.idea/
.vscode/
*.swp
# Environment variables
.env
.env.local
# Testing
.pytest_cache/
.coverage
htmlcov/
# OS
.DS_Store
Thumbs.db
Java 项目
# Compiled class files
*.class
# Package files
*.jar
*.war
*.ear
# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
# Gradle
.gradle/
build/
# IDE
.idea/
*.iml
*.ipr
*.iws
.classpath
.project
.settings/
# OS
.DS_Store
Thumbs.db
Go 项目
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool
*.out
# Dependency directories
vendor/
# Go workspace file
go.work
# IDE
.idea/
.vscode/
*.swp
# OS
.DS_Store
Thumbs.db
Rust 项目
# Build output
/target/
# Cargo
Cargo.lock
# IDE
.idea/
.vscode/
*.swp
# OS
.DS_Store
Thumbs.db
通用模板
# IDE
.idea/
.vscode/
*.swp
*.swo
*~
# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Logs
*.log
logs/
# Environment variables
.env
.env.local
.env.*.local
# Temporary files
*.tmp
*.temp
tmp/
temp/
获取官方模板
GitHub 维护了各种语言的官方 .gitignore 模板:
| |
8.7 已提交的文件怎么忽略?git rm --cached
文件已经提交了,现在想把它加入 .gitignore,该怎么做?直接加 .gitignore 是不够的,因为 Git 已经在追踪这个文件了。
问题现象
| |
解决方案
| |
详细解释
| |
批量处理
| |
注意事项
1. 团队协作时通知大家
| |
2. 历史记录还在
| |
8.8 全局 .gitignore:一次配置,所有项目生效
每个项目都有 .gitignore,但有些忽略规则是通用的(如 IDE 配置、OS 文件)。你可以配置全局 .gitignore,让所有项目自动生效。
配置全局 .gitignore
| |
推荐的全局配置
# IDE
.idea/
.vscode/
*.swp
*.swo
*~
# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Editor
*.sublime-project
*.sublime-workspace
优先级规则
Git 按以下顺序应用忽略规则(后面的覆盖前面的):
- 系统级(很少用)
- 全局(
core.excludesfile) - 项目级(
.gitignore) - 子目录(子目录的
.gitignore)
查看配置
| |
8.9 .gitignore 失效排查:为什么还是提交了?
有时候明明配置了 .gitignore,文件还是被提交了。这是怎么回事?
常见原因1:文件已被追踪
| |
常见原因2:规则写错了
| |
常见原因3:规则被后面的覆盖
| |
常见原因4:缓存未刷新
| |
调试 .gitignore
| |
检查清单
- 文件是否已被追踪?(
git ls-files | grep 文件名) - 规则语法是否正确?
- 是否有取反规则(
!)覆盖了前面的规则? - 路径是否正确(是否以
/开头)? - 是否需要清除缓存?
8.10 本章小结:提交前检查,别做那个泄露密码的人
本章我们学习了 .gitignore 的各种知识:
| 主题 | 要点 |
|---|---|
| 不该提交的文件 | 依赖、编译产物、配置文件、日志、OS/IDE 文件 |
| node_modules | 永远不要提交,用 package.json 重建 |
| .env 文件 | 包含敏感信息,绝对不能提交 |
| Git LFS | 管理大文件的解决方案 |
| 语法 | * ? ** ! 等通配符的用法 |
| 模板 | 各语言有官方模板,可以直接使用 |
| 停止追踪 | 用 git rm --cached |
| 全局配置 | core.excludesfile 配置全局 .gitignore |
| 失效排查 | 用 git check-ignore -v 调试 |
安全原则:
- 提交前检查:
git status看看会提交什么 - 敏感信息绝不提交:密码、密钥、token
- 提供模板:用
.env.example代替.env - 定期审计:检查仓库是否包含敏感信息
记忆口诀:
- 依赖目录 → 忽略
- 编译产物 → 忽略
- 配置文件 → 忽略
- 日志文件 → 忽略
- OS/IDE 文件 → 忽略
练习建议:
- 检查你的项目,看看 .gitignore 是否完整
- 使用
git check-ignore -v调试几个文件 - 配置全局 .gitignore,管理 IDE 和 OS 文件
下一章,我们将进入 Git 的核心特性——分支管理!