前言

通过在一个 gitignore 文件里面添加相关的规则,我们可以让 git 在追踪文件时忽略一些特定的文件(gitignore 文件泛指所有存放忽略规则的文件,不仅仅是指 .gitignore 这个文件)。

注意: 如果一个文件当前已经被 git 追踪,则针对它添加的任何忽略规则都将不会起作用;如果确实要取消对它的追踪,在添加相应的忽略规则之后,还应该使用git rm --cached fileNamegit rm -r --cached dirName 来移除对此文件或目录的追踪

在下文中我们用 repo_dir/ 代表 git 管理的仓库的顶层目录。

gitignore 文件存放的位置

gitignore 文件里面的每一行规定一个规则来忽略相应的文件,当 git 决定是否忽略某个文件时,它会参考多个来源的 gitignore 规则,下面以 git 访问的的顺序列出这些来源:

  • 来自命令行的规则,有些 git 命令(git ls-filesgit read-tree等)支持从命令行通过参数输入规则

  • 来自文件所在目录下 .gitignore 文件里面的规则,或者是文件所在目录的上层目录(逐层往上,直到仓库顶层目录)下的 .gitignore 文件(子目录下的 .gitignore 文件中的规则可以覆盖其上层目录下的 .gitignore 文件里面的规则)

  • 来自 $GIT_DIR/info/exclude(一般是 repo_dir/.git/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 文件里面,即 repo_dir/.gitignore 文件

1. 忽略仓库里面所有以 .a 结尾的文件,但保留keep.a这个文件

# 忽略所有以 .a 结尾的文件
*.a # 保留 keep.a 这个文件
!keep.a

2. 忽略 release 文件夹,但是保留它下面的 app-latest.apk 这个文件

下面的忽略规则将不能正常工作:

# 忽略 release 这个文件夹,也可以写成 release,但是有可能匹配到名为 release 的文件或者软链接
release/ # 取消对 release/app-latest.apk 这个文件的忽略,但这条规则将不会起作用;
# 因为前面一条规则已经将 release 这个文件夹忽略了,对已被忽略的文件夹下的任何文件或者文件夹使用 ! 规则都不会起作用
!release/app-latest.apk

正确的写法:

# 忽略 release 文件夹下面的所有文件和文件夹(但是没有忽略 release 自身这个文件夹)
release/* !release/app-latest.apk

3. 忽略仓库顶层目录里面的 packages/build 这个文件夹

# 由于规则里面包含斜杠(即使去掉末尾的斜杠之后),因此只会在起始目录里面进行匹配,不会去子目录里面匹配
# 也可以写成 packages/build 和 /packages/build/ 以及 /packages/build
packages/build/

4. 忽略仓库里面所有的 packages/build/ 文件夹

# ** 会匹配任意的路径字符串,因此 packages/build,temp/packages/build 都会被匹配到
**/packages/build/

5. *** 的区别

# 匹配 /a/b/z,/a/c/z,/a/d/z 等
/a/*/z
# 匹配 /a/b/z,/a/b/c/z,/a/b/c/d/z 等
/a/**/z

参考

  1. https://git-scm.com/docs/gitignore

  2. https://stackoverflow.com/questions/681262/difference-in-the-paths-in-gitignore-file

  3. https://stackoverflow.com/questions/41761128/are-leading-asterisks-redundant-in-gitignore-path-matching-syntax

原文链接:https://hcwang.xyz/posts/aboutgitignore/

关于 gitignore的更多相关文章

  1. 关于gitignore文件的创建与使用

    在我们使用github提交本地代码时,有些库文件和日志文件是不必要提交的,那如何处理这个问题呢?这个时候我们就会用到.gitignore文件了. 该篇博客我会介绍如何创建.gitignore,以及如何 ...

  2. gitignore 规范

    gitignore 应该包含 5 块内容: 当前项目需要忽略的文件 项目性质需要忽略的文件(比如是 nodejs 项目,有些文件就需要忽略) 所有项目都需要忽略的文件(比如日志.临时文件) 操作系统需 ...

  3. Git忽略.gitignore规则不生效的解决办法

    在git中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改根目录中 .gitignore 文件的方法(如无,则需自己手工建立此文件). 这个文件每一行保存了一个匹配的规则例如: # 此为 ...

  4. .gitignore过滤个人配置

    git还是一个很好使用的版本工具.所以用eclipse做自己的小玩意儿,在多台电脑之间同步的时候我经常会使用它.. 但是有个问题..不同电脑的eclipse的个人配置稍微有那么一点点的不同..比如有几 ...

  5. Github .gitignore详解

    在使用git作版本控制时,git会默认把git控制的文件夹里面的所有文件都加入到版本控制.但是在实践中,我们经常会遇到不想某些文件或文件夹被git追踪的情况.比如logs文件.代码构建过程中产生的一些 ...

  6. ios 项目的.gitignore

    git作为代码管理工具,.gitignore文件用来忽略哪些哪些文件不用添加到仓库管理https://www.gitignore.io/ 这个网址输入变成语言会帮你生成常用的忽略文件如:IOS项目,输 ...

  7. 编写.gitignore文件的几个小技巧

    记录几个编写.gitignore文件的小技巧,可能你早就知道了,但我是google了一番才找到写法. 忽略所有名称为bin的文件夹 bin/ 只忽略第一级目录中,名称为bin的文件夹 /bin/ 忽略 ...

  8. .gitignore详解

    今天讲讲Git中非常重要的一个文件――.gitignore. https://git-scm.com/docs/gitignore 首先要强调一点,这个文件的完整文件名就是“.gitignore”,注 ...

  9. Git的.gitignore文件配置

    .gitignore是Git工具的配置文件,用于屏蔽某些文件上传到线上. 创建.gitignore 在window系统中,不允许新建文件名以"."开头的文件,所以通过git bas ...

  10. git用.gitignore忽略指定文件

    .gitignore 配置文件用于配置不需要加入版本管理的文件,配置好该文件可以为我们的版本管理带来很大的便利,以下是个人对于配置 .gitignore 的一些心得. 1.配置语法: 以斜杠“/”开头 ...

随机推荐

  1. 集合源码分析[2]-AbstractList 源码分析

    AbstractList 类型:抽象类 接口的继承以及实现关系 继承AbstractCollection 实现List接口 典型方法实现解析 public List<E> subList( ...

  2. 仿照selalchemy实现简单的mongo查询

    首先这是一个很奇葩的需求,时间紧迫顺手胡写了一个,以后看看有没有好的思路 def and_(item_list): return "%s:[%s]" % ("$and&q ...

  3. font-spider问题【已解决】

    最近写一个项目,使用了引入的字体,然而字体太大,于是找解决方法,想要把字体压缩一下,然后找到了font-spider;font-spider使用方法这里就不多说了,网上一大把,主要是在node里面安装 ...

  4. 五十七、linux 编程——UDP 编程 域名解析

    57.1 介绍 57.1.1 域名解析 57.1.2 域名解析函数 gethostent 可以获取多组,gethostbyname 只可以获取一组 /etc/hosts 文件设置了域名和 IP 的绑定 ...

  5. linux Centos7下安装python3及pip3

    先去python官网下载python3安装包 执行命令:wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz 安装zlib-dev ...

  6. JAVA基础---入门

    JDK的安装和环境变量的配置: 在Oralce官网下载好符合自己电脑配置的JDK后开始配置环境变量. 找到下载好的JDK的位置,复制,然后在环境变量里创建“JAVA_HOME”,粘贴:在path里用“ ...

  7. JVM中的方法分派

    解析调用是一个静态的过程,在编译期间就完全确定,在类装载的解析阶段就会把涉及的符号引用全部转变为可确定的直接引用,不会延迟到运行期再去完成.而分派调用则可能是静态的也可能是动态的,根据分派依据的宗量数 ...

  8. 2018-2019-2 20165325 《网络对抗技术》 Exp5:MSF基础应用

    2018-2019-2 20165325 <网络对抗技术> Exp5:MSF基础应用 实验内容(概要) 1.1 一个主动攻击实践,本实验选择 ms17_010_eternalblue(成功 ...

  9. 配置tensorflow和keras时教程及问题总结

    基本参数:(如何基本参数和我的电脑不一致,有可能会出意外的错误) 操作系统:Windows 10,64位 Anaconda版本:Python 3.6版本.关于Anaconda的介绍.安装及使用教程可查 ...

  10. appniu踩坑

    1.pyCharm识别不到appnium-python-client 解决:新建项目注意选择环境,查看Project Interpreter中是否识别到了appnium-python-client 还 ...