Finish 2.3.5-git_ignore.
This commit is contained in:
161
sources/2.3.5-git_ignore.md
Normal file
161
sources/2.3.5-git_ignore.md
Normal file
@ -0,0 +1,161 @@
|
||||
# .gitignore
|
||||
|
||||

|
||||
|
||||
***[git add](2.3.1-git_add.md) / [git commit](2.3.2-git_commit.md) / [git diff](2.3.3-git_diff.md) / [git stash](2.3.4-git_stash.md) / [.gitignore](2.3.5-git_ignore.md)***
|
||||
|
||||
> ✍️ [童仲毅](https://github.com/geeeeeeeeek) | ⏳ 2018 年 12 月 24 日
|
||||
>
|
||||
> ©️ 本文演绎自 Atlassian 编写的 [_Saving Changes_](https://www.atlassian.com/git/tutorials/saving-changes)。页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))许可协议。
|
||||
|
||||
Git 将工作副本中每个文件都视作以下三者之一:
|
||||
|
||||
1. 被追踪的文件——之前被缓存或提交过的文件;
|
||||
2. 未被追踪的文件——尚未被缓存或提交过的文件;
|
||||
3. 被忽略的文件——Git 被明确告知要忽略的文件。
|
||||
|
||||
被忽略的通常是构建过程(build)和机器生成的文件。它们可以根据你的仓库源码生成,或者不应该被提交。下面是一些常见的栗子:
|
||||
|
||||
- 缓存的依赖文件,例如 `/node_modules` 或 `/packages` 里的内容
|
||||
- 编译后的代码,例如 `.o`、`.pyc`、`.class`
|
||||
- 构建输出的目录,例如 `/bin` 、`/out`、`/target`
|
||||
- 运行时生成的文件,例如`.log`、`.lock`、`.tmp`
|
||||
- 隐藏的系统文件,例如`.DS_Store`、`Thumbs.db`
|
||||
- 个人的开发环境(IDE)配置文件,例如`.idea/workspace.xml`
|
||||
|
||||
忽略的文件通过一个名为 `.gitignore` 的文件追踪,该文件位于仓库的根目录下。Git 没有显式的忽略命令。添加新文件时必须手动修改并提交 `.gitignore` 文件来添加忽略的文件。`.gitignore` 文件里的规则用于匹配文件名,从而判断该文件是否需要被忽略。
|
||||
|
||||
## 目录
|
||||
|
||||
- [Git 忽略文件的匹配规则](#Git 忽略文件的匹配规则)
|
||||
- [仓库内的共享 .gitignore 文件](#仓库内的共享 .gitignore 文件)
|
||||
- [个人的 Git 忽略规则](#个人的 Git 忽略规则)
|
||||
- [全局的 Git 忽略规则](#全局的 Git 忽略规则)
|
||||
- [忽略一个被提交过的文件](#忽略一个被提交过的文件)
|
||||
- [提交被忽略的文件](#提交被忽略的文件)
|
||||
- [储存被忽略的文件](#储存被忽略的文件)
|
||||
- [调试 .gitignore 文件](#调试 .gitignore 文件)
|
||||
|
||||
## Git 忽略文件的匹配规则
|
||||
|
||||
`.gitignore` 使用 [GLOB 规则](http://linux.die.net/man/7/glob) 匹配文件名。你可以使用多种符号创建你的规则:
|
||||
|
||||
| 匹配规则 | 样例 | 解释* |
|
||||
| ------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
| `**/logs` | `logs/debug.log` `logs/monday/foo.bar` `build/logs/debug.log` | 在规则前接两个星号,从而在仓库任何位置匹配该目录。 |
|
||||
| `**/logs/debug.log` | `logs/debug.log` `build/logs/debug.log` *但不会匹配* `logs/build/debug.log` | 使用两个星号匹配文件名和父目录名称。 |
|
||||
| `*.log` | `debug.log` `foo.log` `.log` `logs/debug.log` | 单个星号为通配符,匹配零或多个字符。 |
|
||||
| `*.log` `!important.log` | `debug.log` `trace.log` *但不会匹配* `important.log` `logs/important.log` | 在规则前接一个感叹号作为否定。如果文件同时符合一个先定义的规则和一个后定义的否定规则,它将不会被忽略。 |
|
||||
| `*.log` `!important/*.log` `trace.*` | `debug.log` `important/trace.log` *但不会匹配* `important/debug.log` | 在否定规则后定义的规则会覆盖之前定义的否定规则。 |
|
||||
| `/debug.log` | `debug.log` *但不会匹配* `logs/debug.log` | 前接斜杠只匹配仓库根目录下的文件。 |
|
||||
| `debug.log` | `debug.log` `logs/debug.log` | 规则默认匹配任何目录下的文件。 |
|
||||
| `debug?.log` | `debug0.log` `debugg.log` *但不会匹配* `debug10.log` | 一个问号用于匹配一个符号。 |
|
||||
| `debug[0-9].log` | `debug0.log` `debug1.log` *但不会匹配* `debug10.log` | 方括号用于从特定范围中匹配单个字符。 |
|
||||
| `debug[01].log` | `debug0.log` `debug1.log` *但不会匹配* `debug2.log` `debug01.log` | 方括号用于从特定集合中匹配单个字符。 |
|
||||
| `debug[!01].log` | `debug2.log` *但不会匹配* `debug0.log` `debug1.log` `debug01.log` | 感叹号用于匹配除去特定集合中的任一字符。 |
|
||||
| `debug[a-z].log` | `debuga.log` `debugb.log` *但不会匹配* `debug1.log` | 范围可以是数字,也可以是字母。 |
|
||||
| `logs` | `logs` `logs/debug.log` `logs/latest/foo.bar` `build/logs` `build/logs/debug.log` | 如果你不后接斜杠,规则将会同时匹配相符的文件和目录。在左边的栗子中,名为 *logs* 的目录和文件都被忽略了。 |
|
||||
| logs/ | `logs/debug.log` `logs/latest/foo.bar` `build/logs/foo.bar` `build/logs/latest/debug.log` | 后接斜杠表示该规则对应的是一个目录。仓库中符合该规则的任何目录中的所有内容(包括文件和子目录)都会被忽略。 |
|
||||
| `logs/` `!logs/important.log` | `logs/debug.log` `logs/important.log` | 注意,为什么左边栗子中被加上否定的 `logs/important.log` 没有被忽略?由于 Git 的性能优化,你 *不能* 否定一个根据目录匹配规则被忽略的文件。 |
|
||||
| `logs/**/debug.log` | `logs/debug.log` `logs/monday/debug.log` `logs/monday/pm/debug.log` | 两个星号匹配零个或多个目录。 |
|
||||
| `logs/*day/debug.log` | `logs/monday/debug.log` `logs/tuesday/debug.log` 但不会匹配* `logs/latest/debug.log` | 通配符也可被用于目录名中。 |
|
||||
| `logs/debug.log` | `logs/debug.log` 但不会匹配* `debug.log` `build/logs/debug.log` | 一些规则指定特定目录下的文件,这些路径相对于仓库的根目录。你可以在前接一个斜杠,但这不是必须的。 |
|
||||
|
||||
** 这些解释假设你的 .gitignore 文件按照惯例位于仓库根目录。如果仓库中存在多个 .gitignore 文件,你只需要将“包含 .gitignore 文件的目录”想成是“仓库的根目录”。同时,为了便于团队合作,你应该考虑将它们合并*
|
||||
|
||||
除了这些符号之外,你可以使用 # 在 `.gitignore` 文件中添加注释:
|
||||
|
||||
```shell
|
||||
# ignore all logs
|
||||
*.log
|
||||
```
|
||||
|
||||
你可以在 `.gitignore` 规则字符中使用 \ 转义,如果文件名或目录名中包含特殊字符:
|
||||
|
||||
```shell
|
||||
# ignore the file literally named foo[01].txt
|
||||
foo\[01\].txt
|
||||
```
|
||||
|
||||
## 仓库内的共享 .gitignore 文件
|
||||
|
||||
Git 忽略规则通常被定义在仓库根目录的 `.gitignore` 文件中。但是,你也可以在仓库内不同文件夹下定义多个 `.gitignore` 文件。 `.gitignore` 文件中的每个规则都会在所在文件夹进行匹配。不过,我们一般只在根目录定义一个 `.gitignore` 文件,这也是最简单的做法。当 `.gitignore` 文件被检入时,它和仓库内其它所有文件一样也有版本,在你推送后将与他人共享。在 `.gitignore` 中,你应该只添加对其它用户也有用的规则。
|
||||
|
||||
## 个人的 Git 忽略规则
|
||||
|
||||
你可以在 `.git/info/exclude` 这个文件中为某个仓库定义个人的忽略规则。它们没有版本,也不会跟随仓库发布,因此它们适合存放只对你有用的规则。例如,如果你有一个自定义的登陆配置,火烧会在仓库的工作目录下生成文件的特殊开发工具,你可以将它们添加到 `.git/info/exclude` 以避免被意外提交到仓库中。
|
||||
|
||||
## 全局的 Git 忽略规则
|
||||
|
||||
此外,通过设置 Git 的 `core.excludesFile` 属性,你可以在本地系统中为所有仓库设置全局的 Git 忽略规则。你需要自己创建这个文件。如果你不确定在哪里放置这个全局的 `.gitignore` 文件,home 目录会是一个好的选择,也便于以后的查找。创建这个文件之后,你需要使用 `git config` 配置它的位置:
|
||||
|
||||
```shell
|
||||
$ touch ~/.gitignore
|
||||
$ git config --global core.excludesFile ~/.gitignore
|
||||
```
|
||||
|
||||
你应该特别注意哪些规则是应该全局忽略的,因为不同的项目会用到不同类型的文件。某些操作系统文件(如 `.DS_Store` 和 `thumbs.db`)和开发者工具生成的临时文件往往可以被全局忽略。
|
||||
|
||||
## 忽略一个被提交过的文件
|
||||
|
||||
如果你想要忽略一个已经提交过的文件,你需要将这个文件从仓库中删除,然后在 `.gitignore` 中添加一条规则。使用 `git rm` 的 `--cached` 选项表示这个而文件将从仓库中被删除,但将作为一个被忽略的文件存在于工作目录下。
|
||||
|
||||
```shell
|
||||
$ echo debug.log >> .gitignore
|
||||
$ git rm --cached debug.log
|
||||
rm 'debug.log'
|
||||
$ git commit -m "Start ignoring debug.log"
|
||||
```
|
||||
|
||||
如果你希望将某个文件同时从仓库和本地文件系统中删除,你可以省略 `--cached` 选项。
|
||||
|
||||
## 提交被忽略的文件
|
||||
|
||||
使用 `git add` 的 `-f`(或者`--force`)选项,你可以强制提交一个被忽略的文件:
|
||||
|
||||
```shell
|
||||
$ cat .gitignore
|
||||
*.log
|
||||
$ git add -f debug.log
|
||||
$ git commit -m "Force adding debug.log"
|
||||
```
|
||||
|
||||
使用这个命令的一个场景是,你定义了一个通用的规则(如 `*.log`),但是想要提交某个特定的文件。不过,一个更好的解决方案是为这个通用的规则定义一个例外:
|
||||
|
||||
```shell
|
||||
$ echo !debug.log >> .gitignore
|
||||
$ cat .gitignore
|
||||
*.log
|
||||
!debug.log
|
||||
$ git add debug.log
|
||||
$ git commit -m "Adding debug.log"
|
||||
```
|
||||
|
||||
上面的这个方法更加清晰易懂,尤其是对于其它团队成员。
|
||||
|
||||
## 储存被忽略的文件
|
||||
|
||||
`git stash` 是一个强大的 Git 功能。它将本地的更改临时储存起来然后撤销,允许你随后再重新应用这些更改。正如你所想的一样,`git stash` 默认跳过被忽略的文件,它只储存被 Git 追踪的文件中的更改。然后,你可以使用 git stash 的 --all 选项来储存被忽略和为追踪的文件。
|
||||
|
||||
## 调试 .gitignore 文件
|
||||
|
||||
如果你的 `.gitignore` 规则十分复杂,或者规则分散于多个 `.gitignore` 文件,要理解某个文件为什么被忽略了不是一件容易的事情。你可以使用 `git check-ignore` 命令的 `-v`(或者 `--verbose`)选项来确定是哪条规则让某个文件被忽略了:
|
||||
|
||||
```shell
|
||||
$ git check-ignore -v debug.log
|
||||
.gitignore:3:*.log debug.log
|
||||
```
|
||||
|
||||
输出的格式如下:
|
||||
|
||||
```shell
|
||||
<file containing the pattern> : <line number of the pattern> : <pattern> <file name>
|
||||
```
|
||||
|
||||
你可以向 `git check-ignore` 传入多个文件名。这些文件名不一定要对应于仓库中已存在的文件。
|
||||
|
||||
> 这篇文章是[**「git-recipes」**](https://github.com/geeeeeeeeek/git-recipes/)的一部分,点击 [**目录**](https://github.com/geeeeeeeeek/git-recipes/wiki/) 查看所有章节。
|
||||
>
|
||||
> 如果你觉得文章对你有帮助,欢迎点击右上角的 **Star** :star2: 或 **Fork** :fork_and_knife:。
|
||||
>
|
||||
> 如果你发现了错误,或是想要加入协作,请参阅 [Wiki 协作说明](https://github.com/geeeeeeeeek/git-recipes/issues/1)。
|
||||
Reference in New Issue
Block a user