通过在一个 gitignore 文件里面添加相关的规则,我们可以让 git 在追踪文件时忽略一些特定的文件(gitignore 文件泛指所有存放忽略规则的文件,不仅仅是指 .gitignore 这个文件)。
注意: 如果一个文件当前已经被 git 追踪,则针对它添加的任何忽略规则都将不会起作用;如果确实要取消对它的追踪,在添加相应的忽略规则之后,还应该使用git rm --cached fileName
或 git rm -r --cached dirName
来移除对此文件或目录的追踪
在下文中我们用 $GIT_DIR
代表 git 管理的仓库的顶层目录。
gitignore 文件里面的每一行规定一个规则来忽略相应的文件,当 git 决定是否忽略某个文件时,它会参考多个来源的 gitignore 规则,下面以 git 访问的的顺序列出这些来源:
来自命令行的规则,有些 git 命令(git ls-files
, git read tree
等)支持从命令行输入规则
来自文件所在目录下 .gitignore 文件里面的规则,或者是文件所在目录的上层目录(逐层往上,直到工程顶层目录)下的 .gitignore 文件,子目录下的 .gitignore 文件中的规则会覆盖其上层目录下的 .gitignore 文件里面的规则
来自 $GIT_DIR/info/exclude
文件里面的规则
来自全局的 gitignore 文件,这个文件由 git 的配置文件(一般是 ~/.gitconfig)里面的 core.excludeFile 这一项指定,如果 git 配置文件里面没有这一项,则默认值为 $XDG_CONFIG_HOME/git/ignore
,但是如果 XDG_CONFIG
这个环境变量没有配置或者是空的,则默认值为 $HOME/.config/git/ignore
正如上面所讲的,git 会参考来自多个文件的忽略规则去决定是否忽略一个文件,因此我们在添加一条忽略规则是,应该遵循以下的原则:
如果忽略规则是需要和工程一起发布到远程仓库的,则应该把这些规则放在仓库里面的 .gitignore 文件里面
如果忽略规则不需要和工程一起发不到远程仓库,但这些规则又只是针对当前这个工程,不是全局性的,则这些规则就应该放在 $GIT_DIR/info/exclude
这个文件里面
如果忽略规则是全局性的,则应该将其放入全局的 gitignore 文件里面
忽略规则根据其所在的文件会有一定的作用范围,这个范围包括一个起始目录和及其下面的所有文件,不同文件的起始目录为:
.gitignore 文件的起始目录是其所在的目录
其它文件里面的起始目录是仓库的顶层目录
gitignore 文件里的每一行都规定一条规则,git 对文件里面的规则进行自上到下的匹配。下面是各种规则的格式:
空行不匹配任何文件,只是使得文件更容易阅读
每一行中 #
后面的都是注释,如果规则里面需要用 #
,请使用反斜杠 \
转义
每一行后面的空格都会被忽略,除非空格前面用反斜杠 \
进行转义
以 !
开头的规则用来取消对这条规则前面某些规则对某些文件的忽略,例如前面忽略了某个文件夹下所有的文件,在利用 !
写一条规则取消对该文件夹下面某个文件的忽略,如果想输入普通的 !
,请使用反斜杠 \
转义。
注意: 如果前面的规则将某个目录忽略了,则对这个目录下面所有的文件使用 !
规则将不起作用,具体请看例2
如果一条规则以斜杠 /
结尾,git 首先会将 /
去掉再进行匹配,但是这个反斜杠也会其作用,代表这个规则最后匹配的是文件夹,例如 build/
这条规则最后会以build
这个规则去匹配名为 build 的文件夹,但是不会匹配一个名为 build 的文件(以及软链接)
如果一条规则不包含斜杠 /
(包括那些仅在末尾包含斜杠的规则,因为 git 会首先去掉规则末尾的斜杠),则这条规则会在相应的 起始目录 下的所有层次的文件夹里面进行匹配
如果一条规则包含斜杠 /
(指去掉末尾的斜杠之后还包含斜杠),则这条规则只会在相应的 起始目录 里面(不包括子目录)进行匹配;
与 shell 下面的通配符一样,忽略规则里面可以用 *
匹配任意的字符串(不包括包含斜杠的字符串),用 ?
匹配任意一个字符(除了斜杠),用 []
中列出的字符范围匹配其中的一个字符串
两个连续的星型标号 **
有其特殊的含义,但是它的表现依赖于 git 运行的平台。总的来说,**
匹配任意的路径字符串 (也就是说可以包含斜杠 /
的字符串),因此与单个星型标号 *
只匹配目录下的单个文件和文件夹不同,**
会匹配任意深度的文件和文件夹
下面所有例子中列举的忽略规则都位于仓库顶层目录下的 .gitignore 文件里面
.a
结尾的文件,但保留keep.a
这个文件*.a # 忽略所有以 .a 结尾的文件
!keep.a # 保留 keep.a 这个文件
下面的忽略规则将不能正常工作:
release/ # 也可以写成 release,但是有可能匹配到名为 release 的文件或者软链接
!release/app-latest.apk # 这条规则将不会起作用,因为前面一条规则已经将 build 这个文件夹忽略了
正确的写法:
release/* # 忽略 release 文件夹下面的所有文件和文件夹(但是没有忽略 release 自身这个文件夹)
!release/app-latest.apk
packages/build
这个文件夹packages/build/ # 也可以写成 packages/build 和 /packages/build/ 以及 /packages/build
# 因为即使去掉末尾的斜杠后,规则里面依然包含斜杠,因此只会在本例子中 .gitignore 文件的起始目录(也就是仓库顶层目录)中进行匹配,不会去子目录里面进行匹配
# 因此 packages/temp/packages/build/log.txt 这个文件不会受影响
packages/build/
文件夹**/packages/build/ # ** 会匹配任意的路径字符串,因此 packages/build,pakcages/temp/packages/build 都会被匹配到
*
与 **
的区别/a/*/z # 匹配 /a/b/z,/a/c/z,/a/d/z 等
/a/**/z # 匹配 /a/b/z,/a/b/c/z,/a/b/c/d/z 等
原文链接:https://hcwang.xyz/blog/aboutgitignore/
原文:https://www.cnblogs.com/0x4863/p/10583122.html