git reset hard/soft/mixed区别

https://blog.csdn.net/carolzhang8406/article/details/49761927

根据–soft –mixed –hard,会对working tree和index和HEAD进行重置:
     git reset --mixed:此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本, 只保留源码,回退commit和index信息
    git reset --soft:回退到某个版本, 只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可

    git reset  --hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容,此命令 慎用!

 

git reset 命令是git中最常用的命令,但也是最危险,最容易被误用的命令。

一、master 分支

 

    我们知道git在初始化时,会为我们默认创建一个master分支,那这个master到底是什么呢?其实它在.git目录下对应了一个引用文件-----.git/refs/heads/master文件,而该文件的内容便是该分支中最新的一次提交的ID:

1
2
3
4
5
6
7
8
9
10
11
12
 cat  .git /refs/heads/master
22f8aae534916e1174711f138573acfbb47e489c
 
$ git  cat - file  -t 22f8aae
commit
 
$ git log --oneline
22f8aae git ignore  file  added.
4e79a0b Rename third to third.txt
46ae7e3 remove branch_first.txt  file  from master branch
55d1e70 branch first  file
545a382 Merge commit  '35bbd32'

   当我们用以上查看master文件内容时,发现它果然记录了最新一次的提交。了解了这个前提,那我们来分析下git reset到底做了什么?

二、reset命令

    以上面的例子为基础我们来探讨reset命令的魔力,首先我们来执行一个reset命令,reset到上一次提交

1
2
3
4
5
6
7
8
9
$ git reset --hard HEAD^
HEAD is now at 4e79a0b Rename third to third.txt
 
Quadrangle@QUADRANGLE-PC  /d/GitRepo/GitOne  (master)
$ git log --oneline
4e79a0b Rename third to third.txt
46ae7e3 remove branch_first.txt  file  from master branch
55d1e70 branch first  file
545a382 Merge commit  '35bbd32'

   HEAD^的意思就是最新一次提交的父提交,reset后,我们看一下提交日志,发现最新一次提交没了。到底git做了什么呢?我们还能找回最新的一次提交吗?

    回答上面两个问题,就用到上面就到的master引用文件了,这是我们再看一下这个文件的内容有什么变化?

1
2
 cat  .git /refs/heads/master
4e79a0ba92f1ae63dc661e29343fa0c369ca480d

   发现了吧,里面记录了reset后的最后一次提交。这时或许我们有所觉察了。先不急着下结论,我们看怎么回到最新的提交呢?其实reset后,git没有删除最新提交的相关信息,包括目录树,因此只要我们记住提交ID,便可以重新reset回来:

1
2
3
4
5
6
7
8
9
$ git reset --hard 22f8aae
HEAD is now at 22f8aae git ignore  file  added.
 
$ git log --oneline
22f8aae git ignore  file  added.
4e79a0b Rename third to third.txt
46ae7e3 remove branch_first.txt  file  from master branch
55d1e70 branch first  file
545a382 Merge commit  '35bbd32'

   这样查看log,发现最新提交又回来了。但是如果我们忘了最新提交ID 怎么办呢?好办,reflog命令可以最总引用变更的记录:

1
2
3
4
5
6
Quadrangle@QUADRANGLE-PC  /d/GitRepo/GitOne  (master)
$ git reflog
22f8aae HEAD@{0}: reset: moving to 22f8aae
4e79a0b HEAD@{1}: reset: moving to HEAD^
22f8aae HEAD@{2}: reset: moving to 22f8aae
4e79a0b HEAD@{3}: reset: moving to HEAD^

   我们可以找到前面任意操作的记录,并且可以reset到任意提交。

三、揭秘

    之前我们看到了reset后master文件的内容发生了变化,其实这就是reset命令的本质,但结合不同的参数,会有额外的工作:如--hard --soft --mixed等,他们决定了是否重置暂存区或工作区。

我们来看下面图片

113832_xvvr_258230.png

其实reset命令有两种用法:

  1. git reset [-q] [commit] [--] <paths>

  2. git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]

第一种用法是不会重置引用的,即不会修改master文件。只是用某一次提交的文件提交暂存区的文件

第二种用法不使用<paths> 则会重置引用,并且参数不同决定是否覆盖暂存区和工作区:

  • --hard参数会执行途中1,2,3 全部动作,即暂存区,工作区全部用指定提交版本的目录树替换掉

  • --soft 参数只执行1, 不进行暂存区和工作区的覆盖

  • --mixed或不使用参数,执行1,2覆盖暂存区,但不覆盖工作区

 

这样一来相信对reset的理解会用更深刻的理解了吧。

posted on   四海骄阳  阅读(1953)  评论(0编辑  收藏  举报

编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
· 全程使用 AI 从 0 到 1 写了个小工具
历史上的今天:
2019-10-30 Spring为什么@Autowired注入的是接口
2019-10-30 @Autowired用法详解

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示

喜欢请打赏

扫描二维码打赏

了解更多