一文浅析git中三种reset命令的使用与区别

 更新时间:2026年05月19日 08:41:55   作者:金銀銅鐵  
相信不少朋友在使用 git时,都对以下三种git reset 命令的区别产生过疑惑,这篇文章小编就来和大家详细介绍一下git中这三种reset命令的具体使用与区别吧

背景

相信不少朋友在使用 git时,都对以下三种git reset 命令的区别产生过疑惑。

git reset --soft <commit>
git reset --mixed <commit> (和 git reset <commit> 效果相同)
git reset --hard <commit>

本文会探讨它们的区别。

要点

如果将 HEAD/暂存区/工作目录 都看作树 🌲(即,文件的集合),在不同的git reset 命令中,对应的树是否会被更新可以这样总结

HEAD\text{HEAD}HEAD 🌲 是否会被更新暂存区(Index\text{Index}Index) 🌲 是否会被更新工作目录 🌲 是否会被更新
git reset --soft <commit>否❌否❌
git reset --mixed <commit> 或
git reset <commit>
是✅是✅否❌
git reset --hard <commit>是✅是✅是✅

这个链接中,可以看到关git reset 命令的介绍,其中开头的内容如下 (我在图中用红色框标出了本文关心的内容)

据此可知以下三个命令都会调整HEAD,但是这三个命令对 暂存区工作目录 的处理不同。

  • git reset --soft <commit>
  • git reset --mixed <commit> (和 git reset <commit> 效果相同)
  • git reset --hard <commit>

参考 7.7 Git 工具 - 重置揭密 一文的描述,我们可以将以下三者看成三棵树 🌲(这里的树 🌲 是指文件的集合,而不是指数据结构中的树)

  • HEAD (可以将它简单理解为当前分支的最近一次commit 的指针或者引用)🌲
  • 暂存区(即,Index)🌲
  • 工作目录 🌲

准备工作

代码

我们可以用代码验证不同选项的git reset 命令的效果。请将以下代码保存为main.sh

## Prepare a temp dir for our test
TEST_DIR=temp_git_test_dir
if [[ -d "${TEST_DIR}" ]];
then
    rm -rf "${TEST_DIR}"
fi

mkdir "${TEST_DIR}" 
cd "${TEST_DIR}" 

git init

function append() {
    echo "$1" >> f.txt
}

function add_and_commit() {
    git add f.txt
    git commit -m "$1"
}

## Prepare for the 1st commit 
append "1st line"
add_and_commit "1st commit" 

## Prepare for the 2nd commit
append "2nd line"
add_and_commit "2nd commit"

## Prepare for the 3rd commit
append "3rd line"
add_and_commit "3rd commit"

## Prepare for the 4th commit
append "4th line"
add_and_commit "4th commit"

main.sh

  • 创建一个名为 temp_git_test_dir 的临时目录
  • git 管理这个临时目录的内容
  • 创建4commit

运行结果

通过执行下方的命令就可以运行main.sh

bash main.sh

运行完 main.sh 之后,当前目录中会多出一个 temp_git_test_dir 目录。在当前目录执行 tree temp_git_test_dir 命令后,应该可以看到如下的内容

temp_git_test_dir
└── f.txt

1 directory, 1 file

通过执行 cd temp_git_test_dir 命令就可以切换到 temp_git_test_dir 目录。不难验证,现在 HEAD 的位置如下图所示  (下图是借助 Visual Studio Code 而生成的)

我们执行 git status 命令,可以得到如下的结果 

由此可以知道以下三棵树 🌲 当前的内容是一样的 

  • 工作目录 🌲
  • 暂存区(即,Index)🌲
  • HEAD 🌲

