开始使用 Git 时,一个常见问题是“如何告诉 Git 不要再跟踪一个或多个文件?”git rm 命令用于从 Git 存储库中删除文件。可以认为它与 git add 命令相反。

Git rm 概述

git rm 命令可用于删除单个文件或文件集合。git rm 的主要功能是从 Git 索引中删除跟踪的文件。此外,git rm 可用于从暂存索引和工作目录中删除文件。无法仅从工作目录中删除文件。正在操作的文件必须与当前 HEAD 中的文件相同。如果文件的 HEAD 版本与暂存索引或工作树版本之间存在差异,Git 将阻止删除。此块是一种安全机制,用于防止删除正在进行的变更。

请注意,git rm 不会删除分支。了解有关使用 git 分支的更多信息

使用

<file>…​

指定要删除的目标文件。选项值可以是单个文件、以空格分隔的文件列表 file1 file2 file3 或通配符文件 glob (~./directory/*)

-f
--force

-f 选项用于覆盖 Git 所做的安全检查,以确保 HEAD 中的文件与暂存索引和工作目录中的当前内容匹配。

-n
--dry-run

"dry run" 选项是一种保护措施,它将执行 git rm 命令,而不是真的删除这些文件。 相反,它会输出删除哪些文件。

-r

-r 选项是“递归”的简写。在递归模式下操作时, git rm 将删除目标目录和该目录的所有内容。

--

分隔符选项用于明确区分传递给 git rm 的文件名列表和参数。 如果某些文件名的语法可能会被误认为是其他选项,这将非常有用。

--cached

缓存选项指定删除应仅在暂存索引时进行。 工作目录文件将单独保留。

--ignore-unmatch

这会导致命令以 0 sigterm 状态退出,即使没有匹配的文件也是如此。这是 Unix 级别的状态码。代码 0 表示成功调用该命令。使用 git rm 作为需要优雅降级的更大 shell 脚本的一部分时,--ignore-unmatch 选项会很有用。

-q
--quiet

静默选项隐藏了 git rm 命令的输出。该命令通常会为每个删除的文件输出一行。

如何撤销 git rm

执行 git rm 不是永久更新。该命令将更新暂存索引和工作目录。在创建新提交并将变更添加到提交历史记录之前,这些变更不会保留。这意味着可以使用常用的 Git 命令“撤销”此处的变更。

git reset HEAD

重置会将当前的暂存索引和工作目录还原为 HEAD 提交。这将撤销 git rm

git checkout .

签出将产生同样的效果,并从 HEAD 恢复文件的最新版本。

如果执行 git rm 并创建了一个新提交,该提交会保留删除操作,则可以使用 git reflog 来查找在 git rm 执行之前的引用。了解有关使用 git reflog 的更多信息。

讨论

给命令的 参数可以是精确路径、通配符文件 glob 模式或精确的目录名。该命令仅删除当前提交到 Git 存储库的路径。

通配符文件 glob 跨目录匹配。使用通配符 glob 时务必谨慎。考虑以下示例:directory/*directory*。第一个示例将删除 directory/ 的所有子文件,而第二个示例将删除所有兄弟目录,例如 directory1 directory2 directory_whatever,这可能是意想不到的结果。

git rm 的范围

git rm 命令仅在当前分支上运行。删除事件仅应用于工作目录和暂存索引树。创建新提交之前,文件删除不会保留在存储库历史记录中。

为什么要用 git rm 而不是 rm

Git 存储库将识别出常规 shell rm 命令何时在它正在跟踪的文件上执行。 它将更新工作目录以反映删除操作。删除后它不会更新暂存索引。必须在已删除的文件路径上执行额外的 git add 命令才能将变更添加到暂存索引中。git rm 命令在这方面起到了快捷方式的作用,它将在删除后更新工作目录和暂存索引。

示例

git rm Documentation/\*.txt

此示例使用通配符文件 glob 删除所有 Documentation 目录及其子目录的 *.txt files 子目录。

请注意,在本示例中,星号 * 用斜杠转义,这是防止 shell 扩展通配符的防护。然后,通配符扩展 Documentation/ 目录下文件和子目录的路径名。

git rm -f git-*.sh

此示例使用 force 选项并以所有通配符 git-*.sh 文件为目标。force 选项将目标文件从工作目录和暂存索引中显式删除。

如何删除文件系统中不再存在的文件

如上所述,“为什么使用 git rm 而不是 rm”,git rm 实际上是一个方便的命令,它结合了标准 shell rmgit add 来从工作目录中删除文件,并将删除提升到暂存索引。如果仅使用标准 shell rm 命令删除了多个文件,存储库可能会陷入麻烦的状态。

如果打算将所有明确删除的文件记录为下一次提交的一部分,git commit -a 会将所有删除事件添加到暂存索引中,为下一次提交做准备。

但是,如果意图是永久删除使用 shell rm 删除的文件,请使用以下命令:

git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached

此命令将生成从工作目录中删除的文件列表,并将该列表传送到 git rm --cached,这将更新暂存索引。

Git rm 摘要

git rm 命令在两个主要 Git 内部状态管理树上运行:工作目录和暂存索引。git rm 用于从 Git 存储库中删除文件。这是一种方便的方法,它将默认 shell rm 命令的效果与 git add 相结合。这意味着它将先从文件系统中删除一个目标,然后将该删除事件添加到暂存索引中。该命令是可用于撤销 Git 中变更的众多命令之一。