一个实验搞懂IDEA中git reset的多种模式

2,926 阅读5分钟

git 如何撤回已push的代码 - 掘金 (juejin.cn)

在之前的这篇文章里,我提到了reset方法的几种模式,但是仅仅是简单的介绍,没有深入的了解,于是就找了个时间把这个坑填了。

image.png

我们一般使用reset 命令想要快速的将代码恢复到我们想要的一个commit记录的位置。

但是在IDEA中使用reset命令时会遇到以上四个模式选择,虽然大多数情况下都是无脑选择hard然后push -force强推上去,但是了解其他三个模式的使用场景也是很有必要的。

image.png ## IDEA对四种reset模式的定义 直接看IDEA中给出的解释:
  • Soft:文件不会更改,改动将暂存以供提交。

  • Mixed:文件不会更改,改动将不会暂存。

  • Hard:文件恢复到所选的commit的状态,注意:任何本地变更都会丢失。

  • keep:文件恢复到所选的commit的状态,但是本地的变更会完整的保存下来。

如果单纯的从字面理解,files、differences、changes 分别对应的含义都不是很明确。 对于git了解不深的同学就会很苦恼,不知道他们的区别到底是什么。接下来,我会从几个对比实验帮助各位深入的理解这些模式的具体作用。

工作目录、暂存区

  • 工作区是指项目在本地文件系统中的目录,工作区中创建或修改文件时,Git会跟踪这些变化并将其显示为未暂存的修改。
  • 暂存区是Git用于暂存修改的缓冲区域,我们需要将工作区的修改添加到暂存区,然后才能将其提交到仓库中。

在使用IDEA的git时我们可能对git的暂存区感知没有那么强。

工程目录下都是工作区,但是不一定是暂存区,暂存区是工作区的子集,工作区包含暂存区。git bash中需要使用git add 才能将工作区的文件转到暂存区中。

在IDEA中我们创建文件时,会有一个提示,是否将文件添加到git其实就是问你这个文件放不放进暂存区的意思。

所以,选择cancel,就会得到一个在工作目录中,但是不在暂存区的文件。 image.png

选择add,就会得到一个既在工作目录中又在暂存区的文件。 image.png

在不在暂存区中的文件于IDEA中是明显区别对待的,一个红色一个绿色。 image.png

在commit时这两者也是不一样的。 image.png

reset对比实验

1. 实验准备

- 首先提交一段测试代码:

image.png

- 然后再在本地工作区和暂存区分别做改动。就用上面的那两个文件了

image.png

2. 实验对比

1. reset --soft结果

reset到最后一个同步commit

image.png

结果如下:

image.png

可以看到工作区和暂存区的文件都没有变动,而且,test:git reset测试的改动也没有消失,而是保留到了暂存区。

  • 结论:reset --soft 会在重置到指定commit时,保留工作区和暂存区中的内容,并把reset后本地分支与remote分支的差异添加(add)到暂存区以供提交(commit)。

需要注意的一点是:图片左下方master显示有待拉取的更新,是因为我们本地比远程少了一个commit,所以才会如此,这是reset到过去的commit都会出现的。只需要强推,实现本地和远程的同步即可。这也是为什么reset命令比较危险的原因。

image.png

2. reset --mixed结果

reset选择mixed模式,直接看结果 image.png

可以看到工作区文件没有变动,但是暂存区文件放回了工作区。同样的,test:git reset测试的改动也没有消失,而是保留到了暂存区。

个人认为这里暂存区文件放回工作区是因为删除了暂存区中的文件,但是没有删除文件,文件就保留在了工作区。

  • 结论:reset --mixed时工作区文件和 reset --soft时一样都会被保留,同样把reset后本地分支与remote分支的差异添加(add)到暂存区以供提交(commit)。但和 --soft 的区别在于,它会把原来暂存区的文件返回工作区。

3.reset --hard结果

reset选择mixed模式,直接看结果 image.png

可以看到工作区文件没有变动,但是暂存区文件消失了。而且,test:git reset测试的改动直接消失了。

  • 结论:reset --hard时工作区文件保留,暂存区文件直接消失,而且reset后本地分支与remote分支的差异也直接消失。

4.reset --keep结果

reset选择keep模式,直接看结果 image.png 可以看到工作区文件没有变动,但是暂存区文件放回了工作区,test:git reset测试的改动直接消失了

个人认为这里暂存区文件放回工作区是因为删除了暂存区中的文件,但是没有删除文件,文件就保留在了工作区。

3.实验结论

在IDEA中不同模式的reset主要在三个方面体现不同。

  1. 工作区文件(特指不在暂存区中的)
  2. 暂存区文件
  3. reset后本地分支与remote分支的不同

最后总结表格如下,可以在不同场景下选择不同的模式进行reset。

模式工作区文件暂存区文件reset后本地分支与remote分支的不同
soft无变化无变化放入暂存区
mixed无变化放回工作区放入暂存区
hard无变化删除删除
keep无变化放回工作区删除

注意:尽管从描述上hard模式中,工作区文件应该直接删除,但是实验结果摆在这里,先以实验结果为准。