手册页说log显示提交日志,reflog管理reflog信息。究竟什么是reflog信息,它有什么日志没有的?日志似乎更详细。
当前回答
git日志将从当前HEAD开始,即指向某个分支(如master)或直接指向提交对象(sha代码),并在提交后使用每个提交对象中的父字段实际扫描.git/objects目录中的对象文件。
实验:将HEAD直接指向一些commit: git checkout a721d(创建新的repo并用提交和分支填充它。用一些提交代码替换a721d)并删除rm .git/refs/heads/*分支 现在git log——oneline将只显示HEAD及其提交的祖先。
另一方面,Git reflog使用在.git/logs中创建的直接日志
实验:rm -rf .git/logs, git reflog为空。
不管怎样,即使你丢失了所有标签、所有分支和logs文件夹中的所有日志,提交对象仍然在.git/objects目录中,所以如果你发现所有悬挂的提交,你可以重建树:git fsck
其他回答
下面是Pro Git书中对reflog的解释:
One of the things Git does in the background while you’re working away is keep a reflog — a log of where your HEAD and branch references have been for the last few months. You can see your reflog by using git reflog: $ git reflog 734713b... HEAD@{0}: commit: fixed refs handling, added gc auto, updated d921970... HEAD@{1}: merge phedders/rdocs: Merge made by recursive. 1c002dd... HEAD@{2}: commit: added some blame and merge stuff 1c36188... HEAD@{3}: rebase -i (squash): updating HEAD 95df984... HEAD@{4}: commit: # This is a combination of two commits. 1c36188... HEAD@{5}: rebase -i (squash): updating HEAD 7e05da5... HEAD@{6}: rebase -i (pick): updating HEAD Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. And you can specify older commits with this data, as well.
reflog命令还可以用于删除reflog中太旧的表项或过期表项。来自reflog的官方Linux内核Git文档:
expire子命令用于删除旧的reflog表项。 要从reflog中删除单个条目,使用delete子命令并指定确切的条目(例如git reflog delete master@{2})。
Git日志显示了从refs(头,标签,远程)访问的提交日志。 Git reflog记录了任何时候在你的repo中被引用或被引用的所有提交。
这就是为什么当你执行“破坏性”操作(比如删除一个分支)时使用git reflog(默认90天后修剪的本地记录),以获得该分支引用的SHA1。 参见git配置:
gc.reflogexpire
gc.<pattern>.reflogexpire
Git reflog expire删除比这个时间更老的reflog条目;默认为90天。 “<模式>”(例如:"refs/stash"),该设置只适用于匹配<pattern>的引用。
Git reflog通常被称为“您的安全网”
以防万一,一般的建议,当git日志没有显示你要找的东西时,是:
“保持冷静,使用git reflog”
同样,reflog是SHA1的本地记录。 与git日志相反:如果你将你的回购推到上游的回购,你会看到相同的git日志,但不一定是相同的git reflog。
我对此也很好奇,我想详细阐述和总结一下:
git log shows a history of all your commits for the branch you're on. Checkout a different branch and you'll see a different commit history. If you want to see you commit history for all branches, type git log --all. git reflog shows a record of your references as Cupcake said. There is an entry each time a commit or a checkout it done. Try switching back and forth between two branches a few times using git checkout and run git reflog after each checkout. You'll see the top entry being updated each time as a "checkout" entry. You do not see these types of entries in git log.
引用: http://www.lornajane.net/posts/2014/git-log-all-branches
我喜欢把git log和reflog之间的区别看作是私有记录和公共记录之间的区别。
私人vs公共
使用git reflog,它会跟踪您在本地所做的所有事情。你答应了吗?Reflog跟踪它。你硬复位了吗?Reflog跟踪它。你修改commit了吗?Reflog跟踪它。你在本地做的所有事情,在reflog中都有一个条目。
这对对数来说不成立。如果修改了提交,日志只显示新的提交。如果您执行重置并回跳历史记录中的一些提交,那么您跳过的那些提交将不会显示在日志中。当您将更改推送给另一个开发人员或GitHub或类似的东西时,只会显示日志中跟踪的内容。对于另一个开发人员来说,这看起来就像从未发生过重置或修正。
圆木经过打磨。这是一种宝石。
所以,是的,我喜欢“私人vs公共”的类比。或者一个更好的原木vs reflog类比是“抛光vs宝石”。reflog显示了你所有的尝试和错误。日志只是展示了你工作历史的一个干净的版本。
看看这张图片来强调这一点。自存储库初始化以来,发生了许多修改和重置。这一切都体现在重新发行上。然而,log命令使它看起来好像只有一次针对repo的提交:
回到“安全网”的概念
此外,由于reflog会跟踪你修改过的东西并提交你重置的东西,它允许你返回并找到那些提交,因为它会给你提交id。假设您的存储库没有清除旧提交,这允许您复活日志中不再可见的项。这就是为什么当人们需要拿回他们认为自己无意中丢失的东西时,reflog有时会拯救他们的皮肤。
实际上,reflog是
git log -g --abbrev-commit --pretty=oneline
所以答案应该是:这是一个具体的情况。
推荐文章
- 如何将git配置存储为存储库的一部分?
- 如何修改GitHub拉请求?
- 如何在Github和本地删除最后n次提交?
- 我如何调试git/git-shell相关的问题?
- 错误:无法使用rebase进行拉取:您有未分阶段的更改
- Git隐藏未缓存:如何把所有未分期的变化?
- 真实的恶魔
- 如何从另一个分支获得更改
- Git:权限被拒绝(publickey)致命-无法从远程存储库读取。克隆Git存储库时
- git reflog和log有什么区别?
- git推挂在Total line之后
- 重命名git子模块
- 结合Git存储库的前两次提交?
- Xcode 6 gitignore文件应该包括什么?
- 我如何从现有回购的分支创建一个新的GitHub回购?