一文浅析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 <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)🌲 工作目录 🌲
  • 我们把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)🌲 没有 – 工作目录 🌲 没有 –
  • 说明: 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 相同 工作目录 🌲 没有 –
  • 我们把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撤销命令revert与reset区别全面对比 git版本回退方式(git reset、git revert、git stash) 如何使用git reset进行多commit合并 Git版本回退之reset和revert使用详解 git中reset和revert区别小结 Git恢复之前版本的三种方法之reset、revert、rebase详解
  • 目录
    • 背景
    • 要点
    • 准备工作
      • 代码
      • 运行结果
    • 使用–soft选项的git reset命令
      • 使用–mixed选项的git reset命令
        • 使用–hard选项的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 <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

          我们把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)🌲 没有
          工作目录 🌲 没有

          说明: 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 相同
          工作目录 🌲 没有

          我们把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撤销命令revert与reset区别全面对比
          • git版本回退方式(git reset、git revert、git stash)
          • 如何使用git reset进行多commit合并
          • Git版本回退之reset和revert使用详解
          • git中reset和revert区别小结
          • Git恢复之前版本的三种方法之reset、revert、rebase详解

          站内搜索