在学习 reset 命令之前,先了解两个命令。
gi log
显示从最近到最远的提交日志。
$ git log
commit 9d3d0f16459a1e53841edae0738e6467215d5340 (HEAD -> master, origin/master, origin/HEAD)
Author: 58214381@qq.com <58214381@qq.com>
Date: Thu Feb 17 20:00:12 2022 +0800
Initial commit
commit bfec61e5f8f1f9b799c147f671662aa8d04971aa
Author: 58214381@qq.com <58214381@qq.com>
Date: Thu Feb 17 20:00:12 2022 +0800
Initial commit
我们可以看到输出了很多信息,这个时候我们可以加上 --pretty=oneline 参数
。
如下我们可以看到它会把每条记录以一行的形式输出:
$ git log --pretty=oneline
9d3d0f16459a1e53841edae0738e6467215d5340 (HEAD -> master, origin/master, origin/HEAD) Initial commit
bfec61e5f8f1f9b799c147f671662aa8d04971aa Initial commit
git HEAD
在Git
中,用 HEAD
表示当前版本,也就是最新的一次提交,上一个版本就是 HEAD^
,上上一个版本就是 HEAD^^
,当然往上100个版本写100个 ^ 显然是不现实的,可以写成 HEAD~100
。
接下来,我们要把当前版本回退到上一个版本,就可以使用 git reset 命令:
git reset
将当前<HEAD>
重置为指定状态。
有以下几种模式:
–soft
不删除工作区改动代码,撤销 commit
,不撤销 git add
. (git status
是绿色
的状态)。
git reset --soft HEAD^
–mixed
重置索引,但不重置工作树,更改后的文件标记为未提交(add)
的状态。
即不删除工作区改动代码,撤销 commit
,并且撤销 git add
. 这个是默认参数。
git reset --mixed HEAD^
// 等价于
git reset HEAD^
–hard
删除工作区改动代码,撤销 commit
,撤销 git add
. 注意完成这个操作后,就恢复到了上一次的 commit 状态,从指定的 `
git reset --hard HEAD^
这里误操作了也不用怕,可以恢复的,下面会讲。
–merge
重置索引并更新工作树中在
换句话说, --merge
做的是类似于 git read-tree -u -m <commit>
的事情,但会转发未合并的索引条目。
git reset --merge HEAD^
–keep
重置索引项并更新工作树中 <commit>
和 HEAD
之间不同的文件。 如果一个在<commit>
和 HEAD
之间不同的文件有本地修改,重置将被中止。
git reset --keep HEAD^
–[no-]recurse-submodules
当工作树被更新时,使用 --recurse-submodules
也将根据超级项目中记录的提交,递归地重置所有活动的子模块的工作树,同时也将子模块的 HEAD
设置为在该提交中被分离。
我现在的需求使用 --mixed
就可以了:
git reset --mixed HEAD^
// or
git reset --mixed HEAD~1
git reset 和 git revert 的区别
git revert
后多出一条 commit
,提醒同事,这里有回撤操作。
git reset
直接版之前 commit
删掉,非 git reset --hard
的操作是不会删掉修改代码,如果远程已经有之前代码,需要强推 git push -f
误操作后也可以恢复
例如执行了 git reset --hard HEAD^
后 commit
记录也会被消除,git
还可以指定回到未来的某个版本,只要你知道 commit_id
就可以:
$ git reset --hard 1094a
HEAD is now at 83b0afe append GPL
如果不知道commit_id
怎么办呢,也不用担心。
在 Git
中,总是有后悔药可以吃的。当你用 $ git reset --hard HEAD^^
回退过头了,再想恢复到最近一次提交,就必须找到这次提交的的commit id
。Git
提供了 git reflog
命令,用来记录你的每一次命令:
$ git reflog
e475afc HEAD@{1}: reset: moving to HEAD^
这样你又可以回到未来了。