# Git忽略提交.gitignore

> 作者：James Zhu ([fatindeed@hotmail.com](mailto:fatindeed@hotmail.com))
>
> 创建日期：2018-09-19

## 引言

在使用Git的过程中，我们喜欢有的文件比如日志，临时文件，编译的中间文件等不要提交到代码仓库，这时就要设置相应的忽略规则，来忽略这些文件的提交。

## Git 忽略规则优先级

在 `.gitingore` 文件中，每一行指定一个忽略规则，Git 检查忽略规则的时候有多个来源，它的优先级如下（由高到低）：

* 从命令行中读取可用的忽略规则
* 当前目录定义的规则
* 父级目录定义的规则，依次递推
* `$GIT_DIR/info/exclude` 文件中定义的规则
* `core.excludesFile` 中定义的全局规则

## Git 忽略规则匹配语法

在 `.gitignore` 文件中，每一行的忽略规则的语法如下：

* 空格不匹配任意文件，可作为分隔符，可用反斜杠转义
* \# 开头的文件标识注释，可以使用反斜杠进行转义
* ! 开头的模式标识否定，该文件将会再次被包含，如果排除了该文件的父级目录，则使用 ! 也不会再次被包含。可以使用反斜杠进行转义
* / 结束的模式只匹配文件夹以及在该文件夹路径下的内容，但是不匹配该文件
* / 开始的模式匹配项目跟目录
* 如果一个模式不包含斜杠，则它匹配相对于当前 `.gitignore` 文件路径的内容，如果该模式不在 `.gitignore` 文件中，则相对于项目根目录
* \*\* 匹配多级目录，可在开始，中间，结束
* ? 通用匹配单个字符
* \[] 通用匹配单个字符列表

注意：Git 对于 `.gitignore` 是按行从上到下进行规则匹配的，意味着如果前面的规则匹配的范围更大，则后面的规则将不会生效。

## 常用匹配示例：

* `#`: 此为注释 – 将被 Git 忽略
* `*.log`: 忽略所有 `.log` 结尾的文件
* `!lib.a`: 不忽略 `lib.a` 文件
* `/config.php`: 仅仅忽略项目根目录下的 `config.php` 文件，不包括 `subdir/config.php`
* `build/`: 忽略 `build/` 目录下的所有文件，不包括 `build` 文件
* `doc/*.txt`: 会忽略 `doc/notes.txt` 但不包括 `doc/server/arch.txt`
* `**/foo`: 会忽略 `/foo`、`a/foo`、`a/b/foo` 等
* `a/**/b`: 会忽略 `a/b`、`a/x/b`、`a/x/y/b` 等

## Git 忽略规则查看

如果你发现 `.gitignore` 写得有问题，需要找出来到底哪个规则写错了，可以用 `git check-ignore` 命令检查：

```bash
$ git check-ignore -v HelloWorld.class
.gitignore:1:*.class    HelloWorld.class
```

可以看到 `HelloWorld.class` 匹配到了我们的第一条 `*.class` 的忽略规则所以文件被忽略了。

## 常用忽略文件

Github上整理了一些常用的 `.gitignore`，可根据自身需要[编辑使用](https://github.com/github/gitignore)。

## 参考资料

* [gitignore Documentation](https://git-scm.com/docs/gitignore)
* [github/gitignore: A collection of useful .gitignore templates](https://github.com/github/gitignore)
