为何有两种方法能够在Git中取消暂存文件?

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

编辑: 缓存

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
#

#1楼

这个线程有点旧,但我仍然想添加一些演示,由于它仍然不是一个直观的问题: spa

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,这将被视为脚本中的错误。 线程

编辑: git checkout HEAD to-be-modified to-be-removed也可用于取消暂存,但会从工做空间中彻底删除更改 版本控制


#2楼

在我看来, git rm --cached <file>从索引中删除文件而不将其从普通git rm <file>同时执行这二者的目录中删除,就像OS rm <file>将删除文件同样从目录中删除其版本控制。 code


#3楼

若是有问题的文件已经在repo中且受版本控制(以前已提交等),则这两个命令有几个细微差异: 索引

  • git reset HEAD <file>取消暂存当前提交中的文件。
  • git rm --cached <file>也将取消git rm --cached <file>该文件以供未来提交。 它是未分阶段的,直到它再次使用git add <file>

还有一个更重要的区别: ip

  • 运行git rm --cached <file>并将分支推送到远程git rm --cached <file>后,任何从远程控制器中拉出分支的人都将从其文件夹中删除文件,即便在本地工做集中文件刚刚未被跟踪(即不是从文件夹中物理删除)。

最后一个区别对于包含配置文件的项目很重要,其中团队中的每一个开发人员都有不一样的配置(即不一样的基本URL,ip或端口设置),因此若是你使用git rm --cached <file>任何人拉您的分支必须手动从新建立配置,或者您能够将它们发送给您的,而且能够将其从新编辑回其IP设置(等),由于删除只会影响人们从远程启动分支。 开发


#4楼

很简单: rem

  • 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的用法 ,因此如今我有一个更好的心理模型,它是如何工做的,以及当我忘记一些细节时的快速参考。)


#5楼

我很惊讶没有人提到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的更改,还跟踪用户操做(例如,pull,checkout到不一样的分支等)并容许撤消这些操做。 所以,不是取消暂停错误播放的文件,而是能够恢复到不放置文件的位置。

这与git reset HEAD <file>相似,但在某些状况下可能更精细。

对不起 - 没有真正回答你的问题,但只是指出另外一种方式来取消我常用的文件(我很是喜欢Ryan Stewart和waldyrious的回答。);)我但愿它有所帮助。

相关文章
相关标签/搜索