在此基础上,我们可以执行不同选项的git reset 命令 并比较它们的运行结果(HEAD~2 表示当前HEAD 的上一个commit 的上一个 commit

  • git reset --soft HEAD~2
  • git reset --mixed HEAD~2
  • git reset --hard HEAD~2

使用--soft选项的git reset命令

我们把HEAD 视为一个指针或者引用,那么 git reset --soft <commit> 命令的作用就是 

HEAD 指向 <commit> 所对应的位置

在运行 main.sh 之后,我们执行以下命令

git reset --soft HEAD~2

执行该命令后,HEAD 会有对应的变化 

通过查看git status 命令的执行结果,可以知道 工作目录暂存区 的内容是一样的

小结

git reset --soft <commit> 会将 HEAD 指向 <commit> 所对应的 commit。但是 暂存区工作目录 的内容都不受影响。

哪棵树 🌲执行 git reset --soft <commit> 命令后
有变化吗?
会变成什么?
HEAD 🌲变为指向 <commit> 对应的commit
暂存区(即,Index)🌲没有-
工作目录 🌲没有-

使用--mixed选项的git reset命令

说明: git reset <commit>git reset --mixed <commit> 的作用相同。

我们把 HEAD 视为一个指针或者引用,那么 git reset --mixed <commit> 命令的作用是

  • HEAD 指向 <commit> 所对应的位置
  • 用更新后的HEAD 来更新 暂存区(暂存区的内容会和最新的HEAD 相同)

在运行 main.sh 之后,我们执行以下命令 

git reset --mixed HEAD~2

执行该命令后,HEAD 会有对应的变化 

通过查看git status 命令的执行结果,可以知道HEAD暂存区 的内容是一样的 (但是工作目录的内容和它们不同) 

小结

git reset --mixed <commit> 会将 HEAD 指向 <commit> 所对应的 commit,并让 暂存区 的内容与最新的 HEAD 相同。工作目录 的内容不受影响。

哪棵树 🌲执行 git reset --mixed <commit> 命令后
有变化吗?
会变成什么?
HEAD 🌲变为指向 <commit> 对应的commit
暂存区(即,Index)🌲内容会和最新的HEAD 相同
工作目录 🌲没有-

使用--hard选项的git reset命令

我们把HEAD 视为一个指针或者引用,那么 git reset --hard <commit> 命令的作用是

  • HEAD 指向 <commit> 所对应的位置
  • 用更新后的HEAD 来更新 暂存区(暂存区的内容会和最新的 HEAD 相同)
  • 用更新后的 HEAD 来更新 工作目录(工作目录中,所有已被追踪的文件,其内容会和最新的 HEAD 中的内容相同)

在运行 main.sh 之后,我们执行以下命令

git reset --hard HEAD~2

执行该命令后,HEAD 会有对应的变化 

通过查看 git status 命令的执行结果,可以知道以下三者的内容相同

  • HEAD
  • 暂存区
  • 工作目录

小结

git reset --hard <commit> 会将HEAD 指向 <commit> 所对应的 commit,并让 暂存区 的内容与最新的 HEAD 相同。工作目录 中已被追踪的文件,也会变得和最新的HEAD 相同。

哪棵树 🌲执行 git reset --hard <commit> 命令后
有变化吗?
会变成什么?
HEAD 🌲变为指向 <commit> 对应的commit
暂存区(即,Index)🌲内容会和最新的HEAD 相同
工作目录 🌲对所有已被追踪的文件而言,工作目录的内容和最新的 HEAD 相同

到此这篇关于一文浅析git中三种reset命令的使用与区别的文章就介绍到这了,更多相关git reset命令内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • git忽略CRLF警告详解

    git忽略CRLF警告详解

    Git的CRLF警告提示行尾符差异(Windows用CRLF,Unix用LF),通常不影响代码功能,但跨平台协作或脚本文件可能引发问题,推荐配置core.autocrlf或.gitattributes统一处理,个人项目可忽略
    2025-09-09
  • 详解cron表达式

    详解cron表达式

    Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义。接下来通过本文给大家详细介绍cron表达式内容,感兴趣的朋友一起看看吧
    2018-04-04
  • 常用的Git便捷操作合集

    常用的Git便捷操作合集

    虽然现在有很多图形化的 Git 工具,但是命令行依然 yyds。本文记录了工作中很有用的一些 Git 操作,感兴趣的小伙伴可以跟随小编一起了解一下
    2022-09-09
  • 使用git查看分支方式

    使用git查看分支方式

    这篇文章主要介绍了使用git查看分支方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Git代码冲突问题的解决详细指南

    Git代码冲突问题的解决详细指南

    在团队协作开发中,Git 是最常用的版本控制工具,但多人同时修改同一文件时,难免会遇到代码冲突,本文将系统讲解 Git 代码冲突的产生原因和解决方案,需要的可以参考下
    2025-04-04
  • Git下载与环境变量配置方法

    Git下载与环境变量配置方法

    前几天在写博客 手把手教你用Hexo + github 搭建自己博客的时候,经常需要用到一些git操作,截了好多图,于是就想干脆整理成一系列的git 教程,总结如下,需要的朋友可以参考下
    2017-10-10
  • Git回退(Revert)操作后无法重新合并的问题及解决

    Git回退(Revert)操作后无法重新合并的问题及解决

    这篇文章主要介绍了Git回退(Revert)操作后无法重新合并的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • idea中实用的git操作问题小结(撤回commit,撤回push、暂存区使用)

    idea中实用的git操作问题小结(撤回commit,撤回push、暂存区使用)

    我们在开发过程中经常遇到commit代码后,发现还有需要修改的地方又不想多次commit,此时如果不想敲git命令,可以利用idea实现commit撤回,下面给大家分享idea中实用的git操作问题小结,感兴趣的朋友跟随小编一起看看吧
    2024-08-08
  • 手把手教你用Hexo+Github搭建属于自己的博客(详细图文)

    手把手教你用Hexo+Github搭建属于自己的博客(详细图文)

    越来越多的朋友选择自己架设自己的博客,以来方便个性样式二来也能带来不少收入,大部分朋友都会选择wordpress搭建个人博客,这里为大家分享使用Hexo+Github搭建开发者博客的方法,需要的朋友可以参考下
    2017-10-10
  • Win10下为VSCode配置LaTex编辑器的方法

    Win10下为VSCode配置LaTex编辑器的方法

    这篇文章主要介绍了Win10下为VSCode配置LaTex编辑器的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05

最新评论