Git Reset 三种模式

有时候,我们用Git的时候有可能commit提交代码后,发现这一次commmit的内容是有错误的,
那么有两种处理方法:

  1. 修改错误内容,再次commit一次
  2. 使用git reset 命令撤销这一次错误的commit,
    第一种方法比较直接,但会多一次commit记录
    而我个人更倾向于第二种方法 错误的commit没必要保留下来
    那么今天来说一下git reset。它用一句话概括
git reset -Reset current HEAD to the specified state

意思就是可以让HEAD这个指针指向其他的地方 例如我们有一次commit不是很满意
需要回到上一次的Commit里面 那么这个时候就需要通过reset,把HEAD指针指向上一次的commit的点

它有三种模式 soft,mixed,hard,具体的使用方法下面这张图 展示的很全面
在这里插入图片描述

这三个模式理解了,对于使用这个命令很有帮助。在理解这三个模式之前 需要略微知道git的基本流程。正如上图 Git会有三个区域:

  • Working Tree 当前的工作区域
  • Index/Stage 暂存区域 和 git stash命令暂存的地方不一样。使用git add xx,就可以将xx添加到Stage里面
  • Repository 提交的历史 即使用git commit提交后的结果
    在这里插入图片描述
    以下简单的叙述一下把文件存入Repository流程:
  1. 刚开始 working tree、index与repository(HEAD)里面的内容都是一致的
    在这里插入图片描述
  2. 当git管理的文件夹里面的内容出现改变后,此时working tree的内容就会跟index及repository(HEAD)的不一致。而Git知道是哪些文件被改动过,直接将文件状态设置为modified(Unstaged files)。
    在这里插入图片描述
  3. 当我们执行git add后,会将这些改变的文件内容加入index中(Staged files),所以此时working tree跟index的内容是一致的,但他们与repository(HEAD)内容不一致
    在这里插入图片描述
  4. 接着执行git commit后 将Git索引中所有改变的文件内容提交至Repository中 建立出新的commit节点(HEAD)后,working tree 、index、与repository(HEAD)区域的内容又会保持一致
    在这里插入图片描述

实战演示

reset --hard:重置stage区和工作目录

reset --hard 会在重置HEAD和branch的同时,重置stage区和工作目录里的内容。当你在reset后面加了–hard参数时,你的stage区和工作目录里的内容会被完全重置为和HEAD的新位置相同的内容。换句话说,就是你的没有commit 的修改会被全部擦掉。
例如你在上次commit 之后又对文件做了一些改动:
把修改后的game.tsx文件add到stage区,修改后的shopping list.tsx保存在工作目录

git status

在这里插入图片描述

然后,你执行了reset并附上了 --hard参数:
git reset --hard HEAD^

你的HEAD和当前branch切到上一条commit的同时,你工作目录里的新改动和已经add到stage区的新改动也一起全部消失了
git status
在这里插入图片描述
可以看到,在reset --hard后,所有的改动都被擦掉了

reset --soft:保留工作目录,并把重置HEAD所带来的新的差异放进暂存区。

reset --soft 会在重置HEAD和branch时,保留工作目录和暂存区中的内容,并把重置HEAD所带来的新的差异放进暂存区

什么是 重置HEAD所带来的新的差异?就是这里
在这里插入图片描述
由于HEAD从4移动到3,而且在reset过程中 工作目录和暂存区的内容没有被清理掉,

所以4中的改动在reset后就也成了工作目录新增的 [工作目录和HEAD的差异]。这就是上面一段中所说的 [重置HEAD所带来的差异]。

此模式下会保留working tree 工作目录的内容 不会改变到目前所有的git管理的文件夹得内容;也会保留

Index 暂存区的内容 让index 暂存区与working tree 工作目录内容是一致的。就只有repository中的内容的变更需要与reset目标节点一致,

因此原始节点与reset节点之间的差异变更集合会存在于index暂存区中(Staged files),所以我们可以直接执行git commit 将index暂存区中的内容提交至repository 中。

当我们想合并 当前节点和reset目标节点之间不具有太大意义的commit记录 (可能是阶段性地频繁提交)时,可以考虑使用Soft Reset来让commit 演进线图较为清晰点。
在这里插入图片描述

所以在同样的情况下,还是老样子:把修改后的game.txt文件add到stage区,修改后shopping list 保留在工作目录

git status
在这里插入图片描述

假设此时当前commit的改动内容是新增了 laughters.txt文件:

git show --stat
在这里插入图片描述
如果这时你执行:
git reset --soft HEAD^
那么除了HEAD和它指向的branch1被移动到HEAD^之外,原先HEAD处 commit的改动(也就是那个laughters.txt文件)也会被放进暂存区

git status
在这里插入图片描述
这就是–soft和–hard的区别:–heard 会清空工作目录和暂存区的改动 而–soft 则会保留工作目录的内容 并把因为保留工作目录内容所带来的新的文件差异放进暂存区。

reset 不加参数(mixed):保留工作目录,并清空暂存区

reset 如果不加参数 那么默认使用–mixed 参数 。它的行为是:保留工作目录 并且清空暂存区. 也就是说 工作目录的修改、暂存区的内容以及由reset所导致的新的文件的差异,都会被放进工作目录。

简而言之 ,就是把所有差异都混合(mixed)放在工作目录中。

还以同样的情况为例:
git status
在这里插入图片描述

修改了的games.txt 和shopping list.txt 并把games.txt 放进了暂存区

git show --stat

在这里插入图片描述

