LV01-Git-04-Git本地仓库-02-忽略文件

本文主要是Git本地仓库中忽略文件的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
Windows windows11
Ubuntu Ubuntu16.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
点击查看本文参考资料
点击查看相关文件下载
--- ---

【说明】本节笔记的相关操作在Windows下进行,因为VS Code有个Git的插件,可以很直观的演示一些东西。由于Git安装后自带一个Git-Bash终端,所以就不用Win下的命令行啦,就用的这个终端,因为它里边的命令与Linux很类似,而windows中的命令行有些命令与linux并不相同,为了统一,还是用用Git自带的终端啦。另外VS Code是可以选择使用的终端的,我直接将VS Code使用的终端改成了git-bash,这样更方便一些。

一、.gitignore文件说明

这一部分我们可以参考:Git - gitignore Documentation (git-scm.com)

1. gitignore文件

一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件的模式。 来看一个实际的 .gitignore 例子:

1
2
3
$ cat .gitignore
*.[oa]
*~

第一行告诉 Git 忽略所有以 .o.a 结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的。

第二行告诉 Git 忽略所有名字以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都用这样的文件名保存副本。 此外,我们可能还需要忽略 log,tmp 或者 pid 目录,以及自动生成的文档等等。 要养成一开始就为我们的新仓库设置好 .gitignore 文件的习惯,以免将来误提交这类无用的文件。

.gitignore文件其实是一个规则,忽略文件的匹配规则,了解git中的忽略规则,则可以随时剔除不需要的文件。它是一个文本文件,它告诉 git 不要跟踪特定的文件、目录或文件类型。

2. 文件格式规范

2.1 忽略规则优先级

在 .gitingore 文件中,每一行指定一个忽略规则,Git 检查忽略规则的时候有多个来源,它的优先级如下(由高到低):

(1)从命令行中读取可用的忽略规则

(2)当前目录定义的规则

(3)父级目录定义的规则,依次递推

(4)$GIT_DIR/info/exclude 文件中定义的规则

(5)core.excludesfile中定义的全局规则

其实吧,官方文档还有好几条,不管有几条,我是没看懂的,后续使用过程中似乎并不需要看懂,有坑的话后边再补充吧。

【注意】

(1).gitignore 是从上往下依次执行命令的,后面的命令会覆盖前面的命令。

(2).gitignore 文件指定Git应该忽略的故意不想跟踪的文件,而Git已经跟踪的文件不会受到该文件的影响

(3).gitignore 文件的目的是确保Git不跟踪的某些文件仍然不被跟踪。要停止跟踪当前正在跟踪的文件,可以使用git rm ——cached命令:

2.2 格式规范

文件 .gitignore 的格式规范如下:

(1)所有空行或者以 # 开头的行都会被 Git 忽略。

(2)可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。

(3)匹配模式可以以(/)开头防止递归。

(4)匹配模式可以以(/)结尾指定目录。

(5)要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。

2.3 glob 模式

所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。

通配符说明
#以”#”号开头表示注释
*以星号“*”通配多个字符(匹配零个或多个任意字符)
**表示匹配多级目录,可在开始,中间,结束。比如a/**/z 可以匹配 a/z, a/b/z 或 a/b/c/z等
以问号“?”通配单个字符
[ ] 以方括号“[ ]”包含单个字符的匹配列表。如[abc]匹配任何一个列在方括号中的字符(要么匹配一个 a,要么匹配一个 b,要么匹配一个 c),如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)
!以叹号“!”表示不忽略(跟踪)匹配到的文件或目录,需要注意的是如果排除了该文件的父级目录,则即使使用 ! ,那么该文件或者目录也不会再次被包含。
/以 / 开头防止递归,只会忽略当前目录的指定文件夹,不会忽略子目录;以“/” 结束的模式只匹配文件夹以及在该文件夹路径下的内容,但是不匹配该文件。如果一个模式不包含斜杠,则它匹配相对于当前 .gitignore 文件路径的内容,如果该模式不在 .gitignore 文件中,则相对于项目根目录

6.3 使用实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 忽略所有的 .a 文件
*.a

# 但跟踪所有的 lib.a,即便我们在前面忽略了 .a 文件
!lib.a

# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO

# 忽略任何目录下名为 build 的文件夹
build/

# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt

# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf

3. 补充说明

GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore 文件列表, 我们可以在 https://github.com/github/gitignore 找到它。在最简单的情况下,一个仓库可能只根目录下有一个 .gitignore 文件,它递归地应用到整个仓库中。 然而,子目录下也可以有额外的 .gitignore 文件。子目录中的 .gitignore 文件中的规则只作用于它所在的目录中。 (Linux 内核的源码库拥有 206 个 .gitignore 文件。)多个 .gitignore 文件的详情我们可以使用 man gitignore 来查看。

