git rm 将从暂存区域中删除条目。这与“取消暂存”文件的 git reset HEAD 有点不同。 “取消暂存”是指它将暂存区域恢复到我们开始修改之前的状态。另一方面, git rm 只是将文件完全踢出舞台,因此它不会包含在下一个提交快照中,从而有效地删除它。默认情况下,一个 git rm 文件将从暂存区域中完全删除该文件,并从您的磁盘 >(工作目录)中删除该文件。要将文件保留在工作目录中,可以使用 git rm --cached。
但是 git rm --cached asd
和 git reset head -- asd
之间究竟有什么区别?
比如说,一个文件可以存在三个地方——(提交的)树、索引和工作副本。当您只是将文件添加到文件夹时,您就是将其添加到工作副本中。
当您执行 git add file
之类的操作时,您会将其添加到索引中。当你提交它时,你也将它添加到树中。
它可能会帮助您了解 git reset
中三个更常见的标志:
git reset [--
现在,当您执行 git reset HEAD
之类的操作时,您实际执行的是 git reset HEAD --mixed
,它会将索引“重置”到您开始添加文件/向索引添加修改之前的状态(通过 git add
) .在这种情况下,无论工作副本的状态是什么,您都没有对其进行任何更改,但是您以一种现在与树的 HEAD 同步的方式更改了索引。 无论 git add
用于暂存以前提交但已更改的文件,还是用于添加新的(以前未跟踪的)文件,git reset HEAD
都与 git add
完全相反。
另一方面,git rm
从工作目录和索引中删除一个文件,当您提交时,该文件也会从树中删除。但是,git rm --cached
会单独从索引中删除文件并将其保存在您的工作副本中。在这种情况下,如果文件之前已提交,那么您将索引设置为与树的 HEAD 和工作副本不同,因此 HEAD 现在具有以前提交的文件版本,索引根本没有没有文件,工作副本有它的最后修改。现在提交将同步索引和树,并且文件将从树中删除(使其在工作副本中未跟踪)。 当使用 git add
添加新的(以前未跟踪的)文件时,git rm --cached
与 git add
完全相反(与 git reset HEAD
几乎相同)。
Git 2.25 为这些情况引入了一个新命令 git restore
,但从 Git 2.28 开始,它在手册页中被描述为“实验性”,因为行为可能会改变。
也许一个例子会有所帮助:
git rm --cached asd
git commit -m "the file asd is gone from the repository"
相对
git reset HEAD -- asd
git commit -m "the file asd remains in the repository"
请注意,如果您没有更改任何其他内容,则第二次提交实际上不会做任何事情。
--
用于将命令选项与文件名分开。如果同时有一个名为 asd
的 branch 和一个 file,那么 git reset HEAD asd
将是不明确的。 --
表示“这之后的所有内容都是文件名”。
git reset HEAD <file>
是否与 git rm --cached <file>
和 git add --intent-to-add <file>
完全相同?
git rm --cached file
将从舞台中删除文件。也就是说,当您提交时,文件将被删除。 git reset HEAD -- file
将简单地将暂存区域中的文件重置为它在 HEAD 提交时的状态,即,将撤消您自上次提交以来对其所做的任何更改。如果该更改恰好是新添加的文件,那么它们将是等效的。
git rm --cached file
与git add
相反的概念(如其他答案中所述),这个答案对我来说很有意义,而且非常简洁。几乎和这条评论一样短;)
git rm --cached file
不是 git add file
的对立面。在您添加了一个新的、以前未跟踪的文件的特定情况下,该行为恰好与 git add file
相反。在所有其他情况下,git add file
的对立面是 git reset HEAD file
。 git reset HEAD file
在第一种情况下(添加未跟踪的文件)也会反转 git add file
,并且在每种情况下,如果您想反转 git add,这就是 git 建议这样做的原因。
git reset HEAD file
不会有任何效果,您只会得到 fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
git rm --cached
之后,git diff
命令没有显示任何差异,但git diff --cached
显示了差异,就好像它仍然被缓存一样。但是git status
将文件显示为Untracked
。好像有点违和git reset --mixed
。git rm --cached
与git add
相反的说法让我有点困惑。从字面上看,这是不正确的,可能会造成损坏。就我而言,我使用git add
将修改后的文件添加到暂存区,并希望与“那个添加”相反,而不是文件的初始添加。 +Greg Hewgill 的回答帮助我更清楚地了解情况。git rm --cached
'与git add file
完全相反' 具有误导性。git reset file
更接近于git add file
的反面。