最新的commit中新增了laughters.txt文件
这时如果你执行了无参数的reset 或者带 --mixed参数

git reset HEAD^ git reset --mixed HEAD^

工作目录的内容和–soft,一样会被保留,但和–soft的区别在于,它会把暂存区清空,并把原节点和reset节点差异的文件放在工作目录。
总而言之就是 工作目录的修改、暂存区的内容以及由reset所导致的新的文件差异,都会被放进工作目录

git status
在这里插入图片描述

总结

reset的本质:移动HEAD以及他指向的branch

实质上,reset这个指令虽然可以用来撤销commit 但它的实质行为并不是撤销,而是移动HEAD,并且[捎带]上HEAD所指向的
branch(如果有的话)。也就是说,reset 这个指令的行为其实和它的字面意思 “reset” (重置)十分相符:
它是用来重置HEAD 以及它指向的branch 的位置的。
而reset --hard HEAD^ 之所以起到撤销commit的效果 是因为它把HEAD和它指向的branch 一起移动到了当前commit的父commit上,
从而起到撤销的效果:
在这里插入图片描述

Git 的历史只能往回看 不能向未来看 所以把HEAD 和branch 往回移动,就能起到撤回commit的效果
所以同理 reset–hard 不仅可以撤销提交 还可以用来把HEAD 和branch 移动到其他的任何地方
git reset --hard branch2
在这里插入图片描述

reset三种模式区别 和使用场景
区别

1.–hard:重置位置的同时,直接将working Tree 工作目录、 index暂存区及repository都重置成目标Reset节点的内容,所以效果看起来等同于清空暂存区和工作区
2.–soft: 重置位置的同时 保留working Tree工作目录和index暂存区的内容,只让repository中的内容和reset目标节点保持一致,因此原节点和reset节点之间的
[差异变更集]会放入index暂存区中(Staged files)。所以效果看起来就是工作目录的内容不变,暂存区原有的内容也不变,
只是原节点和Reset节点之间的所有差异都会放到暂存区中
3. --mixed(默认):重置位置的同时 只保留Working Tree工作目录的内容,但会将Index暂存区和Repository中的内容更改和reset目标节点一致,因此原节点和Reset节点之间的
[差异变更集]会放入Working Tree 工作目录中。所以效果看起来就是原节点和Reset节点之间的所有差异都会放到工作目录中。

使用场景

1.–hard: (1) 要放弃目前本地的所有改变时,即去掉所有add 到暂存区的文件和工作区的文件,可以执行 git reset -hard HEAD 来强制恢复git 管理的文件夹的内容及状态。
(2)真的想抛弃目标节点后的所有commit(可能觉得目标节点到原节点之间的commit提交都是错的,之前所有的commit有问题)

  1. –soft: 原节点和reset 节点之间的[差异变更集] 会放入index 暂存区中(Staged files),所以假如我们之前工作目录没有改过任何文件 也没add到暂存区,
    那么使用reset --soft后,我们可以直接执行git commit 将index暂存区中的内容提交至repository中。为什么要这样呢?
    这样做的场景是:假如我们想合并当前节点与reset目标节点之间不具太大意义的commit记录(可能是阶段性的频繁提交,就是开发一个功能的时候,改或者增加一个文件的时候就commit,
    这样做导致一个完整的功能可能会好多个commit点,这时假如你需要把这些commit整合成一个commit的时候)时,可以考虑使用reset --soft 来让commit演进线图
    较为清晰 总而言之,可以使用–soft合并commit节点。

  2. –mixed(默认): (1)使用完reset --mixed后,我们可以直接执行git add 将这些改变的文件加入到index暂存区中,再执行git commit
    将index暂存区中的内容提交至repository中,这样一样可以达到合并commit节点的效果(与上面–soft 合并commit节点差不多,只是多了git add 添加到暂存区的操作);
    (2)移除所有index暂存区中准备要提交的文件(Staged files) 我们可以执行git reset HEAD来Unstage所有已列入Index暂存区的带提交的文件
    (有时候发现Add错文件到暂存区,就可以使用命令)
    (3) commit 提交某些错误代码 或者没有必要的文件也被commit上去,不想再修改错误再commit(因为会留下一个错误commit点),可以回退到正确的commit点上,
    然后所有原节点和reset节点之间差异会返回工作目录,假如有个没必要的文件的话就可以直接删除了,再commit上去就OK了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: Git Reset三种模式,分别是soft、mixed和hard。\[2\]这三种模式的具体使用方法如下: 1. soft模式:使用`git reset --soft`命令可以将HEAD指针指向上一次的commit,同时保留之前的修改内容在暂存区中。这样可以撤销上一次的commit,但是保留修改内容以便重新提交。 2. mixed模式(默认模式):使用`git reset --mixed`命令可以将HEAD指针指向上一次的commit,并且将之前的修改内容放回工作目录中。这样可以撤销上一次的commit,并且取消之前的修改内容。 3. hard模式:使用`git reset --hard`命令可以将HEAD指针指向上一次的commit,并且将之前的修改内容完全删除。这样可以彻底撤销上一次的commit,并且丢弃之前的修改内容。请注意,使用hard模式会永久删除修改内容,请谨慎使用。 所以,git reset命令可以根据不同的模式来回退到之前的某个版本或撤销之前的commit。 #### 引用[.reference_title] - *1* [Git Reset 三种模式](https://blog.csdn.net/QGhurt/article/details/122651361)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [GitReset三种模式](https://blog.csdn.net/weixin_42028608/article/details/118595288)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值