.gitignore 文件的匹配规则有哪些?
- 2026-01-28 10:43:00
- Git基础入门 原创
- 9
.gitignore 文件正是为了防止这类问题而生的。它通过一系列匹配规则,告诉 Git 哪些文件或目录不需要被纳入版本控制。掌握好这些规则,能让你的仓库保持整洁和安全。
常用 .gitignore 规则速查
如果你想快速解决问题,可以先从下面这些最常用的规则开始。每一条都对应一个高频场景,可以直接复制使用。
忽略所有 .log 后缀的日志文件:
*.log
忽略 node_modules 依赖目录:
/node_modules
忽略所有 .DS_Store 系统文件:
**/.DS_Store
忽略 dist 或 build 编译产物目录:
/dist /build
忽略 .env 配置文件,但保留一个示例文件:
.env !.env.example
.gitignore 基础匹配规则
.gitignore 文件的规则是逐行读取的,每一行都定义了一个匹配模式。理解最基础的语法是编写有效规则的第一步。
注释与空行
在 .gitignore 文件中,以井号 # 开头的行被视为注释,Git 会直接忽略它们。空行也会被忽略。清晰的注释和适当的空行可以让你的 .gitignore 文件更易于他人和未来的自己理解。
# 这是一个注释行,会被 Git 忽略 # 忽略 IDE 配置文件 .idea/ .vscode/ # 上下的空行也会被忽略
忽略特定文件
最简单的规则就是直接写入文件名。这会忽略仓库中所有路径下与该名称匹配的文件。
例如,要忽略所有名为 debug.log 的文件,只需添加一行:
debug.log
这样一来,无论是在根目录的 debug.log,还是在 src/logs/debug.log,都会被 Git 忽略。
忽略特定目录
忽略目录的写法和忽略文件完全一样,直接写下目录名即可。Git 会忽略该目录下所有的文件和子目录。
比如,要忽略所有名为 temp 的临时文件夹:
temp
使用通配符进行模式匹配
如果每次都要写出完整的文件名,效率会非常低。.gitignore 支持使用标准的 glob 模式(通配符),让规则更灵活。
*:匹配任意数量的字符
星号 * 是最常用的通服符,它可以匹配零个或多个任意字符,但不包括路径分隔符 /。
例如,要忽略所有以 .tmp 结尾的临时文件:
*.tmp
要忽略所有以 log 开头的文件:
log*
?:匹配单个字符
问号 ? 可以匹配除 / 之外的任意一个字符。当文件名只有个别字符不同时,这个规则很有用。
假设你有 image1.jpg, image2.jpg, image3.jpg 等文件,想忽略它们:
image?.jpg
[]:匹配指定范围的字符
方括号 [] 用于定义一个字符集,可以匹配其中任意一个字符。你可以用它来指定一个精确的字符列表,或者用连字符 - 来表示一个范围。
例如,[ab] 会匹配 a 或 b。[0-9] 会匹配任意一个数字。
# 忽略 version1.log, version2.log, ..., version5.log version[1-5].log
通配符 *, ?, [] 让模式匹配变得更加灵活,它们是编写高效 .gitignore 规则的基础。
用斜杠 / 精确控制路径
斜杠 / 在 .gitignore 规则中扮演着路径锚定的关键角色。它出现的位置不同,含义也完全不同,是区分初学者和熟练使用者的一个重要标志。
以 / 开头:仅匹配项目根目录
如果一个模式以 / 开头,那么它只会匹配项目根目录下的文件或目录,而不会递归匹配到子目录中。
# 仅忽略项目根目录下的 a.log 文件 /a.log
这条规则不会忽略 src/a.log。这在处理像 node_modules 或 dist 这类通常只存在于根目录的文件夹时特别有用,可以避免误伤子目录下的同名文件。
以 / 结尾:明确指定为目录
如果一个模式以 / 结尾,那么 Git 会明确地将这个模式识别为目录。这意味着只有同名的目录会被忽略,而同名的文件则不会。
# 忽略所有名为 build/ 的目录 build/
这条规则会忽略任何路径下的 build 目录,但如果有一个名为 build 的文件,它将不会被忽略。这是一种更严谨的写法。
路径中间的 /:定义多级目录
当 / 出现在模式的中间时,它就作为路径分隔符,用于定义更深层次的匹配规则。
# 仅忽略 src/assets/images 目录 src/assets/images
高级匹配规则
掌握了基础和路径规则后,还有两个强大的高级规则能让你应对更复杂的场景。
!:反转忽略规则
感叹号 ! 用于创建例外规则。如果你想忽略一个目录下的绝大多数文件,但又希望保留其中的个别文件,! 就派上用场了。
需要注意的是,一个文件如果已经被前面的规则排除了,那么后续的 ! 规则必须重新包含它的父目录,才能生效。
# 1. 忽略所有 .md 文件 *.md # 2. 但不忽略 README.md !README.md
一个更复杂的例子:忽略 logs/ 目录,但保留 logs/important.log。
# 错误写法: # logs/* # !logs/important.log # 这不会生效,因为 logs/ 目录本身已经被忽略了 # 正确写法: logs/* !logs/ logs/important.log
正确的做法是先用 !logs/ 将目录本身从忽略规则中排除,然后再排除目录下的所有文件 logs/*,最后再用 !logs/important.log 将目标文件排除。但这种写法比较复杂,通常有更好的方式。
一个更简单且推荐的做法是,先忽略目录下的所有内容,再单独取消忽略某个文件。
# 推荐写法: # 忽略 logs 目录下的所有内容 logs/* # 但不忽略 logs/important.log !logs/important.log
**:匹配多级目录
双星号 ** 是一个更强大的通配符,它可以匹配任意层级的目录,包括零层。
如果 ** 单独出现,它代表所有目录。如果它出现在路径模式中,它会匹配 0 个或多个目录。
# 忽略所有目录下的 a.txt 文件 **/a.txt
这个规则会匹配 a.txt, src/a.txt, src/components/a.txt 等。
为什么我的 .gitignore 规则不生效?
这是最令人困惑的问题之一。当你确定规则写得没错,但 Git 依然我行我素时,原因通常只有以下几种。
原因一:文件已被 Git 跟踪
.gitignore 文件只对尚未被 Git 跟踪(untracked)的文件生效。如果一个文件已经被 git add 和 git commit 纳入了版本库,那么后续再将它添加到 .gitignore 中是无效的。Git 会继续跟踪这个文件的变动。
如何诊断:使用 git status 查看文件状态。如果文件出现在 Changes to be committed 或 Changes not staged for commit 区域,说明它已经被跟踪了。
如何解决:你需要先从 Git 的暂存区(索引)中移除它,但保留本地的物理文件。
# 停止对 a.log 文件的跟踪,但保留本地文件 git rm --cached a.log # 如果是目录 git rm -r --cached logs/
执行完上述命令后,再将 .gitignore 文件的修改和这次移除操作一起提交,问题就解决了。
原因二:规则优先级被覆盖
.gitignore 的规则有明确的优先级。简单来说:
- 后面的规则覆盖前面的规则:在同一个 .gitignore 文件中,如果多条规则都能匹配到同一个文件,最后面的那条规则会生效。这就是为什么 ! 例外规则通常写在后面。
- 更具体的规则优先于宽泛的规则:例如,src/a.log 比 *.log 更具体,它的优先级更高。
- 项目内的 .gitignore 优先于全局配置:Git 存在多个层级的忽略配置,包括仓库级的 .git/info/exclude 和用户全局的 ~/.gitconfig。但最常用也最优先的是项目根目录下的 .gitignore 文件。
如果你发现规则不生效,可以检查是否有其他规则在后面覆盖了你的设定。
原因三:空格或语法错误
有时候问题出在一些不起眼的细节上。
如果你的文件名或目录名本身包含空格,你需要用反斜杠 \ 进行转义。
# 忽略名为 "my file.txt" 的文件 my\ file.txt
此外,检查一下规则前后是否不小心加入了多余的空格,虽然大部分情况下 Git 会处理,但在某些边缘场景下可能会导致非预期的行为。
.gitignore 最佳实践
- 使用官方模板:GitHub 维护了一个包含各种语言和框架的 .gitignore 模板库。在创建新项目时,直接从中选用或组合,是最佳的起点。
- 尽早创建 .gitignore:在项目的第一次提交(Initial Commit)时就加入 .gitignore 文件,可以从根源上避免将不必要的文件提交到仓库。
- 保持注释清晰:对于不那么直观的规则,添加注释说明它的作用,方便团队协作。
- 只忽略生成文件:.gitignore 的核心原则是忽略那些由源码自动生成的文件(如编译产物、日志、依赖包),而不应该忽略源码本身。所有需要团队成员共享和协作的文件,都应该被跟踪。
| 联系人: | 郑女士 |
|---|---|
| 电话: | 13792883250 |
| Email: | zhengqiaoyin@cnezsoft.com |
