reset
最后更新于:2022-04-01 00:51:05
## git reset HEAD 取消缓存已缓存的内容
`git reset` 可能是人类写的最费解的命令了。 我用 Git 有些年头了,甚至还写了本书,但有的时候还是会搞不清它会做什么。 所以,我只说三个明确的,通常有用的调用。请你跟我一样尽管用它 —— 因为它可以很有用。
在此例中,我们可以用它来将不小心缓存的东东取消缓存。假设你修改了两个文件,想要将它们记录到两个不同的提交中去。 你应该缓存并提交一个,再缓存并提交另外一个。如果你不小心两个都缓存了,那要如何才能_取消_缓存呢? 你可以用 `git reset HEAD -- file`。 技术上说,在这里你不需要使用 `--` —— 它用来告诉 Git 这时你已经不再列选项,剩下的是文件路径了。 不过养成使用它分隔选项与路径的习惯很重要,即使在你可能并不需要的时候。
好,让我们看看取消缓存是什么样子的。这里我们有两个最近提交之后又有所改动的文件。我们将两个都缓存,并取消缓存其中一个。
~~~
$ git status -s
M README
M hello.rb
$ git add .
$ git status -s
M README
M hello.rb
$ git reset HEAD -- hello.rb
Unstaged changes after reset:
M hello.rb
$ git status -s
M README
M hello.rb
~~~
现在你执行 `git commit` 将只记录 `README` 文件的改动,并不含现在并不在缓存中的 `hello.rb`。
如果你好奇,它实际的操作是将该文件在“索引”中的校验和重置为最近一次提交中的值。 `git add` 会计算一个文件的校验和,将它添加到“索引”中, 而 `git reset HEAD` 将它改写回原先的,从而取消缓存操作。
如果你想直接执行 `git unstage`,你可以在 Git 中配置个别名。 执行 `git config --global alias.unstage "reset HEAD"` 即可。 一旦执行完它,你就可以直接用 `git unstage [file]`作为代替了。
如果你忘了取消缓存的命令,Git 的常规 `git status` 输出的提示会很有帮助。 例如,在你有已缓存的文件时,如果你不带 `-s` 执行 `git status`,它将告诉你怎样取消缓存:
~~~
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# modified: README
# modified: hello.rb
#
~~~
> **简而言之**,执行 `git reset HEAD` 以取消之前 `git add` 添加,但不希望包含在下一提交快照中的缓存。