您的位置:首页 > 手游攻略 > 一文浅析git中三种reset命令的使用与区别实用指南

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

作者:互联网  时间: 2026-10-25 10:50:01  

平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“一文浅析git中三种reset命令的采用与区别”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。

背景

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

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

本文会探讨它们的区别。

要点

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

HEADtext{HEAD}HEAD 是否会被更新暂存区(Indextext{Index}Index) 是否会被更新工作目录 是否会被更新
git reset --soft 是否否
git reset --mixed 或
git reset
是是否
git reset --hard 是是是

在 这个链接中,能够看到关git reset 理解这一步时,命令的介绍,其中开头的内容如下所示 (我在图中用红色框标出了本文关心的内容)

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

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

从实现思路看,参考 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 管理这个临时目录的内容
  • 新建4 个 commit

运行结果

借助执行下方的命令就能够运行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 命令的作用就是

将 HEAD 指向 所对应的位置

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

git reset --soft HEAD~2

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

借助查看git status 命令的执行结果,能够知道 工作目录 和 暂存区 的内容是一样的

小结

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

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

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

说明: git reset 和 git reset --mixed 的作用相同。

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

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

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

git reset --mixed HEAD~2

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

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

小结

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

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

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

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

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

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

git reset --hard HEAD~2

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

借助查看 git status 命令的执行结果,能够知道以下三者的内容相同

  • HEAD
  • 暂存区
  • 工作目录

小结

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

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

结合项目来看,总的来说,git reset命令采用适合结合实际项目边做边理解。先抓住核心思路,再逐步补上细节和边界处理,最后效果会更稳定,也更容易复用。

相关资讯

最新游戏

更多

Copyright©2010-2019. All rights reserved | 波波三国游戏官网|[email protected]

备案编号:湘ICP备2022015115号-4