有时git建议git rm --cached
取消暂存文件,有时候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
#
答案 0 :(得分:1673)
git rm --cached <filePath>
不会取消暂存文件,它实际上从repo中删除文件(假设它之前已经提交)但是将文件留在工作树中(留下未跟踪的文件)。
git reset -- <filePath>
将取消暂存给定文件的任何暂存更改。
也就是说,如果你在一个新的文件中使用了git rm --cached
,它基本上就像你刚刚从未提交它一样,因为它之前从未提交过。
答案 1 :(得分:320)
git rm --cached
用于从索引中删除文件。如果文件已经在repo中,git rm --cached
将从索引中删除该文件,将其保留在工作目录中,并且提交现在也将从repo中删除它。基本上,在提交之后,您将无文件化并保留本地副本。
git reset HEAD file
(默认使用--mixed
标志)不同之处在于,在文件已经存在于repo中的情况下,它将文件的索引版本替换为repo(HEAD),有效地取消修改。
对于未版本控制的文件,由于HEAD中没有文件,因此它将取消整个文件的分级。在这方面,git reset HEAD file
和git rm --cached
是相同的,但它们不相同(如已在回购中的文件所述)
对于Why are there 2 ways to unstage a file in git?
的问题 - 从来没有一种方法可以在git中做任何事情。这就是它的美丽:)
答案 2 :(得分:114)
很简单:
git rm --cached <file>
让git完全停止跟踪文件(将其保留在文件系统中,与普通git rm
不同*)git reset HEAD <file>
取消自上次提交以来对文件所做的任何修改(但不会在文件系统中将其还原,与命令名称可能建议的相反**) 。该文件仍处于修订控制之下。如果文件之前没有进行版本控制(即您第一次取消暂停刚刚git add
编辑的文件),则这两个命令具有相同的效果,因此,这些存在的出现是两种做事的方式&#34;。
*请记住@DrewT在他的回答中提到的警告,关于以前提交的文件的git rm --cached
到存储库。在这个问题的上下文中,对于刚添加但尚未提交的文件,没有什么可担心的。
**由于它的名字,我害怕使用git reset命令的尴尬很长时间 - 而且今天我仍然经常查找语法,以确保我不会搞砸。 (更新:我终于花时间到了summarize the usage of git reset
in a tldr page,所以现在我有一个更好的心理模型,它是如何工作的,以及我忘记一些细节时的快速参考。)
答案 3 :(得分:44)
这个帖子有点旧,但我还是想添加一些演示,因为它仍然不是一个直观的问题:
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
也可用于取消暂停,但会从工作区中完全删除更改
答案 4 :(得分:32)
如果你不小心上演了你不想提交的文件,并且想要确定你保留更改,你也可以使用:
git stash
git stash pop
这将重置为HEAD并重新应用您的更改,允许您重新暂存单个文件以进行提交。如果您忘记为拉取请求创建功能分支(git stash ; git checkout -b <feature> ; git stash pop
),这也很有用。
答案 5 :(得分:15)
如果有问题的文件已经在repo中且受版本控制(之前已提交等),则这两个命令有几个细微差别:
git reset HEAD <file>
在当前提交中取消暂存文件。git rm --cached <file>
将取消暂存文件以供将来提交。它已取消暂停,直到再次使用git add <file>
添加。还有一个更重要的区别:
git rm --cached <file>
并将您的分支推送到远程控制台后,任何从远程控制器拉出分支的人都会从其文件夹中删除 ACTUALLY 文件,即使在本地工作集中文件刚刚未跟踪(即没有从文件夹中物理删除)。最后一个区别对于包含配置文件的项目很重要,其中团队中的每个开发人员都有不同的配置(即不同的基本URL,IP或端口设置),所以如果您使用git rm --cached <file>
任何人谁拉你的分支必须手动重新创建配置,或者你可以发送它们你的,他们可以重新编辑回他们的IP设置(等),因为删除只会影响人们从遥控器拉你的分支。
答案 6 :(得分:8)
假设您stage
通过git add <folder>
整个目录,但您希望从暂存列表中排除某个文件(即运行git status
时生成的列表)和保留在排除文件中的修改(您正在处理某些事情并且它尚未准备好提交,但您不想丢失您的工作......)。你可以简单地使用:
git reset <file>
当您运行git status
时,您会看到reset
unstaged
的任何文件added
以及您staged
的其余文件仍在this
中{1}}列表。
答案 7 :(得分:8)
D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: a
(使用“git rm --cached ...”取消演出)
git是一个指针系统
您还没有提交更改指针的提交
“将文件从指向桶中取出”的唯一方法是删除告诉git注意更改的文件
D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a
git commit -m a
D:\code\gt2>git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: b
#
(使用“git reset HEAD ...”取消暂停)
答案 8 :(得分: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的答案。);)我希望它有所帮助。
答案 9 :(得分:3)
在我看来,git rm --cached <file>
从索引中删除文件而不将其从普通git rm <file>
同时执行这两者的目录中删除,就像操作系统rm <file>
将删除目录中的文件,而不删除其版本控制。
答案 10 :(得分:3)
只需使用:
git reset HEAD <filename>
这会取消暂存文件并保留对它所做的更改,因此,如果需要,您可以依次更改分支,并将这些文件git add
改为另一个分支。所有更改都会保留。
答案 11 :(得分:1)
在 > 2.2 的较新版本中,您可以使用 git restore --staged <file_name>
。
注意这里
如果您想一次取消暂存(移动到更改)您的文件,请使用上述命令和您的文件名。例如
git restore --staged abc.html
现在,如果您想一次取消所有文件的暂存,您可以执行以下操作
git restore --staged .
请注意空格和点 (.) 这意味着考虑暂存所有文件。
答案 12 :(得分:0)
代替这些建议,您可以使用
git restore --staged <file>
以便unstage
个文件。