07.Git从放弃到入门: 命令reset图解

2,055 阅读4分钟

前言

git reset 命令用于执行撤销操作。 它可以移动 HEAD 指针,并且根据选项参数有选择的改变暂存区域(索引)和工作目录。本文通过图文结合方式讲解其功能和工作原理。 👇 Git入门系列文章链接如下,请按照顺序阅读文章 👇。

本系列更多文章详见专栏 📚 Git从放弃到入门

为了更好进行差异性分析,统一使用初始化的项目作为默认操作目录。详细参考上文 项目初始化设置

命令格式

常用的语法格式如下,

git reset [<mode>] [<commit>]

mode 默认值是 --mixed, 提供了 --soft--mixed--hard--merge--keep等可选项,本文只对--soft--mixed--hard进行介绍。

commit 用于指定重置的提交节点(分支),默认值是 HEAD

可以使用 HEAD~N 语法指定提交节点,也可使用 ^ 符号进行指定 :
HEAD 当前提交节点
HEAD^ 当前提交节点的父节点 等效于 HEAD~
HEAD^^ 当前提交节点的父节点的父节点 等效于 HEAD~2

运行以下命令,查看初始项目信息。

# 查看提交历史  git log
$ git hist --all
# 检查当前文件状态   git status 
$ git st
# 生成文件目录结构 需安装 npm install treer -g 
$ treer -i '.git'
# 查看索引内容
$ git ls-files -s     

image.png

--soft 选项

运行 git reset --soft HEAD~2命令,reset 会移动 HEAD 分支的指向, 这与 checkout 移动 HEAD 自身不同。

image.png

可以看到 HEAD 分支的指向由节点7416512 移动至节点8e47817。由于此节点分支的提交对象跟暂存区域的内容不一致,当查看文件状态时发生变化,显示 Readme.md文件新增,file.txt文件修改。 索引和工作目录内容未受影响。

image.png

--mixed 选项

运行 git reset [--mixed] HEAD~2命令,mode 默认值是 --mixed可以省略(等同于 git reset HEAD~2)。 reset 会用 HEAD 指向的当前快照的内容来更新暂存区(索引)。

image.png

运行 git st (git status)git ls-files -s 查看文件状态和索引。

  • 暂存区(索引)内容更新,只有file.txt跟当前快照保持一致,Readme.md文件被移除。
  • 文件状态显示工作目录中 file.txt 与暂存区(索引)内容相比,发生更改但未暂存;Readme.md 标识为 未跟踪的文件(Untracked),意味着 Git 在之前的快照(提交)中没有此文件,需要使用 git add 命令添加跟踪。

image.png

--hard 选项

运行 git reset --hard HEAD~2命令,它继续这 --mixed 的操作覆盖索引,同时会将索引内容覆盖工作目录。

image.png

--hard 标记是 reset 命令唯一的危险用法,它会真正地销毁数据。 其他任何形式的 reset 调用都可以轻松撤消,但是 --hard 选项不能,因为它强制覆盖了工作目录中的文件。

image.png

--soft/--mixed/--hard 区别图解

reset 命令会以特定的顺序重写 HEADStaging AreaWorking Directory,通过指定以下选项时停止:

  1. 移动 HEAD 分支的指向 (若指定了 --soft,则到此停止)
  2. 使暂存区域(索引)看起来像 HEAD (若不指定 或 指定 --mixed,则到此停止)
  3. 使工作目录看起来像暂存区域(索引) (若指定了 --hard )

image.png

指定路径

reset 命令可以提供一个作用路径,常用于取消暂存的更改,语法如下。

git reset [commit] <paths>

运行 git reset file.txt (等同于 git reset --mixed HEAD file.txt) 命令,通过指定的文件或文件集合,可以部分更新索引。

  • 移动 HEAD 分支的指向 (已跳过)
  • 使暂存区域(索引)看起来像 HEAD (命令运行结束)

image.png

在初始项目中,修改file.txt内容为 v6,使用 git add 暂存更改。

image.png

运行 git reset file.txt 命令后,提示 file.txt 存在更改尚未暂存。

image.png

接下来使用git checkout -- file.txt命令从暂存区域内检出文件覆盖工作目录文件,此时file.txt内容为 v5

image.png

影响速查表

“树” 思是 “文件的集合”,而不是指特定的数据结构。

Git 作为一个系统,是以它的一般操作来管理并操纵这三棵树的:

用途
HEAD上一次提交的快照,下一次提交的父结点
Staging Area ( Index )预期的下一次提交的快照
Working Directory沙盒

命令对树的影响速查表

命令HEADStaging Area/IndexWorking Directory
指定提交
reset --soft [commit]REFNONO
reset [--mixed] [commit]REFYESNO
reset --hard [commit]REFYESYES
checkout <commit>HEADYESYES
指定路径
reset [commit] <paths>NOYESNO
checkout [commit] <paths>NOYESYES

REF 表示该命令移动了 HEAD 指向的分支引用
HEAD 表示只移动了 HEAD 自身
YES 表示对树有影响
NO 表示对树无影响

📚参考&关联阅读

"重置揭密",Pro Git
"Git 引用",Pro Git
"git reset",Pro Git
"git reset",Pro Git

关注专栏

如果本文对您有所帮助请关注➕、 点赞👍、 收藏⭐!您的认可就是对我的最大支持!

此文章已收录到专栏中 👇,可以直接关注