在开发中,有时候需要紧急退回某个线上版本修复问题,特别是 reset
操作回滚之前的版本,如果操作不注意会发现新的一些工作的提交历史丢失了,这个时候 git reflog
会很有帮助。
git reflog
和 git log
功能很相近,都是记录日志的,和 git log
不同在于 git reflog
记录了 HEAD
指针的变更历史。
介绍
首先使用准备好的分支来看一下:
$ git log --oneline
aea03a0 (HEAD -> reflog) version5 1abb498 version4 97697e6 version3 d421d76 version2 b5ba58e version1
$ git reflog
aea03a0 (HEAD -> reflog) HEAD@{0}: commit: version5 1abb498 HEAD@{1}: commit: version4 97697e6 HEAD@{2}: commit: version3 d421d76 HEAD@{3}: commit: version2 b5ba58e HEAD@{4}: commit (initial): version1
|
其中 git reflog
比 git log
多了一些信息:
HEAD@{n}
: 表示 HEAD
指针在第 n
次操作前的位置;
commit
: 表示这一次的操作,可能会有其他取值,比如 merge
、fetch
、reset
、rebase
等。
来使用 git reset
回滚一下看看:
$ git reset --hard 1abb498
HEAD is now at 1abb498 version4
$ git log --oneline
1abb498 (HEAD -> reflog) version4 97697e6 version3 d421d76 version2 b5ba58e version1
$ git reflog
1abb498 (HEAD -> reflog) HEAD@{0}: reset: moving to 1abb498 aea03a0 HEAD@{1}: commit: version5 1abb498 (HEAD -> reflog) HEAD@{2}: commit: version4 97697e6 HEAD@{3}: commit: version3 d421d76 HEAD@{4}: commit: version2 b5ba58e HEAD@{5}: commit (initial): version1
|
可以看出,此时 git log
已经找不到之前保存的最新的提交 aea03a0 version5
,而 其变更仍然保存在 git reflog
中。
这个时候时候如果想要找回这个丢失的提交就可以重新使用 reset
或者 cherry-pick
等操作:
$ git reset --hard aea03a0
$ git reset --hard HEAD@{0}
HEAD is now at aea03a0 version5
$ git log --oneline aea03a0 (HEAD -> reflog) version5 1abb498 version4 97697e6 version3 d421d76 version2 b5ba58e verson1
$ git reflog
aea03a0 (HEAD -> reflog) HEAD@{0}: reset: moving to aea03a0 1abb498 HEAD@{1}: reset: moving to 1abb498 aea03a0 (HEAD -> reflog) HEAD@{2}: commit: version5 1abb498 HEAD@{3}: commit: version4 97697e6 HEAD@{4}: commit: version3 d421d76 HEAD@{5}: commit: version2 b5ba58e HEAD@{6}: commit (initial): verson1
|
当然 reflog
仍然会记录找回的这个过程。
其它命令
其他命令基本不常使用,这里只做简单介绍,感兴趣可以去查看 git 文档
git reflog [show] [log-options] [[]]
- show 可以省略,等价于 git reflog;
- 支持增加其他 git log 命令的选项;
- ref 为需要查看的引用,可以省略,默认为展示全部的 HEAD,
下面为查看某个分支的 HEAD 变更记录:
$ git reflog test
8d7244a (test) test@{0}: pull: Fast-forward 34beecc test@{1}: pull: Fast-forward a1ed01a test@{2}: pull: Fast-forward 20bbab4 test@{3}: pull: Fast-forward a8fd248 test@{4}: branch: Created from refs/remotes/origin/test
|
git reflog expire
删除旧的 reflog
记录。如果指定了过期时间则从 reflog
中删除超过过期时间的记录。
git reflog delete
从 reflog
中删除一条记录。
$ git reflog delete HEAD@{n}
|
git reflog exists
检查一个引用是否有 reflog
。
参考