gitignre原理浅识

1、学习 gitignore 的起因

在项目过程中,由于需要忽略某一个文件,所以新建了一个 .gitignore 文件。但是,与我想象的有些不太一样,和我 Pair 的小伙伴直接将 .gitignore 文件建在了当前目录下。结构大致如下:

    .
    ├── Dockerfile
    ├── Gemfile
    ├── README.md
    ├── auto
    │   ├── dev-environment
    │   └── rubocop
    ├── docker-compose.yml
    ├── template
    │   ├── README.md
    │   └── auto
    │       ├── kite
    |       └── .gitignore
    ├── version.txt
    └── .gitignore

What?
这样可以吗?不是需要在根目录下创建的吗?难道我的理解有问题?
于是,我来学 gitignore 了!😂

2、我原本对 .gitignore 的理解

我自己学习过 Git ,也一直在用 Git ,而 .gitignore 用于忽略某些文件,使其不被 Git 追踪,这个作用我是知道的。
当然,我一直以来的理解是:

  • .gitignore 文件需要在项目根目录下
  • .gitignore 只对当前项目起作用
  • .gitignore 文件中可以有一些简单的匹配规则

3、gitignore 介绍

  • gitignore 的定义
    对于 gitignore 的定义,我在官网上找到的解释是这样的:Specifies intentionally untracked files to ignore. 而翻译成中文,大意是:故意指定不追踪的文件,以达到忽略的目的。
    同时,我还在一篇文章中找到了一个比较浅显易懂的解释:.gitignore ,是用来显式指定哪些文件或文件夹应该被Git忽略的一个文件。
    这个解释就相当得好懂了,而根据这两个定义(解释)以及我自己之前对 .gitignore 的理解,很明显,.gitignore 就是用来指定需要被 Git 忽略的文件或文件夹的,以达到其不被 Git 追踪的目的,从而,在整个版本控制的生命周期中,Git 不会对在 .gitignore 中指定的文件和文件夹进行版本管理。
    同时,经常使用 .gitignore 的一个场景是:为了在提交代码时不将某些没有意义的文件或文件夹提交到远端仓库,比如:VS Code 生成的 .vscode 目录、IDEA 生成的 .idea 目录、Node 项目中的 node_modules 目录等。

  • gitignore 的有效位置
    $HOME/.gitignore_global , $HOME/.config/git/ignore , $GIT_DIR/info/exclude , .gitignore 这些地方指定的 ignore 规则都会在 Git 仓库中生效。

4、gitignore 描述

