从指针行为理解Git中的reset操作

从指针行为理解Git中的reset操作

节点状态

先确立一个状态概念,也就是工作区暂存区工作树上的节点N看作一组状态

当commit之后,状态得以固定:

  • 工作区内容固定为为commit时的内容,如第二次提交时,工作区内容固定为

    bash 复制代码
    第二次提交
  • 暂存区被"清空"(简单理解为被提交到节点上去了,自然就不需要暂存了。)

  • HEAD指向被创建的节点

至此,HEAD以及HEAD之前的节点的状态都可以被确定,之后对工作区和暂存区的更改,我们可以将其看作是对一个未被创建的虚拟节点------待存节点状态的操作

假设第N个(N<=3)固定状态对应的内容:

  • 工作区:第N次提交
  • 暂存区:空
  • 节点:第N次提交

此时,我们对代存节点的状态(工作区和暂存区)进行修改(在1.txt中输入文字):

  1. 修改工作区内容: 第4次提交
  2. 提交到暂存区:git add .,此时暂存区内容也为第4次提交
  3. 再次修改工作区内容: 第5次提交

在git插件中我们可以看到如下情况:

于是现在待存节点的状态可以看作:

将这个状态当作我们实验的初始状态,然后我们就可以来看看使用三种不同的reset方法时到底发生了什么

--hard

bash 复制代码
git reset --hard C2
//c725740f0a4... 第二次提交id,简化为C2

此时可以发现:

  • 工作区:第二次提交 (无显示状态)
  • 暂存区:没有内容
  • HEAD指向C2

而这个恰好是C2的状态!

先不着急得出结论,不妨把剩下的运行结果全部看完

--soft

回到我们的初始状态,然后

bash 复制代码
git reset --soft C2

神奇的事情发生了!

工作区与暂存区的内容不仅没有更改,甚至连状态都没有改变,与初始状态一模一样!

  • 工作区:第五次提交 (M,已修改)
  • 暂存区:第四次提交 (M,已修改)
  • HEAD指向C2

这样看来,虽然节点对应的状态是唯一 的,但是工作区、暂存区、HEAD的变化并不是统一

我们可以为其分别设置三个虚拟指针,来探究到底发生了什么

  • 工作区:HEAD_Work
  • 暂存区:HEAD_Index
  • 节点:自然是HEAD

看到这里或许大家内心都已经有了猜想,我们不妨再来看看最后一个操作验证一下

--mixed

可以确定的是,reset后HEAD是必然改变的(有点像废话。。),有区别的是:

  • 工作区:HEAD_Work
  • 暂存区:HEAD_Index

这两个指针是如何变化的?

从上述内容的表现来看,--hard和--soft分别代表两个极端,一个是全都跟着HEAD变,一个是都不变,那么很容易猜想到--mixed就是改变其中一个,那么这个猜想是否正确?改变的又是哪一个呢?为什么

猜想验证

回到初始状态

bash 复制代码
git reset --mixed C2

可以看到:

  • 工作区:第五次提交 (M,已修改)
  • 暂存区:空
  • HEAD指向C2

猜想得到验证!

指针变化

  • 工作区:HEAD_Work不变
  • 暂存区:HEAD_Index跟着HEAD变
  • 节点:指向C2

为什么是改变暂存区的指针而不是工作区的指针?(猜想)

想象这样一个场景:

你辛辛苦苦写好了一段代码放在工作区,突然发现当前的版本不兼容,而你知道你的代码经过微调后,C2是兼容的,于是你想要回退到C2,但是代码已经写好了,如果用--hard,工作区指针也指向C2,你写的代码将被清除,白忙活一场;如果用--soft,暂存区的指针不改变,虽然不影响后续,但其实没啥必要,恰好,--mixed就实现了这个功能:回退版本,不改变你的代码,清空暂存区,perfect!

这也是为什么--mixed成为了git reset的默认方式吧

当然如果不嫌麻烦,假设我们将--mixed设置为工作区的指针跟着HEAD跑,暂存区的不变,那么我们必然要多走一步,也就是将暂存区的代码git restore --stage 1.txt回退到工作区,再进行操作,想想都觉得麻烦~

总结

模式 git reset --soft git reset --mixed (默认) git reset --hard
HEAD 指针 移动 移动 移动
暂存区 (Index) 不动 重置到 HEAD 重置到 HEAD
工作区 (Working Dir) 不动 不动 重置到 HEAD

以上只是我这个刚开始学习计算机知识小白的一些拙见,作为学习记录,或许会有人在刚学git的时候有些类似的疑惑,欢迎大家批评!

相关推荐
无限进步_3 小时前
面试题 02.02. 返回倒数第 k 个节点 - 题解与详细分析
c语言·开发语言·数据结构·git·链表·github·visual studio
2401_859049083 小时前
git submodule update --init --recursive无法拉取解决
前端·chrome·git
是店小二呀7 小时前
Git 深度学习笔记:从初始化到核心操作机制解析
笔记·git
xlq223228 小时前
11.git_gbd
git
CCC:CarCrazeCurator8 小时前
IDE 与编程语言区分介绍
git·github
Q741_1478 小时前
Git 基础操作速查手册 场景模拟
git·学习·版本控制·总结
玉梅小洋14 小时前
Git 使用技巧——查看 Commit 修改文件的概要
git·github
Howie Zphile1 天前
Git 拉 NocoBase 2.0 beta(next 分支),并“每天自动更新 + 自动编译 + 自动重启”
大数据·git·elasticsearch
吕司1 天前
Git分支管理
git
黑屋里的马1 天前
GitExtension下载、安装
git·gitextension