git reflog和log有什么区别?

时间:2013-07-25 12:13:49

标签: git git-log git-reflog

手册页说日志显示提交日志,reflog管理reflog信息。什么是reflog信息以及日志没有什么?日志似乎更加详细。

7 个答案:

答案 0 :(得分:182)

git log显示当前的HEAD及其祖先。也就是说,它会将提交HEAD点打印到其父级,其父级,依此类推。它通过递归查找每个提交的父级来遍历repo的祖先。

(实际上,某些提交有多个父级。要查看更具代表性的日志,请使用git log --oneline --graph --decorate之类的命令。)

git reflog根本没有穿越HEAD的祖先。 reflog是HEAD指向的提交的有序列表:它是您的repo的撤消历史记录。 reflog不是repo本身的一部分(它单独存储在提交本身中),并不包含在推送,提取或克隆中;它纯粹是本地的。

除此之外:了解reflog意味着一旦提交了repo,您​​就无法真正丢失数据。如果您不小心重置为较旧的提交,或错误地重新绑定,或者任何其他可视“删除”提交的操作,您可以使用reflog查看之前的位置,并git reset --hard返回该ref以恢复之前的状态。请记住,refs不仅意味着提交,还意味着它背后的整个历史。

答案 1 :(得分:47)

  • git log显示可从refs(head,tags,remotes)
  • 访问的提交日志
  • git reflog是您在回购协议中随时引用的所有提交的记录

这就是为什么git reflog(默认情况下在90天后修剪的本地记录)用于执行“破坏性”#34;操作(比如删除分支),以便返回该分支引用的SHA1 见git config

gc.reflogexpire
gc.<pattern>.reflogexpire
  

git reflog expire删除比此时更旧的reflog条目;默认为90天   使用&#34; <pattern>&#34; (例如&#34; refs/stash&#34;)中间设置仅适用于与<pattern>匹配的引用。

safety net

git reflog通常被称为&#34; your safety net&#34;

如果遇到问题,当git log没有显示您要查找的内容时,一般建议是:

  

&#34; Keep calm and use git reflog&#34;

keep calm

同样,reflog是SHA1的本地录音 与git log相反:如果您将回购推送到upstream repo,则会看到相同的git log,但不一定相同git reflog

答案 2 :(得分:12)

这是explanation of reflog from the Pro Git book

  

当你工作的时候,Git在后台做的事情之一是保留一个reflog - 记录过去几个月HEAD和分支引用的位置。

     

您可以使用git reflog

查看您的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
     

每次因任何原因更新分支提示时,Git会在此临时历史记录中为您存储该信息。您也可以使用此数据指定较旧的提交。

reflog命令也可用于从reflog中删除过旧的条目或过期条目。来自official Linux Kernel Git documentation for reflog

  

子命令expire用于修剪旧的reflog条目。

     

要从reflog中删除单个条目,请使用子命令delete并指定确切的条目(例如git reflog delete master@{2})。

答案 3 :(得分:4)

我对此也很好奇,只是想详细说明一下:

  1. git log --all显示您所在分支的所有提交的历史记录。签出不同的分支,您将看到不同的提交历史记录。如果要查看为所有分支提交历史记录,请键入git reflog

  2. git checkout显示了您的参考记录,如Cupcake所说。每次提交或结账都有一个条目。尝试使用git reflog在两个分支之间来回切换几次,并在每次结帐后运行git log。您每次都会看到顶部条目更新为&#34;结帐&#34;条目。您在SELECT s.Country, m.Country FROM tbl_country AS s cross JOIN tbl_country AS m

  3. 中看不到这些类型的条目

    参考文献: http://www.lornajane.net/posts/2014/git-log-all-branches

答案 4 :(得分:3)

我想将git log和reflog之间的区别视为私有记录和公共记录之间的区别。

私人vs.公共

使用git reflog,它可以跟踪您在本地完成的所有操作。你犯了吗? Reflog跟踪它。您是否进行了硬重置? Reflog跟踪它。您amend a commit吗? Reflog跟踪它。您在本地完成的所有操作,在reflog中都有相应的条目。

对于日志而言并非如此。如果您修改提交,则日志仅显示新提交。如果您重置并跳过历史记录中的一些提交,则您跳过的那些提交将不会显示在日志中。当您将更改推送给其他开发人员或GitHub或类似的内容时,只会显示日志中跟踪的内容。对于另一位开发人员来说,看起来好像从未发生过重置或从未发生过修改。

原木已打磨。 reflog是简单的。

是的,我喜欢“私人与公共”的比喻。也许更好的log vs reflog比喻是“抛光vs浮雕”。刷新日志显示您的所有尝试和错误。日志仅显示您的工作历史记录的原始版本。

看一下这张图片以强调要点。自存储库初始化以来,发生了许多修改和重置。 reflog显示了所有内容。但是log命令使它看起来好像只有一次针对仓库的提交:

Log is polished. Reflog is lapidary.

回到“安全网”的想法

此外,由于刷新日志跟踪您所做的修改并向您提交reset,因此它可以让您返回并查找那些提交,因为它将为您提供提交ID。假设您的存储库尚未清除旧提交,那么您可以重新启动日志中不再可见的项目。这就是当某些人需要找回他们认为自己无意中丢失的东西时,有时候它会最终挽救皮肤的方式。

答案 5 :(得分:0)

实际上,reflog是它的别名

 git log -g --abbrev-commit --pretty=oneline

所以答案应该是:这是特定情况。

答案 6 :(得分:0)

git log从当前的 HEAD 开始,即指向某个分支(例如 master )或直接提交对象(sha代码),并且实际使用提交对象内部存在的 parent 字段在提交后实际扫描 .git / objects 目录提交内的对象文件。

实验:直接将HEAD指向某些提交:git checkout a721d(创建新的存储库并用提交和分支填充。用您的一些提交代码替换a721d)并删除分支{{1 }} 现在rm .git/refs/heads/*将只显示 HEAD 及其提交祖先。

另一方面,

git reflog使用的是在 .git / logs

内部创建的直接日志

实验:git log --onelinerm -rf .git/logs为空。

无论如何,即使您丢失了所有标签,所有分支和所有日志以及日志文件夹中的内容,提交对象也位于 .git / objects 目录中,因此,如果您找到所有悬空的提交,则可以重构树:git reflog