git rm --cached
的定义是:使用此选项仅从索引中取消暂存并删除路径。工作树文件(无论是否修改)都将被保留不变。
“路径”指的是文件或目录在仓库中的相对位置。
git rm --cached
的定义是:$ git checkout -b feature master
<make all-new file>
$ git add newfile.ext
$ git commit
feature
在其最新的提交中有这个文件,而master
没有这个文件。$ git checkout master
newfile.ext
从工作树中消失。git checkout
以获取不在其中的文件newfile.ext
的提交(位于某个分支的顶部)。但是,newfile.ext
现在存在于您的工作树和索引中。因此,Git必须从索引中拉出副本。它还将副本从您的工作树中删除。这就是我们刚才所做的,从develop
(其中有一个新文件)切换到master
(其中没有该文件)。develop
:$ git checkout develop
develop
分支上的最新提交确实有文件 newfile.ext
。你现在的索引或工作树中没有它,因此 Git 可以安全地将 newfile.ext
从 develop
分支上的最新提交复制到索引中,然后再将其复制到你的工作树中。现在你已经拥有了这个文件,一切都很好。newfile.ext
。它是一个配置文件,或者是存储活跃用户的数据库,或其他东西。我们不想在 feature
分支中包含它。所以我们把它删除了。$ git rm newfile.ext
$ git commit
但是,糟糕的是,我们丢失了配置(或数据库或其他什么东西)!所以,不要使用git rm
命令,让我们不要执行上述两个命令。相反,让我们执行:
git reset HEAD~1
这将撤消最后一次提交,并将更改还原为工作目录中的文件。然后,您可以恢复您最初的回答中提到的配置文件。
$ git rm --cached newfile.ext
$ git commit
newfile.ext
从索引中删除,但是并没有从我们的工作区删除。这个文件仍然在我们的工作区中。它已经从索引中删除了,因此在feature
分支上新提交中不再有它。feature
分支上的旧提交,比如通过它的哈希ID,会发生什么呢?那个提交确实包含newfile.ext
。Git想要将该文件放入索引并将其复制到工作区。git checkout
将覆盖newfile.ext
。有时候-具体何时有点棘手-Git会无论如何覆盖newfile.ext
!如果我们强制进行检出,Git将按照我们的要求覆盖newfile.ext
。现在,该文件既存在于索引中(在保存它的提交中看到),也以常规(非Git化)形式存在于我们的工作区中。feature
或master
- 这两个命令都标识不包含该文件的提交-Git现在将从索引和工作区中删除该文件。我们宝贵的配置或数据库或任何其他东西又不见了!git rm --cached
的作用,但要记住它也会设置这些陷阱:其中包含该文件的提交,当您检出时可能会覆盖一些重要文件。您无法更改这些现有的提交:它们将永远拥有该文件。如果这是一个问题,您能做的最好的事情就是避免使用它们,或者完全停止使用它们。