二、基本使用

1. 准备文件

我们还是使用上一节的git仓库来做测试,但是我的仓库好像被我删掉了,这里我重新初始化一下然后提交一次。

1
2
3
4
git init
touch README.md
git add .
git commit -m "feat:第一次提交README.md文件"

当前本地git版本库中的文件如下:

image-20230622150645891

然后我们再创建几个文件和文件夹用于测试,创建完成后,目录结构如下:

image-20230622152154485

我们模拟一下平时写C语言可能出现的几种文件,其中test为最终生成的可执行文件,test.o为编译过程中的中间文件,这两个文件可以由test.c和test.h生成,所以一般是不需要参与管理的,我们接下来就用这几个文件实操使用一下.gitignore文件。

2. gitignore的使用

我们在git版本库根目录创建一个.gitignore文件。这一部分的演示就可以体会到VS Code的便利之处啦。

2.1 创建之前的文件状态

我们先来看一下使用.gitignore文件之前的版本库中文件的状态:

1
git status
image-20230622152227699

2.2 创建.gitignore文件并忽略文件

我们在.gitignore中添加以下内容:

1
2
*.o
test

然后我们再看一下现在的文件状态:

image-20230622153113138

可以看到 git 检测到的文件中已经没有 test 和 test.o 了。

2.3 提交本次更新

为方便后边测试,这里将版本库中的文件进行提交。

1
2
git add .
git commit -m "gitignore文件测试第一次提交"

然后我们依次修改这四个文件,然后查看文件状态:

image-20230622154101271

会发现,忽略掉的文件的修改是不会被检测到的。

3. 查看被忽略的文件列表

一个版本库中哪些文件被忽略了?Git为我们提供了相关的命令来查看:

1
git status --ignored # 查看有哪些文件是被忽略的

然后我们可以看到git为我们罗列出当前版本库忽略掉的文件:

image-20230622154500954

4. 添加已忽略的文件

4.1 命令说明

我们要是想把已经忽略的文件添加到暂存库进行跟踪怎么办?Git也为我们提供了命令:

1
git add -f <file_name> # 将已经忽略的文件强制添加到Git

4.2 使用实例

我们将上边的test.o文件也添加到暂存库:

1
git add -f test.o
image-20230622155035193

可以看到test.o作为新文件被添加到暂存库中,并且,此时.gitignore并不能对此文件造成影响,可此命令可以强制破坏.gitignore的规则,将原本已经忽略的文件重新进行跟踪。

4.3 提交更新

为方便后续测试,这里将前边测试的内容进行一次提交:

1
2
git add .
git commit -m "gitignore文件测试第二次提交(管理被忽略的test.o)"

然后我们尝试修改test.o,看一下文件状态的变化:

image-20230622155441317

可以看到这个文件确实是被管理起来了的。测试完成后我们将文件恢复原样,以便于下一次测试。

image-20230622155558211

恢复原样后会发现在VS Code中这个问价依然是灰色的,这是因为我们没有修改.gitignore文件,虽然我们实际上已经开始管理这个文件了,但是VS Code还是以.gitignore为准了,其实最好就是我们要管理某个曾经被忽略的文件的话,在强制添加文件后,还是要修改一下.gitignore文件。所以这里修改.gitignore文件如下:

1
2
#*.o
test

然后重新进行一次提交。

5. 忽略已跟踪文件

5.1 命令格式

那现在我们不想再跟踪test.o文件了,怎么办?我们可以通过git rm命令来取消跟踪:

1
git rm [-r] --cached file_name  # 将版本管理追踪,清空,重新追踪,当我们已经管理了某些文件,但是后续不想再管理时可以使用

-r参数是在我们移除的是目录的跟踪的时候才会用到的,这个命令会产生一次git add操作。

5.2 使用实例

我们将test.o文件从版本库中移除,但是不删除:

1
git rm --cached test.o

会有以下输出信息:

image-20230622164816527

然后我们看一下文件状态:

image-20230622164857082

可以看到test.o文件变成了未跟踪状态,并且本地暂存库也删除了这个文件。需要注意的是,这个时候我们一定要修改.gitignore文件,若是不修改的话,我们再执行一次git add的话,这个文件又会被重新跟踪。然我们修改了.gitignore文件后,文件状态如下:

image-20230622165235273

会发现,未跟踪的文件中已经没有test.o这个文件了,后面我们就可以安心的提交啦,也不用担心这个文件重新被管理起来了。