gitignore 指定应该被 Git 忽略的文件或目录;同时,在 gitignore 文件中,每一行都指定了一种匹配模式(规则),指定了匹配到的文件或目录应该被 Git 忽略;但,有一点需要注意,即已经被 Git 追踪的文件或目录不受 gitignore 文件的影响。
这是已经在上面解释过的关于 gitignore 的定义,但是,可以注意到,在上面有写到 gitignore 的有效位置有多个,包括 $HOME/.gitignore_global , $HOME/.config/git/ignore , $GIT_DIR/info/exclude , .gitignore 等。那么,这么多的 gitignore ,如果他们都指定了应该被忽略的文件或目录,那他们的顺序是怎样的呢?
这就不得不提到 Gitgitignore 的优先检查顺序!
以下,是按照从高到低的优先级顺序列出的各个 .gitignore 的有效位置(规则源)

  • 从命令行输入的 gitignore 规则

  • 项目中的 gitignore 规则:其中,当前目录下的 gitignore 规则优先级最高,紧接着是父目录中的 gitignore 规则…最后,是项目根目录下的 gitignore 规则。总之,越靠近指定忽略文件或目录的 gitignore 规则,优先级越高

  • $GIT_DIR/info/exclude 位置的 gitignore 规则。🤔️$GIT_DIR 是什么?官网给出的定义是:$GIT_DIR .git 文件夹的位置。如果未指定,则 Git 会沿目录树移动,在每个位置查找 .git 文件夹,直至到达 ~/

  • Git 配置的变量 core.excludeFile 指定的规则。🤔️变量 [core.excludeFile](https://stackoverflow.com/questions/7335420/global-git-ignore) 是什么?怎么用?**git config --global core.excludesfile '~/.gitignore' 指定一个 .gitignore 文件,作为全局的配置**

  • 🤔️那 $HOME/.gitignore_global , $HOME/.config/git/ignore 呢?
    经过查找资料发现,原来 [$HOME/.gitignore_global](https://digitalfortress.tech/tricks/creating-a-global-gitignore/) 就是用来配置到变量 core.excludeFile,而这个文件名其实完全可以随便起,只是为了更加语义化一些,所以将其命名为 .gitignore_global
    那,这只是一个,另一个 $HOME/.config/git/ignore 呢?原来,上面的 core.excludeFile 是通过设置全局 gitignore 的形式使用了 $HOME/.gitignore_global ,但是,这种方法是需要我们自己手动去配置的!然而,Git 是有默认的全局 gitignore 的位置的!即,$XDG_CONFIG_HOME/git/ignore ,但是,如果 $XDG_CONFIG_HOME 没有设置或为空的话,则使用 $HOME/.config/git/ignore !当然,如果 $HOME/.config/git/ignore 也没有设置,那还用个🍺呦!😂

那么,gitignore 有这么多的有效位置,我们在平时使用的时候,到底应该将我们的 gitignore 规则放置在什么位置呢?
官网给出了几个建议:

  • 如果在一个项目中,需要 Git 忽略掉一些文件或目录,不对它们进行追踪,并且要保证其他人 **clone 下该项目后,gitignore 规则依旧生效**,则应该.gitignore 文件定义在项目中

  • 如果某个规则只想在某一个特定的仓库中生效,就把它定义在 $GIT_DIR/info/exclude

  • 如果你的gitignore规则要在任何情况下都生效,这种规则最好放在core.excludesFile这一变量中这个变量定义在用户目录下-~/.gitconfig,该变量的默认值是$XDG_CONFIG_HOME/git/ignore,如果$XDG_CONFIG_HOME未设置或为空,Git会使用$HOME/.config/git/ignore

以上就是一些大致的建议。同时,关于 gitignore 规则,还有一个需要注意的点,即:

  • Git 的底层管道工具,比如 git ls-filesgit read-tree,只从命令行参数指定的文件中读取 gitignore 规则

  • 上层的 Git 工具,比如 git statusgit add,会从上述规则源中读取 gitignore 规则

5、gitignore 的语法规则

  • 空行不匹配任何文件,可以用空行来增强 gitignore 规则的可读性😂
  • 注释行以 # 开头
  • 如果指定要忽略的文件或目录名中含 # 的话,可以在 # 前加反斜杠 \ ,即 \#
  • 如果每一行最后尾随的空格没有用反斜杠转义,那么这些空格是无效的,不会作为规则的一部分
  • 使用 ! 前缀来否定 gitignore 规则中前面部分忽略掉的文件或目录。如果一个文件被前面的 gitignore 规则给匹配到了,那么该文件不会被Git追踪,但是如果后面的规则使用!匹配到了该文件,那么该文件又会被Git追踪。
  • 如果一个目录被 Git 忽略了,那么无论如何,即便在后面部分指定了应该否定该目录下的某个文件,这个文件也不会被Git追踪。这是由于:出于性能考虑,Git不会遍历被忽略的目录,因此,定义在被忽略目录下的 gitignore 规则都是无效的。
  • 如果某个文件或目录以感叹号 ! 开头,如果要指定忽略该文件或目录的话,可以! 前面加上反斜杠 \ ,即 \! 。比如:\!important.txt会匹配文件!important.txt
  • 以斜杠 / 结尾代表指定的是某个目录及该目录下的所有子目录及文件
  • 如果不是以斜杠 / 结尾,则代表指定的是某个文件
  • 如果规则不符合以上的情况,那么 Git 就会把这个规则当成 shell 通配符规则来进行解析。举个🌰,Documentation/*.html 匹配 Documentation/git.html,但不会匹配Documentation/ppc/ppc.html 或者 tools/perf/Documentation/perf.html
  • 以斜杠开头的通配符规则从路径开头开始匹配。比如,/*.c 匹配 cat-file.c,但不匹配mozilla-sha1/sha1.c
  • ** 代表可以匹配到 0+ 个目录,比如:
    • **/foo 会匹配到所有路径下的文件 foo 或者目录 foo,无论它在哪个目录
    • **/foo/bar 规则会匹配到所有路径下的目录 foo 下直接跟的文件bar或目录bar
    • abc/** 会匹配目录 abc 下的所有文件及子目录…
    • a/**/b 会匹配 a/ba/x/ba/x/y/b 等,中间的目录级数可以是 0+ 个

6、停止被 Git 追踪(Track)

gitignore 文件的目的是确保某些不应该被Git追踪的文件确实没有被 track
如果要停止追踪(track)一个已经被Git追踪的文件,请使用 git rm --cached Xxx 命令

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十甫寸木南

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值