有时,我们用git commit代码时,发现commit的内容有误或者有些文件不小心被commit了,这个时候就需要撤销这一次的commit操作,通常可以使用git reset命令来实现。
用一句话概括该命令:
git reset - Reset current HEAD to the specified state
简单概括就是让HEAD这个指针指向其他的commit节点。
git reset命令的语法格式如下:
git reset [--soft | --mixed | --hard] [HEAD]
也可以直接指定要指向的commit_id:
git reset [--soft | --mixed | --hard] [commit_id]
科普三个概念:
- 工作目录:就是我们工作时的代码存放的区域。
- Index暂存区:执行了git add操作或者之前commit后的代码修改后的内容都会存入此区域。
- Repository:代码仓库,commit后的代码存放区域。
git reset命令有三种模式:mixed(默认)、soft和hard,下面分别进行介绍这三种模式。
mixed
保留工作目录,并清空暂存区
reset如果不加参数,默认使用 --mixed参数。
执行reset命令,在重置位置的同时,只保留工作目录的内容,但会将 Index暂存区 和 Repository 中的內容更改和reset目标节点一致,因此原节点和reset节点之间的差异变更集会放入工作目录中。
使用场景:
1、使用 git reset --mixed [HEAD] 后,可直接执行 git add 将改变过飘红的文件內容加入 index 暂存区中,再执行 git commit 将 Index暂存区 中的內容提交至Repository中,这样可以达到合并commit节点的效果,与soft合并commit节点相比,只多了git add添加到暂存区的操作。
2、移除所有Index暂存区中准备要提交的文件。
3、某些错误代码,或者没有必要的文件也被commit上去了,不想再修改错误再进行commit,假如有个没必要的文件的话就可以直接删除了。
soft
保留工作目录,并把重置HEAD所带来的新的差异放进暂存区
执行reset命令,在重置位置的同时,保留工作目录和Index暂存区的内容,只让 Repository 中的内容和 reset 目标节点保持一致,因此原节点和reset节点之间的差异变更集会放入index暂存区中。
使用场景:
如果之前工作目录没有改过任何文件,也没add到暂存区,那么使用git reset --soft [HEAD] 后,可以直接执行 git commit 將 index暂存区中的內容提交至Repository中。与mixed模式相比少了git add这步操作。
hard
重置工作目录和暂存区
执行reset命令,在重置位置的同时,直接将工作目录、Index暂存区和Repository都重置成目标reset节点的內容,所以效果看起来等于清空Index暂存区和工作区。
使用场景:
1、要放弃目前本地的所有改变时,即去掉所有add到暂存区的文件和工作区的文件,可以执行 git reset -hard [HEAD] 来强制恢复git管理的文件夹的內容及状态。
2、 想要抛弃目标节点后的所有commit时。
HEAD说明
HEAD后面有多少个^就代表前多少个版本:
- HEAD 表示当前版本
- HEAD^ 上一个版本
- HEAD^^ 上上一个版本
- HEAD^^^ 上上上一个版本
......
也可以使用 ~数字表示:
- HEAD~0 表示当前版本
- HEAD~1 上一个版本
- HEAD^2 上上一个版本
- HEAD^3 上上上一个版本
......
总结
git reset的本质是移动HEAD以及它所指向的branch。git reset这个命令虽然可以用来撤销commit,但本质只是移动HEAD的指针,并且顺带上HEAD所指向的branch,所以与其说是撤销,不如说是重置,这也与它的名称“reset”不谋而合。