Git:git-reflog的用法总结

概要

git-reflog的用法总结。

博客

博客地址:IT老兵驿站

前言

git-reflog是用来恢复本地错误操作很重要的一个命令,所以在这里对它进行一下整理。

正文

语法

1
git reflog <subcommand> <options>

具体的用法

1
2
3
4
git reflog [show] [log-options] [<ref>]
git reflog expire [--expire=<time>] [--expire-unreachable=<time>] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all | <refs>…​]
git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] ref@{specifier}…​
git reflog exists <ref>

Reference logs, or “reflogs”, record when the tips of branches and
other references were updated in the local repository.

这句话怎么理解呢,记录了“when”,时间?这个地方理解错误了,应该是在branches和其它参考在本地的仓库中被更新时来做记录。

翻译:Reference logs(参考日志),或者叫做”reflogs”,记录了分支的tips(提示信息?)或者其他参考在本地仓库被更新的时间(when)。

问题来了,这个参考日志的作用是什么,和日志又有什么区别呢?

找到了这篇帖子

1
2
3
4
5
6
7
git log shows the current HEAD and its ancestry. That is, it prints the commit HEAD points to, then its parent, its parent, and so on. It traverses back through the repo's ancestry, by recursively looking up each commit's parent.

(In practice, some commits have more than one parent. To see a more representative log, use a command like git log --oneline --graph --decorate.)

git reflog doesn't traverse HEAD's ancestry at all. The reflog is an ordered list of the commits that HEAD has pointed to: it's undo history for your repo. The reflog isn't part of the repo itself (it's stored separately to the commits themselves) and isn't included in pushes, fetches or clones; it's purely local.

Aside: understanding the reflog means you can't really lose data from your repo once it's been committed. If you accidentally reset to an older commit, or rebase wrongly, or any other operation that visually "removes" commits, you can use the reflog to see where you were before and git reset --hard back to that ref to restore your previous state. Remember, refs imply not just the commit but the entire history behind it.

上面就讲的比较清楚了,总结一下:

git log是显示当前的HEAD和它的祖先的,递归是沿着当前指针的父亲,父亲的父亲,……,这样的原则。
git reflog根本不遍历HEAD的祖先。它是HEAD所指向的一个顺序的提交列表:它的undo历史。reflog并不是repo(仓库)的一部分,它单独存储,而且不包含在pushesfetches或者clones里面,它纯属是本地的。
reflog可以很好地帮助你恢复你误操作的数据,例如你错误地reset了一个旧的提交,或者rebase,……,这个时候你可以使用reflog去查看在误操作之前的信息,并且使用git reset --hard 去恢复之前的状态。
下面研究一下这个命令的具体用法。

先了解一下git的版本表示方法:

HEAD@{2} means “where HEAD used to be two moves ago”, master@{one.week.ago}means “where master used to point to one week ago in this local repository”

HEAD@{2}表示HEAD指针在两次移动之前的情况;而 master@{one.week.ago}表示master在本地仓库一周之前的情况。

“show”子命令显示所指定的参考的日志。

实例: 显示HEADreflog

1
2
3
4
5
6
7
8
9
10
11
12
$ git reflog show
ef64f10 (HEAD -> BlueLake_theme) HEAD@{0}: commit: 新增ethereum-programming-intr oduction
122e0ec (origin/BlueLake_theme) HEAD@{1}: commit: 移除了冗余的ethereum-rationale 文章
c17fbbb HEAD@{2}: commit: 新增git-change-server-password文章
1603d1a HEAD@{3}: pull: Merge made by the 'recursive' strategy.
0ce1e93 HEAD@{4}: commit: 新增了以太坊原理
c73503c HEAD@{5}: commit: 修改了-X-Frame-Options的关键字
6af02f6 HEAD@{6}: commit: 新增了git-tag的文章;修改了git其他的文章,规范了名字、 关键字
9087fbd HEAD@{7}: commit: 新增了gti-reset文章
039d95c HEAD@{8}: commit: 移除了没用的目录
ff72601 HEAD@{9}: commit: 修改成了next主题
ef64f10 (HEAD -> BlueLake_theme) HEAD@{0}: commit: 新增ethereum-programming-intr oduction

从上图可以看到,几乎所有的操作都记录在其中,这个就像MySQL,随时可以回滚。

“expire”子命令会删除掉更老的reflog条目。

“delete”子命令从reflog中删除一个条目。

“exists”子命令检查一个ref是否有一个reflog。

这几个命令就相对比较简单了,以后再尝试了。

参考

https://git-scm.com/docs/git-reflog