git reset --hard --soft --mixed的区别?

介绍

网上看了好多,都是从原理入手,介绍HEAD、index、Working Copy、Flow等一堆名词往上怼,看得我云里雾里的,不如动手实践一下,看的更加清楚明了。

一、准备工作(初始状态)

1.创建版本库,进行了两次提交,每次提交两个文件。
git reset --hard --soft --mixed的区别?
2. 修改1.1,2.1并添加到暂存区,修改1.2,2.1保留在工作区,添加3.1,如下图:
git reset --hard --soft --mixed的区别?

参数一:–hard

  • 执行 git reset --hard HEAD^,然后看现象:
    git reset --hard --soft --mixed的区别?
    git reset --hard --soft --mixed的区别?
    你会发现工作区和暂存区所有的修改都丢失了,只剩下可怜的3.1还在,应为该文件还未被git追踪到。所以,添加–hard参数一定要慎重,否则,将会丢失大量修改。

参数二:–mixed

  • 先回到初始状态,然后执行 git reset HEAD^(–mixed参数为默认值,可以不加),然后看现象:
    git reset --hard --soft --mixed的区别?
    git reset --hard --soft --mixed的区别?
    你会欣喜的发现所有的文件都在,只是之前加入到暂存区的文件(1.1)也回退到工作区了。2.1由于第一次提交时没有追踪,所以无法将2.1退回到工作区,直接变为未追踪。

参数三:–soft

git reset --hard --soft --mixed的区别?
git reset --hard --soft --mixed的区别?
看到这个结果是不是已经蒙了,别急,咱一个文件一个文件分析:
1.1:版本一中有追踪,回退前在暂存区,回退后还在暂存区
1.2:版本一中有追踪,回退前在工作区,回退后还在工作区
2.1:版本一中未追踪,回退前在暂存区,回退后还在暂存区,只是变成新文件了。
2.2:版本一中未追踪,版本二中有追踪,回退前在工作区,回退后暂存和工作区都有。(小朋友,你是否有好多问号???)
3.1:版本一中未追踪,回退前未追踪,回退后人就未追踪。

2.2这个文件没看懂,没关系,再做个实验,回退到初始状态,并取消2.2的修改:
git reset --hard --soft --mixed的区别?
再次执行,git reset --soft HEAD^,看现象:

git reset --hard --soft --mixed的区别?
回退后,2.2这个文件的工作区修改已经没有了,只剩下暂存区新增的记录了,大概就明白其中的逻辑了。

总结

  • –hard:慎用该选项,会丢弃工作区和暂存区的修改,对于未追踪的文件没有影响。
  • –mixed:默认参数,可选择不写,保留当前所有代码,包括工作区和暂存区,并将这些代码一并放入工作区,只是HEAD指向发生了变化,指向命令指定的版本。
  • –soft:略复杂
    1. 工作区:修将会原样保留,
    2. 暂存区:如果回退之后的版本追踪了该文件,那么,将原模原样保留在暂存区,如果回退之后的版本未追踪该文件,该文件仍然保留在暂存区,只是变为新增文件,内容为保留最后修改的结果。
    3. 未被追踪的文件不受影响。