协慌网

登录 贡献 社区

为什么有两种方法可以在 Git 中取消暂存文件?

有时 git 建议使用git rm --cached来取消git reset HEAD file文件,有时git reset HEAD file 。我什么时候应该使用哪个?

编辑:

D:\code\gt2>git init
Initialized empty Git repository in D:/code/gt2/.git/
D:\code\gt2>touch a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       a
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a
#
D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a

D:\code\gt2>touch b

D:\code\gt2>git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       b
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add b

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

答案

git rm --cached <filePath> 不会 取消 git rm --cached <filePath>文件,它实际上会从 repo 中删除文件 (假设它之前已经提交过),但是将文件保留在工作树中(让你无法跟踪)文件)。

git reset -- <filePath>取消暂存给定文件的任何暂存更改。

也就是说,如果你在一个新的文件中使用了git rm --cached ,它基本上看起来就像你刚刚从未提交它一样,因为它之前从未提交过。

git rm --cached用于从索引中删除文件。在文件已经存在于 repo 中的情况下, git rm --cached将从索引中删除该文件,将其保留在工作目录中,并且提交现在也将从 repo 中删除它。基本上,在提交之后,您将无文件化并保留本地副本。

git reset HEAD file (默认情况下使用--mixed标志)的不同之处在于,在文件已经存在于 repo 中的情况下,它会将文件的索引版本替换为 repo(HEAD)中的文件取消对它的修改

在无版本文件的情况下,它会取消整个文件的分级,因为 HEAD 中没有该文件。在这方面, git reset HEAD filegit rm --cached是相同的,但它们不相同(如 repo 中已有文件的情况所述)

关于Why are there 2 ways to unstage a file in git?取消Why are there 2 ways to unstage a file in git? - 从来没有真正只有一种方法可以在 git 中做任何事情。这就是它的美丽:)

很简单:

  • git rm --cached <file> 使 git 完全停止跟踪文件 (将其保留在文件系统中,与普通git rm * 不同)
  • git reset HEAD <file> 取消自上次提交以来对 git reset HEAD <file> 所做的任何修改 (但不会在文件系统中恢复它们,这与命令名称可能建议的相反 **)。该文件仍在版本控制之下。

如果文件之前没有处于版本控制之下(即你第一次取消了你刚刚git addgit add的文件),那么这两个命令具有相同的效果,因此它们的外观是 “两种方式做某事 “。

* 请记住 @DrewT 在他的回答中提到的警告,关于git rm --cached 先前已提交到存储库的文件的缓存。在这个问题的上下文中,对于刚添加但尚未提交的文件,没有什么可担心的。

** 由于它的名字,我害怕长时间使用 git reset 命令 - 而且今天我仍然常常查找语法,以确保我不会搞砸。 ( 更新 :我终于花时间总结了 tldr 页面中git reset的用法 ,所以现在我有一个更好的心理模型,它是如何工作的,以及当我忘记一些细节时的快速参考。)