在开发过程中有时候可能在执行完git commit之后发现代码有问题,需要撤除提交,这时候我们可以使用以下git reset命令来实现
比较常见的git reset
命令包括
1、默认情况下工作区,暂存区和本地仓库区是一样的
2、当我们使用git add命令把文件添加到暂存区后,工作区和暂存区保持一样的状态,只有和本地仓库区不同
3、最后当我们执行完git commit命令后,三个区域又都变为一样的,这个时候HEAD指针会指向最近的一次commit
我们在前面的 git提交流程文章中有介绍到git中分支和HEAD的指向关系,如下图所示
在实际工作中我们可能会存在多笔commit,但是HEAD在默认情况下都会指向最新的一次commit。所有大致的commit和HEAD的指向关系如图
在复习了git提交流程与HEAD指针与commit关系之后,我们就可以先使用git reset命令来重置文件状态了。
1、git reset --mixed
–mixed是默认参数,该命令是重置HEAD和index区
2、重置index区
例如我们修改了工作区的一个文件并通过git add
命令添加到index
区,但是又想要恢复刚刚的git add
操作,首先我们使用git status
查看状态,如图
我们执行git reset
或者git reset --mixed
命令之后得到的结果如
这种情况下会重置index
区的变更,保留工作区内容
3、重置本地仓库repository区
如果我们已经执行完git commit
命令,但是想要进行恢复重置的话也可以使用git reset
命令,但是会稍微有一些区别
git reset HEAD^
这个时候就会重置index
区域和repository
区,但是会保留工作区内容
4、git reset --soft
该命令的主要功能是重置HEAD
,保留index
和工作区。
例如我们已经执行完git commit
操作,使用git log
查看提交记录为
这时我们发现需要commit
内容存在错误,需要恢复。我们可以执行
git reset --soft HEAD^
可以看到,在执行了reset soft
命令后repository
区域的已经被重置,而index
区域的依然被保留
5、git reset --hard
该命令会重置掉工作区,index
区和repository
区,所以在使用的使用一定要小心。在执行完git commit
后我们查看一下提交log
git reset --hard HEAD^
执行完毕后我们发现之前修改的内容已经被重置了
在这个例子中,执行完reset --hard
命令后我们发现会在日志中输出以下内容
HEAD is now at 9f91224 git test
参考我们在本文开头中画出来的git HEAD
和commit
的指向关系图我们可以看到,这个命令在执行前和执行后的指向关系图分别为:
执行前
使用reset命令,可通过移动HEAD指针达到回退版本的目的,重要信息:reset不是回退到HEAD指针,而是重置HEAD指针,即移动HEAD指针,
reset soft
git reset --soft < commit-id>
将指针指向 暂存区的内容变为两个版本之间的差异(改动),工作区内容不变,仍然为旧HEAD的内容
reset
命令:git reset < commit-id>
将指针指向 暂存区的内容变为,工作区内容不变,仍然为旧HEAD的内容
reset hard
命令:git reset --hard <commit-id> 将指针指向<commit-id> ,暂存区和工作内容都变为<commit-id>版本内容
特点:都改变HEAD指针到,程度(reset-soft, reset, reset-hard)逐步扩大,只有reset-hard重置时,才会实际修改当前代码,其余两种会有一点细微区别
支持^和~
git reset --hard HEAD^
git reset --hard HEAD^^
git reset --hard HEAD~10
关于-hard
-hard 会覆盖暂存区和工作区的内容,但是还有一些恢复的方法的,即使使用了–hard,一些提交不见了,但他们仍然存在git的仓库当中,还记得提交号的话,就可以再次将HEAD指回,(依然使用reset命令)原来的提交,由于有暂存区和工作区是不受控的,即使恢复了版本工作区的内容和暂存区(改动)将无法找回。