忽略特殊文件
.gitignore介绍
在使用 Git 的过程中,我们希望不提交工作目录中的一些文件,比如日志,临时文件等。就可以在 Git 工作区的根目录下创建一个特殊的 .gitignore
文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
另外我们不需要从头写 .gitignore 文件,GitHub 开源了一个项目:github/gitignoreopen in new window,里面已经提供了很多模板。
.gitignore 忽略文件的原则是:
- 忽略操作系统自动生成的文件,比如缩略图等;
- 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如 Java 编译产生的
.class
文件; - 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
.gitignore 忽略规则的优先级 在 .gitingore 文件中,每一行指定一个忽略规则,Git 检查忽略规则的时候有多个来源,它的优先级如下(由高到低):
- 从命令行中读取可用的忽略规则【优先级高】
- 当前目录定义的规则
- 父级目录定义的规则,依次递推
$GIT_DIR/info/exclude
文件中定义的规则core.excludesfile
中定义的全局规则【优先级低】
.gitignore匹配语法
在 .gitignore 编写规则,一行即一条规则,不区分大小写。
符号 | 说明 |
---|---|
空格 | 不匹配任意文件,可作为分隔符,可用反斜杠转义 |
# | 以 # 开头的是注释,都会被 Git 忽略,可以使用反斜杠进行转义 |
/ 开始 | 以 / 开始则匹配绝对路径,只从项目根目录开始进行匹配;不以 / 开始则是匹配相对路径,会递归进行匹配如: frotz 匹配 frotz 、 a/frotz ;/frotz 只匹配 frotz ,不匹配 a/frotz |
/ 结束 | 以 / 结束则只匹配目录以及在该目录里面的内容,不匹配该文件;不以 / 结束则匹配目录、目录下的内容,和文件 |
* | 通配符,匹配多个任意字符 |
** | 匹配任意中间目录 |
? | 通配符,匹配单个任意字符 |
[] | 匹配任何一个列在方括号中的字符。比如 [abc] 表示要么匹配一个 a,要么匹配一个 b,要么匹配一个 c |
[0-9] | 在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配 |
! | 非,取反的意思,即不忽略匹配到的文件或目录 注意:如果文件的父目录已经被已有的规则排除掉了,那么再对里面的子文件用 ! 规则是不起作用的 |
以上特殊字符如果出现在文件或目录名中,可使用 \
反斜杠进行转义。如:!\!important!.txt
TIP
git 对于 .ignore 配置文件是按行从上到下进行规则匹配的,意味着如果前面的规则匹配的范围更大,则后面的规则将不会生效。
校验规则是否生效
通过 git check-ignore
命令可以检查文件是否被 .gitignore 忽略。
命令格式:
git check-ignore [options] pathname…
options 选项:
1. -v 显示匹配的详细信息
2
3
4
例如:
$ git check-ignore -v A/t1
.gitignore:3:A/ A/t1
2
从打印结果可以看到,在 .gitignore 文件的第3行有一条 A/
的规则忽略掉了 A 目录下的 t1 文件。
特殊案例
只要A目录中的t1文件
场景:A 目录下包含 t1、t2、t3等文件,但是只需要跟踪 t1 文件,其他文件忽略。
正确规则如下:
/A/*
!/A/t1
2
错误案例:
/A/
!/A/t1
2
上面规则最后会发现 !/A/t1
并没有生效,t1 仍然被忽略掉了。
已经跟踪过的文件忽略规则不生效
现在,有文件 t1 之前已经 add 或 commit 跟踪过了,后面发现不需要对其进行跟踪,在 .gitignore 中加入过滤规则。在这种情况下,发现即使添加过滤规则后,文件 t1 仍然在被跟踪,没有被忽略掉。
场景一:t1 add 了,但是没有 commit。使用下面命令:
# 不写 pathname 则取消所有文件的 add
git reset HEAD pathname
# 重新 add
git add .
2
3
4
场景二:t1 已经commit了。
# 删除的本地缓存
git rm -r --cached .
# 重新 add
git add .
2
3
4
通过 git status
可以看到 t1 文件的状态为 deleted
参考资料
- .gitignore配置运维总结open in new window - 博客园
- Git 官方文档(gitignore):英文open in new window、中文open in new window