在提交错误的情况下,如果需要回滚可以使用git reset 命令
关于工作区,暂存区和HEAD请参考:Git中的工作区,暂存区和HEAD。
在工作中如果想撤回某些提交可以使用git reset,语法如下:
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]
如果只移动HEAD的指针,可以使用--soft参数,默认是--mixed。
现在有三次提交,查看历史可以使用git log命令,此时的工作区,暂存区和HEAD的情况如下图。
$ git log
commit 2dad5d003d6ca1fd421d5a56ee32a7df4b5cf6d9 (HEAD -> master)
Author: Java猿 <1351891797@qq.com>
Date: Fri Jun 24 22:35:27 2022 +0800
v3
commit 2a4ea82ed9b60acf879134a70804e311a9af4dc4
Author: Java猿 <1351891797@qq.com>
Date: Fri Jun 24 22:35:01 2022 +0800
v2
commit 69df4abafbe9a6ce24b1f107c217b47ce2ca0dc9
Author: Java猿 <1351891797@qq.com>
Date: Fri Jun 24 22:34:11 2022 +0800
v1
在执行reset前,先看看暂存区的数据,使用命令git ls-files --stage查看
$ git ls-files --stage
100644 04d0d5494ee40cbab475a7d1c4473f7fc8da3ecc 0 test.txt
现在执行reset 回滚到第二次提交:
$ git reset --soft 2a4ea82ed9b60acf879134a70804e311a9af4dc4
$ git log
commit 2a4ea82ed9b60acf879134a70804e311a9af4dc4 (HEAD -> master)
Author: Java猿 <1351891797@qq.com>
Date: Fri Jun 24 22:35:01 2022 +0800
v2
commit 69df4abafbe9a6ce24b1f107c217b47ce2ca0dc9
Author: Java猿 <1351891797@qq.com>
Date: Fri Jun 24 22:34:11 2022 +0800
v1
再次查看暂存区的数据,发现前后没有变化
$ git ls-files --stage
100644 04d0d5494ee40cbab475a7d1c4473f7fc8da3ecc 0 test.txt
此时可以通过commit命令再次提交,使HEAD更新到最后一次提交。
$ git commit -m "v3"
[master 1a2a395] v3
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log -1
commit 1a2a39537633999571db44ab27aad4f58e26f7ff (HEAD -> master)
Author: Java猿 <1351891797@qq.com>
Date: Fri Jun 24 23:00:06 2022 +0800
v3
移动HEAD同时更新暂存区,使用--mixed参数
现在各个区域的数据如下,文件的版本在各个区域都是v3。
执行rest前还是检查暂存区和HEAD的指向。
$ git ls-files --stage
100644 04d0d5494ee40cbab475a7d1c4473f7fc8da3ecc 0 test.txt
$ git log -1
commit 1a2a39537633999571db44ab27aad4f58e26f7ff (HEAD -> master)
Author: Java猿 <1351891797@qq.com>
Date: Fri Jun 24 23:00:06 2022 +0800
v3
通过--mixed参数执行rest,执行后暂存区也会被更新,也就是更新了索引。
$ git reset --mixed 2a4ea82ed9b60acf879134a70804e311a9af4dc4
Unstaged changes after reset:
M test.txt
$ git log -1
commit 2a4ea82ed9b60acf879134a70804e311a9af4dc4 (HEAD -> master)
Author: Java猿 <1351891797@qq.com>
Date: Fri Jun 24 22:35:01 2022 +0800
v2
$ git ls-files --stage
100644 8494ac27064713465d43ddea83398365ac0ba721 0 test.txt
暂存区更新后,执行git diff命令查看工作区和暂存区的差异,暂存区的内容是v2,工作区的是v3。
$ git diff
diff --git a/test.txt b/test.txt
index 8494ac2..04d0d54 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-v2
\ No newline at end of file
+v3
\ No newline at end of file
此时可以把工作区添加到暂存区,并最终提交,提交后HEAD指向新的提交。
$ git add test.txt
$ git commit -m "v3"
[master 86f1583] v3
1 file changed, 1 insertion(+), 1 deletion(-)
$ git ls-files -s
100644 04d0d5494ee40cbab475a7d1c4473f7fc8da3ecc 0 test.txt
$ git log -1
commit 86f15833a09f0759602cf4fa3d64bb1743608a0a (HEAD -> master)
Author: Java猿 <1351891797@qq.com>
Date: Fri Jun 24 23:27:43 2022 +0800
v3
回滚后更新工作目录,使用参数--herd
此时提交的版本还是v3,如下图所示:
此刻使用rest命令的--hard参数,执行后HEAD指向了v2,查看工作区的文件内容,此时也是v2,说明工作区也回滚到了上个提交。
$ git reset --hard 2a4ea82ed9b60acf879134a70804e311a9af4dc4
HEAD is now at 2a4ea82 v2
$ cat test.txt
v2
$ git log
commit 2a4ea82ed9b60acf879134a70804e311a9af4dc4 (HEAD -> master)
Author: Java猿 <1351891797@qq.com>
Date: Fri Jun 24 22:35:01 2022 +0800
v2
commit 69df4abafbe9a6ce24b1f107c217b47ce2ca0dc9
Author: Java猿 <1351891797@qq.com>
Date: Fri Jun 24 22:34:11 2022 +0800
v1
可见--hard参数是比较危险的,直接更新了工作区,一般情况下谨慎使用此参数。
另外,关于HEAD的说明,HEAD代表当前的提交,HEAD^代表上个提交,HEAD^^代表上上个,一次类推。或者是HEAD~加数字也表示倒数第几次提交。
#以下是回滚上次提交
$ git reset --soft HEAD^
$ git reset --soft HEAD~1