简体中文 ▾ 主题 ▾ 最新版本 ▾ git-rm 上次更新于 2.50.0

名称

git-rm - 从工作目录和索引中移除文件

概要

git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch]
       [--quiet] [--pathspec-from-file=<file> [--pathspec-file-nul]]
       [--] [<pathspec>…​]

描述

从索引中移除匹配 pathspec 的文件,或者从工作目录和索引中移除。git rm 不会仅从工作目录中移除文件。(没有选项可以仅从工作目录移除文件但保留在索引中;如果要做这个,请使用 /bin/rm。)要移除的文件必须与分支的最新提交相同,并且其内容不能有任何暂存的更新,尽管默认行为可以通过 -f 选项覆盖。当给出 --cached 时,暂存的内容必须与分支的最新提交或磁盘上的文件匹配,允许仅从索引中移除文件。当使用稀疏检出时(参见 git-sparse-checkout[1]),git rm 将只移除稀疏检出模式下的路径。

选项

<pathspec>...

要移除的文件。可以给出一个前导目录名(例如,要移除 dir/file1dir/file2dir)来移除目录中的所有文件,以及递归地移除所有子目录,但这需要显式给出 -r 选项。

命令只移除 Git 已知的路径。

文件 globbing 会跨越目录边界进行匹配。因此,给定两个目录 dd2,使用 git rm d*'git rm d/*' 之间存在差异,因为前者还会移除目录 d2 的全部内容。

更多详情,请参见 gitglossary[7]<pathspec> 条目。

-f
--force

覆盖“尚未更新”的检查。

-n
--dry-run

实际上不移除任何文件。相反,只显示它们是否在索引中并且会(否则)被命令移除。

-r

当给出前导目录名时,允许递归移除。

--

此选项可用于区分命令行选项和文件列表(当文件名可能被误认为是命令行选项时很有用)。

--cached

使用此选项可仅从索引中取消暂存并移除路径。工作目录文件,无论是否修改,都将保持不变。

--ignore-unmatch

即使没有文件匹配,也以零状态退出。

--sparse

允许更新稀疏检出锥体之外的索引条目。通常,git rm 会拒绝更新不适合稀疏检出锥体的路径的索引条目。更多信息请参见 git-sparse-checkout[1]

-q
--quiet

git rm 通常会为每个移除的文件输出一行(以 rm 命令的形式)。此选项会抑制该输出。

--pathspec-from-file=<file>

Pathspec 在 <file> 中而不是在参数中传递。如果 <file>-,则使用标准输入。Pathspec 元素由 LFCR/LF 分隔。Pathspec 元素可以按照 core.quotePath 配置变量的解释进行引用(参见 git-config[1])。另请参见 --pathspec-file-nul 和全局 --literal-pathspecs

--pathspec-file-nul

仅在与 --pathspec-from-file 一起使用时有意义。路径规范元素由 NUL 字符分隔,所有其他字符都被视为字面值(包括换行符和引号)。

移除在文件系统中已消失的文件

git rm 没有用于仅从索引中移除已从文件系统中消失的路径的选项。但是,根据用例,有几种方法可以做到这一点。

使用“git commit -a”

如果你打算让下一次提交记录工作目录中所有已跟踪文件的修改,并记录已从工作目录中移除的文件(与 git rm 相反),请使用 git commit -a,因为它会自动识别并记录所有移除操作。你也可以通过使用 git add -u 来在不提交的情况下达到类似的效果。

使用“git add -A”

接受供应商分支的新代码时,你可能希望同时记录路径的移除、新路径的添加以及现有路径的修改。

通常,你会先用此命令从工作目录中移除所有已跟踪文件

git ls-files -z | xargs -0 rm -f

然后将新的代码解压到工作目录。或者,你也可以使用 rsync 将更改同步到工作目录。

之后,记录工作目录中所有移除、添加和修改的最简单方法是

git add -A

参见 git-add[1]

其他方法

如果你真正想做的只是从索引中移除那些在工作目录中不再存在的文件(也许是因为你的工作目录很脏,无法使用 git commit -a),请使用以下命令

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

子模块

只有使用 gitfile 的子模块(意味着它们是用 Git 版本 1.7.8 或更高版本克隆的)才会被从工作目录中移除,因为它们的存储库位于超项目的 .git 目录内。如果子模块(或其中嵌套的子模块)仍然使用 .git 目录,git rm 会将子模块的 git 目录移入超项目的 git 目录,以保护子模块的历史记录。如果存在,gitmodules 文件中的 submodule.<name> 部分也会被移除,并且该文件会被暂存(除非使用了 --cached-n)。

HEAD 与索引中记录的一致、没有已修改的跟踪文件且子模块的工作目录中没有未被忽略的未跟踪文件时,该子模块被认为是“最新”的。被忽略的文件被视为可消耗的,不会阻止子模块的工作目录被移除。

如果你只想从工作目录中移除子模块的本地签出而不提交移除操作,请改用 git-submodule[1] deinit。另请参见 gitsubmodules[7] 以获取有关子模块移除的详细信息。

示例

git rm Documentation/\*.txt

从索引中移除 Documentation 目录及其任何子目录下的所有 *.txt 文件。

请注意,在此示例中,星号 * 已被 shell 转义;这使得 Git 而不是 shell 来展开 Documentation/ 目录下的文件和子目录的路径名。

git rm -f git-*.sh

由于此示例允许 shell 展开星号(即,你明确列出了文件),因此它不会移除 subdir/git-foo.sh

BUG

每次超项目更新移除一个已填充的子模块时(例如,在移除之前和之后切换提交时),旧位置会留有一个过时的子模块签出。只有当旧目录使用 gitfile 时,移除旧目录才是安全的,否则子模块的历史记录也会被删除。当递归子模块更新实现后,此步骤将变得不必要。

另请参阅

GIT

Git[1] 套件的一部分