soft 与 mixed 的区别
先上结论:
- soft 只会回退本地版本库
- mixed 会回退本地版本库和暂存区
- 都不会回退工作区
我个人惯用 IDEA,所以使用 IDEA 的可视化 Git 操作做个简单的实践:
1、 创建一个测试项目,提交第一份 txt 文件:

2、修改 txt 文件内容,并进行第二次提交:

3、尝试使用 reset –mixed 命令进行回退:

4、查看 reset –mixed 的结果:

5、恢复到 reset 之前的状态:

6、尝试使用 reset –soft 命令进行回退:

7、查看 reset –soft 的结果:

结果是莫名的一样,请留意最初的结论——soft 和 mixed 都会回退本地版本库,但 soft 不会回退暂存区。
为了直观的表现暂存区,我们继续往下实践。
8、在第二次提交时,额外再新增一个文件:

9、再次尝试使用 reset –mixed 命令进行回退:

10、查看 reset –mixed 的结果:

留意 Unversioned Files 中的 text-file-2.txt,此时为红色,意味着将不会被提交。
11、恢复到 reset 之前的状态:

12、再次尝试使用 reset –soft 命令进行回退:

13、查看 reset –soft 的结果:

此时 text-file-2.txt 依然在暂存区中。
HEAD^ 与 HEAD~ 的区别
同理,先上结论:
- HEAD^ 偏转到第 1 条分支并回退 1 步
- HEAD~ 回退 1 步
- HEAD^[number] 偏转到第 [number] 条分支,并回退 1 步
- HEAD~[number] 回退 [number] 步
我们同样用实践来感受两个命令的区别。在上文实践的基础上(master 中包含两次提交),将 master 分出 2 个 branch,我这里命名为 branch-1 和 branch-2。
我切换到 branch-1 做了 2 次提交:
- 新增文件 branch-1-file.txt
- 修改文件 branch-1-file.txt 的内容
然后切换到 branch-2 做 2 次提交:
- 新增文件 branch-2-file.txt
- 修改文件 branch-2-file.txt 的内容
如下图:


然后,我们要将 2 个分支 merge 到 master 分支中。如下图:

可以看到,此时 master 已经包含了 branch-1 新增的文件和 branch-2 新增的文件。这里我们人为构造了多分支的交点。我们知道 reset HEAD~ 命令可以回退 1 次提交,那么在处于多分支的交点的情况下,如何控制自己回退 branch-2 的上一次提交,而不是 branch-1 的上一次提交呢?
我们在这里分别尝试 HEAD~ 命令和 HEAD^ 命令,这里使用 IDEA 的 Validate 功能,可以不用真的执行而看到当前命令会导致的结果。


这里可以发现,HEAD~ 和 HEAD^ 在回退一步提交时,功能是一样的。上去看下结论,再尝试 HEAD~2 和 HEAD^2:


可以看到,在 [number] 设置为 2 时出现了区别。
HEAD~2 回退到了 branch-1 第一次提交的位置,而 HEAD^2 回退到了 branch-2 第二次提交的位置。
这里 HEAD^2 表示,偏转分支到第 2 条,并回退 1 步。
这里 ~ 和 ^ 可以混合使用,如果要回到 branch-2 第一次提交的位置,那么我们可以使用 HEAD^2~,如图:
