【微知】git reset --soft --hard以及不加的区别?
背景
在 Git 里,git reset
是用来将当前的 HEAD 复位到指定状态的命令。--soft
、--hard
是它的两个常用选项,本文简单介绍他们的区别,以及不添加选项时的默认情况。
在 Git 里,HEAD 是一个重要的引用,它指向当前所在的分支或者提交。# 查看当前HEAD指向的分支 git symbolic-ref HEAD。 类似C语言的指针,只是HEAD指向的是某个提交,或者git里面的obj。或者blob。
结论(逐级增加)
–soft:仅移动 HEAD,暂存区和工作区不变。(都不影响)
默认(–mixed):移动 HEAD,重置暂存区,工作区不变。(影响暂存区)
–hard:移动 HEAD,同时重置暂存区和工作区。(都影响)
可以用HEAD不-1来理解。
细节
git reset --soft
使用 git reset --soft
时,HEAD 会被移动到指定的提交,不过工作区和暂存区的内容不会改变。可以重新提交之前的修改。
举例:
git reset --soft HEAD~1 #HEAD 回退一个提交,但是暂存区和工作区的内容不变,可重新提交之前的修改。
其他:git reset --soft HEAD 没有任何修改,HEAD指针没有-1所以HEAD不变,soft不影响暂存区,也不影响工作区
不添加选项的默认情况
如果在使用 git reset
时不添加选项,默认是 --mixed
模式。--mixed
会让 HEAD 移动到指定的提交,暂存区的内容会被重置为指定提交时的状态,工作区的内容不变。可以重新选择要提交的修改。
举例:
git reset HEAD~1 #HEAD 回退一个提交,暂存区的内容会被重置为前一个提交时的状态,但是工作区的内容不变,可以重新选择要提交的修改。
其他:git reset HEAD 这里HEAD指针没有-1所以HEAD不变,不影响暂存区,也不影响工作区。相当于git clean -xdf
git reset --hard
git reset --hard
会让 HEAD 移动到指定的提交,同时工作区和暂存区的内容也会被重置
为指定提交时的状态。尚未提交的修改都会丢失。
举例:
git reset --hard HEAD~1 #让 HEAD 回退一个提交,并且工作区和暂存区的内容会被重置为前一个提交时的状态,所有未提交的修改都会丢失。
其他:git reset --hard HEAD 这里HEAD指针没有-1所以HEAD不变,hard影响暂存区,也影响工作区。对于工作区的影响和git clean -xdf不同在于工作区回退只影响git管理的文件不会影响原来git没有的文件
实验
mixed
hard
总结
-
--soft
:仅移动 HEAD,暂存区(git add的东西还在)和工作区不变。 -
默认(
--mixed
):移动 HEAD,重置暂存区(git add的东西不在),工作区不变。所以常用这个git reset HEAD~1 来将暂存区的回退 -
--hard
:移动 HEAD,同时重置暂存区和工作区。
在使用 git reset
尤其是 --hard
时要格外谨慎,因为它可能会导致未提交的修改丢失。
为了便于理解,reset的本质是修改3个层次,用HEAD不变来看:
- 层次1:什么都不影响,git reset --soft HEAD 这里HEAD的值不变;
- 层次2:清空暂存区,回退到工作区, git reset HEAD 会把暂存区的放到工作区,HEAD的值不变;
- 层次3:影响暂存区,工作区; git reset --hard HEAD 这里会把暂存区的清空,工作区回退(但是注意工作区回退只影响git管理的文件不会影响原来git没有的文件),HEAD的值不变;