在开发中,有时候需要紧急退回某个线上版本修复问题,特别是 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。
参考