深入理解 .gitignore 的匹配语法与使用场景,掌握已跟踪文件的忽略方法和全局 gitignore 配置。

.gitignore — 告诉 Git 哪些文件不用管

项目中总有一些文件不需要纳入版本控制:编译产物、依赖包、本地配置、系统文件…….gitignore 就是用来声明哪些文件应该被 Git 忽略的。


一、为什么需要 .gitignore?

1
2
3
4
5
6
7
my-project/
├── .gitignore ← 忽略规则写在这里
├── src/ ← 源代码(需要跟踪)
├── node_modules/ ← 依赖包(不需要,可以重新安装)
├── dist/ ← 编译产物(不需要,可以重新构建)
├── .env ← 本地环境变量(敏感信息,绝对不能提交)
└── .DS_Store ← macOS 系统文件(跟项目无关)

不配置 .gitignore 的后果:

  • node_modules 几万个文件被跟踪,仓库体积爆炸
  • .env 中的密码/密钥泄露到远程仓库
  • .DS_StoreThumbs.db 等系统文件污染提交历史

二、基本语法

忽略规则格式

1
2
3
4
5
6
7
8
9
10
11
12
13
# 这是注释(以 # 开头)

# 忽略所有 .log 文件
*.log

# 忽略 build 目录
build/

# 忽略指定路径下的文件
config/local.json

# 忽略所有目录下的 .DS_Store
**/.DS_Store

核心规则一览

