前言
重置操作主要是用来重置工作区和暂存区的内容,多用来修改提交记录或者恢复本地记录;
重置操作的相关区域有:工作区、暂存区、版本库;
他们之间的关系如下图所示:

目录
- 重置操作的等级
- 重置操作(git reset --soft)
- 重置操作(git reset)- 默认
- 重置操作(git reset --hard)
正文
1. 重置操作的等级
重置操作可以划分为三个等级,而且三个等级分别对应的就是工作区、暂存区、本地仓库
- git reset --soft:只修改Head指针,即只重置本地仓库的记录
- git reset --mixed: 默认,重置本地仓库的同时,还会修改暂存区的内容
- git reset --hard:同时重置本地仓库、暂存区、工作区
下面我们就分别介绍下这三个等级;
2. 重置本地仓库
对应的命令:git reset --soft
这个重置操作,只会将HEAD指针移动到指定的提交上,并不会修改其他区的内容;
比如我们现在提交了三次,在本地仓库有三个版本,如下所示:

本篇文章的例子假设都只有一个master分支,不考虑多分支的情况
此时三个区的版本都为V3:

那么如果我们此时执行git reset --soft HEAD~
操作,就会将HEAD指向V2,到此重置操作就结束了;
这个时候,只是本地仓库的记录被修改了,工作区和暂存区是不会被修改的;

对应的三个区的内容如下,本地仓库变成了V2,工作区和暂存区还是V3:

如果此时我们再在本地进行修改,然后重新提交到本地仓库,那么这几个操作就跟我们之前介绍的如何修改已经提交的记录类似了;他们的结果都是修改了提交记录;
3. 重置暂存区
对于的命令:git reset
这个重置操作是默认的操作,就是在重置本地仓库之后,继续重置暂存区,然后停止;
如下所示,本来三个区域都是最新记录V3:

但是执行git reset HEAD~
后,本地仓库和暂存区会变成V2,工作区不变;

此时通过git status
可以看到,暂存区的内容被清空了;
下面我们看个例子:
现有仓库的git log
如下所示:可以看到,有两条记录
jalon@bogon git-basic % git log
commit df79ed26f9fb8de7c721bd7df3a91a0cb114581b (HEAD -> master)
Merge: d488c1c cf228d6
Author: Jalon
Date: Sat Jan 22 15:59:48 2022 +0800
fix
commit cf228d6ebb0af2209406b7e58c19de79f1b800ec
Author: Jalon
Date: Sat Jan 22 15:59:11 2022 +0800
update a.txt
- 先执行
git reset HEAD~
,此时会重置到cf228
这条记录
重置后会有一条贴心的提示,说修改记录没有暂存;换句话说就是暂存区的修改记录被删除了
jalon@bogon git-basic % git reset HEAD~
Unstaged changes after reset:
M a.txt
- 再执行git status 查看当前仓库的状态,也是提示修改记录没暂存:
jalon@bogon git-basic % git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: a.txt
no changes added to commit (use "git add" and/or "git commit -a")
这个重置暂存区的操作,主要是为了修改提交记录;
比如我们觉得最新的提交记录太潦草,想要把修改记录整理下再重新提交,那么就可以用这个重置操作git reset HEAD~
,然后在本地进行修改,再提交;
4. 重置本地工作区
对应的命令:git reset --hard
- 这个命令会同时重置本地工作区、暂存区、本地仓库的内容;
这个命令 --hard 属于比较危险的,因为本地修改会被覆盖掉,此时如果本地修改还没提交,那么就找不回来了;
如下所示,本来三个区都是V3:

执行git reset --hard HEAD~
命令后,所有区都会变成V2版本:

此时执行git status命令,会发现工作区很干净,因为这三个区域现在都是在V2版本,所以工作区当然也是干净的了;
- 这个重置操作还有一个作用,就是用来清空本地操作:
比如现在我们修改了一些内容,也已经添加到暂存区(执行了git add
);
但是添加之后,感觉修改有问题,这时就可以通过git reset --hard
来进行粗暴的恢复(默认恢复到HEAD节点);
此时本地工作区、暂存区都会恢复到HEAD指向的最新提交版本;
- 关于新增的文件:
如果本地工作区有新增的文件(非修改的文件),那么该文件只是存在于本地工作区,还没有添加到git记录;
此时该文件不受影响即不会被删除(因为该文件不存在于git系统中,所以通过git命令无法去删除它)
比如我们现在新建一个文件c.txt,此时有a.txt, b.txt, c.txt三个文件
jalon@bogon git-basic % touch c.txt
jalon@bogon git-basic % ls
a.txt b.txt c.txt
然后执行git reset --hard HEAD
,即重置所有区的内容到HEAD指向的最新提交:
jalon@bogon git-basic % git reset --hard HEAD
HEAD is now at 633f24c rebase demo
jalon@bogon git-basic % ls
a.txt b.txt c.txt
会发现,重置后,c.txt文件还是存在的,通过git status
查看状态,如下所示:
jalon@bogon git-basic % git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
c.txt
nothing added to commit but untracked files present (use "git add" to track)
意思就是该文件没有被git追踪,所以git的重置操作无法对其进行干涉;
总结
重置操作的三个等级
git reset --soft
:只修改Head指针,即只重置本地仓库的记录git reset
: 默认,重置本地仓库的同时,还会修改暂存区的内容git reset --hard
:同时重置本地仓库、暂存区、工作区
最后的--hard是比较危险的一个操作,因为会重置本地工作区的修改记录;
在执行--hard之前,要确保本地工作区的内容已经提交到版本库中(
git commit
提交,这样还有挽救的余地),除非你真的确定本地工作区的修改记录是没用的
评论区