Git clean 清理仓库
在本节中,我们将重点详细讨论git clean
命令。git clean在某种程度上是“撤消”命令。Git clean可以被认为是对其他撤销命令的补充,比如git reset和git checkout等。这些撤销命令是对先前添加到 Git 跟踪索引的文件进行操作。但是这里有一个前提,文件必须是已经使用git add命令添加到Git暂存区里有了跟踪索引的文件。
而 git clean 命令是对未跟踪的文件进行操作。未跟踪文件是已经在仓库工作目录中创建但是尚未使用 git add命令添加到暂存区的未建立跟踪索引的文件。为了更好地展示跟踪文件和未跟踪文件之间的区别,我们看下面的示例
$ mkdir git_clean_test
$ cd git_clean_test/
$ git init .
Initialized empty Git repository in /Users/kev/code/git_clean_test/.git/
$ echo "tracked" > ./tracked_file
$ git add ./tracked_file
$ echo "untracked" > ./untracked_file
$ mkdir ./untracked_dir && touch ./untracked_dir/file
$ git status
上面示例在git_clean_test
目录中创建了一个新的 Git 仓库。然后继续创建一个文件,tracked_file 并将其添加 Git 索引,此外,还创建了一个untracked_file文件,以及一个文件夹untracked_dir.。然后调用 git status
命令显示当前仓库的状态。我们发现 Git 的已跟踪和未跟踪的文件的内部状态。仓库处于这种状态时,我们可以执行git clean
命令来查看其用途。
$ git clean
fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given; refusing to clean
此时,执行默认git clean命令可能会产生致命错误。我们使用上面的示例可以解释为什么会是这样子。默认情况下,Git 全局配置项中要求 git clean 后面要跟上强制
选项。这是一个重要的安全机制。最后 git clean是不可撤销的。执行完成后,git clean将会对文件进行硬删除,类似于执行命令 rm
。在运行之前,请确保您确实要删除未跟踪的文件。
常用选项和用法
鉴于前面对默认 git clean 行为和产生的错误的解释,下面的内容解释了各种 git clean 用例及其对应的所需的选项。
-n
-n
选项将执行 git clean 的“试运行”。所谓试运行就是显示哪些文件将被删除而不实际删除它们。最佳做法是始终先执行 git clean 的试运行。我们可以在我们之前创建的演示仓库中执行该命令。
$ git clean -n
从上面的输出我们可以看出,untracked_file将在执行 git clean 命令时删除。
注意,此处并未显示 untracked_dir。默认情况下 git clean 不会对目录进行递归删除操作。这是防止意外永久删除的另一种安全机制。
-f 或者 --force
force 选项启动从当前目录中实际删除未跟踪文件。除非将clean.requireForce
配置选项设置为 false,否则必须跟上强制选项。这不会删除由 .gitignore 指定的不进行跟踪的文件夹或文件。现在让我们使用git clean 命令来对仓库中为跟踪的文件执行清理操作。
$ git clean -f
该命令输出被删除的文件。我们可以在此处看到untracked_file已删除。此时执行 git status 或执行 ls
会显示 untracked_file 已被删除并且在文件系统中已经查不到了。默认情况下 git clean -f
将对当前目录中的所有未跟踪文件进行清理操作。此外,可以在-f
选项后面跟上 <path> 值,用来指定要删除的特定文件。
git clean -f <path>
-d 指定要删除的文件夹
-d
选项告诉 git clean 可以删除任何未跟踪的目录,不跟此选项的默认情况下git clean 将会忽略目录。我们可以在前面的示例中添加 -d 选项:
$ git clean -dn
Would remove untracked_dir/
$ git clean -df
Removing untracked_dir/
在这里,我们使用 -dn
组合执行了“试运行”,输出 untracked_dir 已准备好删除。然后我们执行强制清理,并收到 untracked_dir 被删除的输出。
-x 强制删除 .gitignore 忽略的文件
实际情况中,通常会有一个用来构建项目的目录,这个目录是不需要提交到仓库的跟踪索引中的。构建目录将包含从提交的源代码生成的临时构建工件。此构建目录通常添加到仓库的 .gitignore
文件中。默认情况下,git clean 不会清理由 .gitignore指定的忽略的文件。但是要想清理这种文件,其实和清理其他未跟踪文件一样,也很简单。-x
选项告诉 git clean 要连同由 .gitignore 忽略的文件一同清理。与之前的 git clean 调用一样,最佳做法是在最终删除之前先执行“试运行”。-x 选项将作用于所有被忽略的文件,而不仅仅是项目构建特定的文件。比如 ./idea 此类IDE配置文件,这对于我们项目来说是意料之外的东西。
git clean -xf
像 -d 选项一样 -x 可以与其他选项组合。上面示例演示了与 -f 的组合,它将从当前目录中删除未跟踪的文件以及 Git 通常由 .gitignore
忽略的任何文件。
git clean 的交互模式
除了我们迄今为止演示的临时命令行执行之外,git clean还有一个“交互”模式,可以通过传递-i
选项来启动交互。让我们重新审视本文档介绍中的示例仓库。在最开始状态下,我们将开始一个交互式清理会话。
$ git clean -di
我们已经使用 -di
选项启动了交互式会话,因此它也会对我们的 untracked_dir 目录进行一个清理。 交互模式将显示一个What now>
提示,请求将命令应用于未跟踪的文件。首先我们先输入 6: help 来进一步查看其他的命令的详细说明。
What now> 6
5: quit
是直接退出交互式会话。
1: clean
将删除指定的项目。如果我们在此时执行1: clean
,那么 untracked_dir/ untracked_file 将被删除
4: ask each
将遍历每个未跟踪的文件并显示Y/N
删除提示。它看起来像下面这样:
2: filter by pattern
将显示一个额外的提示,它接受用于过滤未跟踪文件列表的输入。
在这里,我们输入*_file
通配符模式将未跟踪的文件列表限制为untracked_dir.
3: select by numbers
与命令 2 类似,命令 3 用于细化未跟踪的文件名列表。交互式会话将提示输入与未跟踪文件名对应的数字。
概括
回顾一下,git clean是一种清理仓库工作目录中未跟踪的文件的便捷方式。未跟踪的文件是那些在仓库目录中但尚未使用 git add 命令添加到仓库暂存区索引的文件。git clean 的总体效果可以通过使用 git status 和 操作系统本机的删除工具来实现。git clean可以与git reset一起使用,来完全撤销仓库中的任何文件和提交。