语法含义示例
*匹配任意字符(不含 /*.js 匹配所有 .js 文件
**匹配任意层级目录**/logs 匹配所有层级的 logs
?匹配单个字符file?.txt 匹配 file1.txt
[abc]匹配字符集[a-z].log 匹配 a.log、b.log
/路径分隔符build/ 只匹配目录
!取反(不忽略)!important.log 不忽略此文件
#注释# 这是注释

三、匹配规则详解

3.1 按扩展名忽略

1
2
3
4
5
6
7
8
# 忽略所有 .log 文件(所有目录)
*.log

# 忽略所有 .tmp 文件
*.tmp

# 忽略所有 .zip 压缩包
*.zip

关键:不带路径前缀的模式(如 *.log)会匹配所有层级的文件,等同于 **/*.log

3.2 按目录名忽略

1
2
3
4
5
6
7
8
# 忽略根目录下的 build 目录
/build/

# 忽略所有层级中名为 dist 的目录
dist/

# 只忽略 src 目录下的 temp
src/temp/
注意

build//build/ 的区别:前者匹配所有层级的 build 目录,后者只匹配根目录下的 build。

3.3 按具体路径忽略

1
2
3
4
5
6
7
# 忽略根目录下的特定文件
config/local.json
.env
.env.local

# 忽略指定目录下的文件
src/config/debug.js

3.4 双星号 ** 的用法

1
2
3
4
# 匹配任意层级
**/logs → logs/ a/logs/ a/b/logs/
a/**/z → a/z a/b/z a/b/c/z
**/*.js → 所有 .js 文件(等同于 *.js)

3.5 取反规则 !

1
2
3
4
5
6
7
8
9
# 忽略所有 .log 文件
*.log

# 但不忽略 error.log
!error.log

# 忽略所有文件,但保留 src 目录
/*
!src/

取反的限制:如果一个文件的父目录被忽略了,即使你用 ! 取反这个文件也不会生效。Git 不会进入被忽略的目录去检查里面的文件。


四、常见项目的 .gitignore 模板

Node.js 项目

1
2
3
4
5
6
7
node_modules/
dist/
.env
.env.local
*.log
.DS_Store
Thumbs.db

Java 项目

1
2
3
4
5
6
7
8
9
target/
*.class
*.jar
*.war
.idea/
*.iml
.settings/
.classpath
.project

Go 项目

1
2
3
4
5
6
7
*.exe
*.exe~
*.dll
*.so
*.dylib
vendor/
.env

获取模板:GitHub 提供了各种语言和框架的 .gitignore 模板:github.com/github/gitignore,可以直接复制使用。


五、已跟踪文件的忽略

.gitignore 只能忽略未被 Git 跟踪的文件。如果一个文件已经被 git add 过了,再写进 .gitignore 是没有用的。

解决方法

1
2
3
4
5
6
7
8
9
10
11
12
# 1. 先把文件从 Git 索引中移除(但保留本地文件)
git rm --cached 文件名

# 如果是整个目录
git rm -r --cached 目录名/

# 2. 写入 .gitignore
echo "文件名" >> .gitignore

# 3. 提交变更
git add .gitignore
git commit -m "chore: 将 xxx 从版本控制中移除"

git rm --cached 做了什么?

  • 从 Git 索引中移除文件(不再跟踪)
  • 不删除本地文件(文件还在磁盘上)
  • 下次 git add . 时,因为 .gitignore 的规则,不会再被加入

六、全局 .gitignore

有些文件在所有项目中都应该忽略(如 .DS_Store),每个项目都写一遍很麻烦。可以配置一个全局忽略文件

配置方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 创建全局忽略文件
# Windows
echo. > C:\Users\你的用户名\.gitignore_global
# macOS/Linux
touch ~/.gitignore_global

# 2. 写入常用忽略规则
# .DS_Store
# Thumbs.db
# *.swp

# 3. 告诉 Git 使用这个文件
git config --global core.excludesFile ~/.gitignore_global
# Windows
git config --global core.excludesFile C:/Users/你的用户名/.gitignore_global

三层忽略文件的优先级

1
2
3
4
5
项目 .git/info/exclude   →  最高优先(不共享,仅本地生效)
↑ 被覆盖
项目 .gitignore → 中等(共享给团队)
↑ 被覆盖
全局 core.excludesFile → 最低(个人通用规则)
文件位置是否共享适用场景
.git/info/exclude项目内不共享个人临时忽略
.gitignore项目根目录共享团队统一规则
core.excludesFile用户目录不共享个人通用规则

七、排查忽略问题

为什么某个文件被忽略了?

1
2
3
4
5
6
# 检查一个文件被哪条规则忽略
git check-ignore -v src/debug.js

# 输出:
# .gitignore:5:*.js src/debug.js
# → 被 .gitignore 第 5 行的 *.js 规则匹配

查看哪些文件被忽略

1
2
# 列出所有被忽略的文件
git ls-files --others --ignored --exclude-standard

强制添加被忽略的文件

1
2
# -f 强制添加(即使被 .gitignore 忽略)
git add -f config/local.json
慎用

-f 仅在你确定需要提交被忽略的文件时使用,通常不推荐。


八、实战:完整配置流程

新项目初始化时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 1. 创建 .gitignore(在第一次 commit 之前!)
cat > .gitignore << 'EOF'
# 依赖
node_modules/

# 构建产物
dist/

# 环境变量
.env
.env.local

# 系统文件
.DS_Store
Thumbs.db

# 日志
*.log
logs/

# IDE
.idea/
.vscode/
*.swp
EOF

# 2. 初始化并提交
git add .
git commit -m "chore: 初始化项目"

旧项目补充 .gitignore

1
2
3
4
5
6
7
8
9
10
# 1. 创建 .gitignore 并写入规则

# 2. 移除已跟踪但需要忽略的文件
git rm -r --cached node_modules/
git rm --cached .env

# 3. 提交
git add .gitignore
git commit -m "chore: 添加 .gitignore 并移除不应跟踪的文件"
git push

总结:.gitignore 速查卡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──────────────────────────────────────────────────────────┐
│ .gitignore 语法速查 │
├──────────────┬───────────────────────────────────────────┤
│ *.log │ 忽略所有 .log 文件 │
│ build/ │ 忽略所有名为 build 的目录 │
│ /build/ │ 只忽略根目录的 build │
│ **/logs │ 忽略任意层级的 logs 目录 │
│ src/temp/ │ 忽略 src 下的 temp 目录 │
│ !important │ 取反:不忽略这个文件 │
├──────────────┼───────────────────────────────────────────┤
│ 移除已跟踪文件 │ git rm --cached 文件 → 加入 .gitignore │
│ 全局忽略 │ git config --global core.excludesFile 路径 │
│ 排查忽略原因 │ git check-ignore -v 文件 │
│ 强制添加 │ git add -f 文件 │
└──────────────┴───────────────────────────────────────────┘