有时git会建议git rm——cached来取消文件,有时git会重置HEAD文件。什么时候用哪个?

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 <file>从索引中删除了文件,而没有从目录中删除它,而普通的git rm <file>将两者都做,就像OS rm <file>将从目录中删除文件而没有删除它的版本。

其他回答

仅适用于版本2.23及以上,

除了这些建议,你可以使用 Git恢复—staging <文件>,以便取消文件的阶段。

我很惊讶没有人提到git reflog (http://git-scm.com/docs/git-reflog):

# git reflog
<find the place before your staged anything>
# git reset HEAD@{1}

reflog是一个git历史记录,它不仅跟踪对repo的更改,还跟踪用户的操作(例如。拉,签出到不同的分支等),并允许撤销这些操作。因此,与其取消被错误地暂存的文件,还不如恢复到没有暂存文件的位置。

这类似于git reset HEAD <file>,但在某些情况下可能更细粒度。

抱歉,我并没有真正回答你的问题,只是指出了另一种方法来取消我经常使用的文件(我非常喜欢Ryan Stewart和waldyrious的答案);)我希望这能有所帮助。

在我看来,git rm——cached <file>从索引中删除了文件,而没有从目录中删除它,而普通的git rm <file>将两者都做,就像OS rm <file>将从目录中删除文件而没有删除它的版本。

这个线程有点老了,但我仍然想添加一个小演示,因为它仍然不是一个直观的问题:

me$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   to-be-added
#   modified:   to-be-modified
#   deleted:    to-be-removed
#

me$ git reset -q HEAD to-be-added

    # ok

me$ git reset -q HEAD to-be-modified

    # ok

me$ git reset -q HEAD to-be-removed

    # ok

# or alternatively:

me$ git reset -q HEAD to-be-added to-be-removed to-be-modified

    # ok

me$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   to-be-modified
#   deleted:    to-be-removed
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   to-be-added
no changes added to commit (use "git add" and/or "git commit -a")

git reset HEAD(不带-q)给出关于修改文件的警告,其退出码为1,这将被视为脚本中的错误。

Edit: git签出要修改要删除的HEAD也适用于取消暂存,但会将更改完全从工作空间中删除

更新git 2.23.0:命令会不时发生变化。现在,git状态显示:

  (use "git restore --staged <file>..." to unstage)

... 哪种对这三种变化都有效

假设你通过git add <folder>暂存整个目录,但是你想从暂存列表(即运行git状态时生成的列表)中排除一个文件,并将修改保留在排除的文件中(你正在做一些事情,它还没有准备好提交,但你不想失去你的工作…)你可以简单地使用:

Git重置<文件>

当您运行git status时,您将看到您重置的任何文件都是非暂存的,而您添加的其余文件仍然在暂存列表中。