前言
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
--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 选项不能,因为它强制覆盖了工作目录中的文件。
--soft/--mixed/--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表示对树无影响
📚参考&关联阅读
"重置揭密",Pro Git
"Git 引用",Pro Git
"git reset",Pro Git
"git reset",Pro Git
关注专栏
如果本文对您有所帮助请关注➕、 点赞👍、 收藏⭐!您的认可就是对我的最大支持!
此文章已收录到专栏中 👇,可以直接关注