$HOME/.gitignore_global
, $HOME/.config/git/ignore
, $GIT_DIR/info/exclude
, .gitignore
这些地方指定的ignore规则都会在Git仓库中生效一个.gitignore
文件显式地指定了哪些文件不该被Git追踪,即被Git忽略掉。在被gitignore以前已经被Git追踪的文件不受gitignore规则的影响。关于gitignore规则的详情请继续往下看。html
.gitignore
文件中的每一行都指定了一种匹配模式。一般来讲,Git会从多个可能的规则源获取gitignore
规则来决定Git是否要忽略某一个具体的路径path,以下按照优先级列出了各类规则源,越靠前的规则优先级越高(在一个规则源内部,若是有多个gitignore
匹配,以最后匹配的为准)linux
.gitignore
文件,或者父级目录的.gitignore
中定义的规则。其中,越靠近具体路径的.gitignore
文件的优先级越高,同目录下的.gitignore
文件优先级最高。项目仓库中一般都有.gitignore
文件,里面会包含忽略项目build自动生成的文件的规则$GIT_DIR/info/exclude
中定义的规则core.excludeFile
指定的规则具体讲gitignore规则定义在哪一个文件中取决于该规则的做用(域):git
gitignore
规则应该被Git追踪,别人clone仓库后规则也生效,那么它就应该被定义在.gitignore
文件中$GIT_DIR/info/exclude
中吧gitignore
规则要在任何状况下都生效,这种规则最好放在core.excludesFile
这一变量中,这个变量定义在用户目录下-~/.gitconfig
,该变量的默认值是$XDG_CONFIG_HOME/git/ignore
,若是$XDG_CONFIG_HOME
是空的,Git会使用$HOME/.config/git/ignore
Git的底层管道工具,好比git ls-files
和git read-tree
,只从命令行参数||命令行参数指定的文件中读取gitignore
规则。上层的Git工具,好比git status
和git add
,会从上述规则源中读取gitignore
规则shell
gitignore
规则的可读性#
开头。能够在#
前加一个反斜杠转义之,使之可以匹配包含#字符
的文件夹或文件!
前缀来否认以前的规则。若是一个文件被前面的gitignore
规则给匹配到了,那么该文件不会被Git追踪,可是若是后面的规则使用!
匹配到了该文件,那么该文件又会被Git追踪。固然,若是一个文件的父目录都被Git忽略了,那么不管如何,这个文件都不会被Git追踪。出于性能考虑,Git不会遍历被忽略的目录,所以,定义在被忽略目录下的gitignore
规则都是无效的。有时候,咱们真的是想忽略以感叹号!
开头的一个文件或者目录,这时,能够在感叹号!
前面加一个反斜杠转义之,好比:\!important.txt
会匹配文件!important.txt
foo/
会匹配到目录foo
和foo
下的子目录,但不会匹配到文件foo
或者软连接foo
/
,Git就会就会把该规则当成通配符规则来进行处理,从该规则所在.gitignore
文件所在路径开始匹配。固然,若是这个规则不是放在.gitignore
文件中的,就会从work tree
的顶部开始匹配FNM_PATHNAME
标记的fnmatch(3)规则进行解析。可是,规则中的通配符不会匹配路径名中的斜杠/
。举个栗子,Documentation/*.html
匹配Documentation/git.html
,但不会匹配Documentation/ppc/ppc.html
或者tools/perf/Documentation/perf.html
/*.c
匹配cat-file.c
,但不匹配mozilla-sha1/sha1.c
两个连续的星号**
在匹配全路径名的时候可能有特殊含义:bash
**
开头,后接一个斜杠,这样的规则会在全部路径或子路径中尝试进行匹配。好比,**/foo
会匹配到文件foo
或者目录foo
,不管它在哪一个目录;foo
这条规则一样会尝试匹配全部路径中的文件foo
或者目录foo
。**/foo/bar
规则会匹配任意文件或目录foo
下直接跟的文件bar
或目录bar
**
,那这条规则会匹配下面的全部东西。好比abc/**
会匹配目录abc
下的全部文件或目录,固然,这里的目录abc
是相对于.gitignore
文件位置而言的,无限递归斜杠/
后跟两个星号,而后再跟一个斜杠的形式,这里的两个星号就会匹配0+
个目录,这里的0+
是指能够没有,也能够是多个。再举个例子,好比a/**/b
会匹配a/b
、a/x/b
、a/x/y/b
这些gitignore文件的目的是确保某些不该该被Git追踪的文件确实没有被track。若是要中止track一个已经被Git追踪的文件,请使用git rm --cached Xxx
命令工具
$ git status
[...]
# 暂未被Git追踪的文件:
[...]
# Documentation/foo.html
# Documentation/gitignore.html
# file.o
# lib.a
# src/internal.o
[...]
$ cat .git/info/exclude
# 忽略,即再也不追踪仓库中全部的objects和压缩文件.
*.[oa]
$ cat Documentation/.gitignore
# 忽略自动生成的html文件,
*.html
# 排除手动维护的foo.html,即不忽略foo.html,即Git会追踪foo.html
!foo.html
$ git status
[...]
# 暂未被Git追踪的文件:
[...]
# Documentation/foo.html
[...]
复制代码
一个例子不够,再来一个:性能
$ cat .gitignore
vmlinux*
$ ls arch/foo/kernel/vm*
arch/foo/kernel/vmlinux.lds.S
$ echo '!/vmlinux*' > arch/foo/kernel/.gitignore
复制代码
在这个例子中,第二个.gitignore文件arch/foo/kernel/.gitignore
的优先级更高,它阻止了第一个.gitignore文件试图忽略arch/foo/kernel/vmlinux.lds.S
的行为,从而,Git不会忽略arch/foo/kernel/vmlinux.lds.S
,会尝试追踪它ui
最后再来一个例子收尾。举个忽略目录下全部文件或目录,除了某个特定的目录foo/bar
的例子吧(注意下面的/*
,就算没有前面的斜杠,通配符也会匹配包括foo/bar
在内的全部文件或目录,因此斜杠/
是无关紧要的):spa
$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar
复制代码
译文到此完毕,我再补充几个小例子吧命令行