一文详解.gitignore与.gitkeep的作用与使用规则

6,476 阅读5分钟

采用Git进行版本控制的项目通常会有一个.gitignore文件,用于忽略不需要被跟踪的文件和目录,Git根据.gitignore中的匹配规则对进行过滤,会忽略符合匹配规则的目录和文件。

另外有的项目里边还会有.gitkeep文件,里面却没有什么内容,有时这个文件还不止一个,那么这个文件的作用是什么呢?为什么需要一个空文件放在目录下面?

本篇文章会对.gitignore.gitkeep的使用与区别分别进行介绍。

.gitignore概念和匹配规则介绍

.gitignore工作原理

采用Git做版本管理的项目里都有一个.gitignore文件,.gitignore的作用是告诉Git哪些文件可以忽略,不需要被跟踪,不需要添加到版本管理中。那些受Git追踪的文件不会受到影响。

.gitignore是一个文本文件,其中的每一行代表一个模式,表示匹配规则,开发人员需要忽略的模式相关的模式都应该放到.gitignore文件中

.gitignore一般放在代码库的根目录下,这是官方推荐的做法。但是你也可以把它放置在代码库里边的任意目录下,代码库可以有多个.gitignore文件,其中的匹配模式的路径是相对当前.gitignore所在目录的。

常用规则

  • 空行不会匹配任何文件,因此可以作为提高可读性的分隔符
  • #为注释
  • 反斜杠\为转义符,比如.gitignore会忽略字符结尾的空白,但是在空白前面加上反斜杠,那么就会匹配到空白
  • !为否定模式的前缀选项,被前一个模式排除的匹配文件会再次包含进来;如果!有文本意义,那么在前面加一个反斜杠就可以了,比如\!important!.txt

比如test目录下有两个文件a.txt!important.txt.gitignore的配置如下:

# exclude test directory
test

# include !important.txt file
\!important!.txt

那么在提交代码的日志是这样的,除了important.txt文件,test目录下的其他文件都被忽略了:

image.png

  • 斜杠/是目录分隔符,在.gitignore的搜索模式中,斜杠会出现在搜索模式的开头、中间或末尾
  • /位于搜索模式的开头或中间,那么该模式是相对.gitignore文件的相对路径。否则,该模式也会匹配到.gitignore所在目录以下的目录级别
  • /位于搜索模式的末尾,表示该模式代表只匹配目录,否则该模式表示会同时匹配文件和目录

比如doc/frotz/只会匹配doc/frotz目录,而不会匹配a/doc/frotz目录;但是frotz/匹配frotz目录以及a/frotz目录(所有路径都是相对.gitignore所在路径的)

  • *匹配除了/之外的任意目录和文件,也就是说*只能匹配文件和当前目录下的一级目录(当前文件下的文件和目录),比如foo/*能匹配到foo/test.jsonfoo/bar(目录),但不能匹配到foo/bar/hello.c,因为*匹配不到含有/的部分
  • ?匹配除了/之外的任意字符。
  • []匹配范围,比如[a-zA-Z]能够用来匹配范围内的任意字母。

在匹配完整路径的搜索模式中,两个连续的星号**有特殊含义:

  • 开头的**/表示匹配所有目录。比如**/foo能够匹配任意路径下的文件或目录foo,用法跟foo一样。**/foo/bar会匹配foo目录下的任意bar文件和目录
  • 末尾的**/会匹配内部的所有内容。比如abc/**匹配目录abc(相对于.gitignore的路径)下的所有文件,不限路径深度
  • /**/匹配0个或多个目录。比如a/**/b匹配a/b, a/x/b, a/x/y/b等等
  • 其它星号组合则根据以上规则匹配

哪些文件应该被忽略

  • 日志文件
  • 无用的系统文件,比如macOS上产生的.DS_Store文件
  • 编译生成的文件,比如dist目录
  • 通过包管理器能够下载安装的依赖文件,比如node_modules目录
  • 项目目录下的压缩文件,比如*.zip, *.rar, *.tar.gz, *.war等文件

如何撤销追踪的文件

如果已经将文件提交到代码库,那么就会受到Git的追踪。如果想忽略已经提交的文件,那么首先要将文件撤销追踪,使用如下命令:

git rm --cached FILENAME

不使用.gitignore规则

针对当前项目的追踪规则都放在了.gitignore文件中,那么有没有办法可以禁止追踪文件,而不将这些规则放到.gitignore中呢?答案是有的。比如有一些文件只需要在某些项目里边用到,或者你跟其他同事使用不同的编辑器并且需要忽略那些类型的文件。

本地代码库.gitignore规则

如果你只想在禁止某个代码库追踪文件,那么你可以将匹配规则放到.git/info/exclude

全局.gitignore规则

如果是针对所有代码库禁止追踪的文件,就可以将匹配规则放到全局的.gitignore文件中。首先需要给Git配置选项:

git config --global core.excludeFile ~/.gitignore

.gitkeep

有时候在项目里面除了.gitignore文件之外,还会看到.gitkeep文件,不同的是.gitignore放在项目根目录下,.gitkeep放置的位置则不固定,一般.gitkeep所在的目录下没有其他内容,那.gitkeep的作用是什么呢?

stackoverflow上的高赞回答给出的答案是:.gitkeep只是起占位符作用,用于需要被Git追踪的空目录。因为Git不能添加空目录,所以如果需要将空目录添加到版本控制中,开发人员一般在该目录下创建一个.gitkeep文件。.gitkeep并没有特殊的含义,起其他的名称作用也是一样的。也有人添加.gitignore文件以追踪空目录,但比较具有迷惑性,所以才保持了.gitkeep这个名称。

参考链接

Git .gitignore-简书

What are the differences between .gitignore and .gitkeep?

How to Use a .gitignore File