? 这是我参与更文挑战的第18天,活动详情查看: 更文挑战
0x00 ? 前言
? Git入门系列文章链接如下,请按照顺序阅读文章 ?。
本文是第六篇,通过图文结合方式学习reset命令的功能和工作原理。
为了更好进行差异性分析,统一使用初始化的项目作为默认操作目录。详细参考上文 项目初始化设置
0x01 Reset
git reset 命令用于执行撤销操作。 它可以移动 HEAD 指针,并且根据选项参数有选择的改变暂存区域(索引)和工作目录。
常用的语法格式如下,
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
复制代码

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

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

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

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

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

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

总结
reset 命令会以特定的顺序重写 HEAD、Staging Area、 Working Directory,通过指定以下选项时停止:
- 移动 HEAD 分支的指向 (若指定了 –soft,则到此停止)
- 使暂存区域(索引)看起来像 HEAD (若不指定 或 指定 –mixed,则到此停止)
- 使工作目录看起来像暂存区域(索引) (若指定了 –hard )

指定路径
reset 命令可以提供一个作用路径,常用于取消暂存的更改,语法如下。
git reset [commit] <paths>
复制代码
运行 git reset file.txt (等同于 git reset --mixed HEAD file.txt) 命令,通过指定的文件或文件集合,可以部分更新索引。
- 移动 HEAD 分支的指向 (已跳过)
- 使暂存区域(索引)看起来像 HEAD (命令运行结束)

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

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

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

影响速查表
“树” 思是 “文件的集合”,而不是指特定的数据结构。
Git 作为一个系统,是以它的一般操作来管理并操纵这三棵树的:
| 树 | 用途 |
|---|---|
| HEAD | 上一次提交的快照,下一次提交的父结点 |
| Staging Area ( Index ) | 预期的下一次提交的快照 |
| Working Directory | 沙盒 |
命令对树的影响速查表
| 命令 | HEAD | Staging Area/Index | Working Directory |
|---|---|---|---|
| 指定提交 | |||
reset --soft [commit] |
REF | NO | NO |
reset [--mixed] [commit] |
REF | YES | NO |
reset --hard [commit] |
REF | YES | YES |
checkout <commit> |
HEAD | YES | YES |
| 指定路径 | |||
reset [commit] <paths> |
NO | YES | NO |
checkout [commit] <paths> |
NO | YES | YES |
REF表示该命令移动了 HEAD 指向的分支引用
HEAD表示只移动了 HEAD 自身
YES表示对树有影响
NO表示对树无影响
0x02 ?参考
“重置揭密”,ebook
“Git 引用”,ebook
“git reset”,ebook
“git reset”,docs
0x03 关注专栏
此文章已收录到专栏中 ?,可以直接关注。
更多文章继续阅读|系列文章持续更新






















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)