许多时候,在用 Git
的时候有可能 git commit
提交代码后,发现这一次 commit
的内容是有错误的,那么可以用git reset进行操作撤回,且无新增commit_id
工作模式
git reset
有三种工作模式,即 --soft
、–mixed
(默认方式) 和 --hard
。
git reset --soft
:仅仅移动当前Head
指针,不会改变工作区和暂存区的内容,如下图所示:只有HEAD
指针被修改了
git reset --mixed
:是git reset
的默认参数,移动HEAD
指针,改变暂存区内容,但不会改变工作区 ,如下图所示:HEAD
指针和暂存区的内容均被修改
git reset --hard
:当前HEAD
指针、工作区和暂存区内容全部改变 ,如下图所示:HEAD
指针、工作区和暂存区内容全部改变
使用场景
–hard
-
要放弃目前本地的所有改变时,即去掉所有
git add
到暂存区的文件和工作区的文件,可以执行git reset --hard HEAD
来强制恢复 git 管理的文件夹的內容及状态; -
抛弃目标节点后的所有
commit
(可能觉得目标节点到原节点之间的commit
提交有问题)。
–soft
-
原节点和
reset
节点之间的差异变更集会放入index
暂存区中(Staged files
),所以假如我们之前工作目录没有改过任何文件,也没add
到暂存区,那么使用reset --soft
后,我们可以直接执行git commit
將index
暂存区中的內容提交至Repository
中。为什么要这样呢?这样做的使用场景是:假如我们想合并当前节点与 reset 目标节点之间不具太大意义的
commit
记录(可能是阶段性地频繁提交,就是开发一个功能的时候,改或者增加一个文件的时候就commit
,这样做导致一个完整的功能可能会好多个commit
点,这时假如你需要把这些commi
t 整合成一个commit
的时候)时,可以考虑使用reset --soft
来让commit
演进线图较为清晰。总而言之,可以使用--soft
合并commit
节点。
–mixed
(默认)
-
使用完
reset --mixed
后,我们可以直接执行git add
将这些改变过的文件內容加入index
暂存区中,再执行git commit
将Index
暂存区中的內容提交至Repository
中,这样一样可以达到合并 commit 节点的效果(与上面 --soft 合并 commit 节点差不多,只是多了git add
添加到暂存区的操作); -
移除所有
Index
暂存区中准备要提交的文件(Staged files
),我们可以执行git reset HEAD
来Unstage
所有已列入Index
暂存区的待提交的文件。(有时候发现 add 错文件到暂存区,就可以使用命令)。 -
commit
提交某些错误代码,或者没有必要的文件也被commit
上去,不想再修改错误再commit
(因为会留下一个错误commit
点),可以回退到正确的commit
点上,然后所有原节点和reset
节点之间差异会返回工作目录,假如有个没必要的文件的话就可以直接删除了,再commit
上去就OK了。
git回滚文件场景总结
修改完还未git add:使用 git checkout 回滚:
git checkout .
使用暂存区的文件覆盖工作区,所以执行完 git add .
之后,再执行该命令是无效的。 git checkout .
和 git add .
是一对反义词。
git add提交还未commit
使用 git add
提交到暂存区,还未 commit
之前,使用 git reset
和 git checkout
回滚:
git reset # 先用 Head 指针覆盖当前的暂存区内容
git checkout . # 再用暂存区内容覆盖工作区内容
或者使用直接使用 head 覆盖当前暂存区和工作区。
git reset --hard
已经git commit还未git push
使用 git reset 回滚:
git reset --hard <last_commit_id>
覆盖本地仓库、暂存区和工作区。
已经git push
git reset --hard <commit_id>
强制提交当前版本号:git push origin <远端分支名称> --force
错误的把大文件添加到了缓存区
git reset
撤回添加。