采用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
目录下的其他文件都被忽略了:
- 斜杠
/
是目录分隔符,在.gitignore
的搜索模式中,斜杠会出现在搜索模式的开头、中间或末尾 /
位于搜索模式的开头或中间,那么该模式是相对.gitignore
文件的相对路径。否则,该模式也会匹配到.gitignore
所在目录以下的目录级别/
位于搜索模式的末尾,表示该模式代表只匹配目录,否则该模式表示会同时匹配文件和目录
比如doc/frotz/
只会匹配doc/frotz
目录,而不会匹配a/doc/frotz
目录;但是frotz/
匹配frotz
目录以及a/frotz
目录(所有路径都是相对.gitignore
所在路径的)
*
匹配除了/
之外的任意目录和文件,也就是说*
只能匹配文件和当前目录下的一级目录(当前文件下的文件和目录),比如foo/*
能匹配到foo/test.json
,foo/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
这个名称。