git reflog和log有什么区别?


158

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

Answers:


221

git log显示当前的HEAD及其祖先。也就是说,它将打印HEAD指向的提交,然后打印其父级,父级,依此类推。通过递归查找每个提交的父对象,它遍历回购协议的祖先。

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

git reflog根本不遍历HEAD的血统。reflog是HEAD指向的提交的有序列表:它是您的存储库的撤消历史记录。reflog不是回购本身的一部分(它与提交本身分开存储),并且不包含在push,fetch或clone中;它纯粹是本地的。

撇开:了解reflog意味着一旦提交,您就不会真正丢失回购中的数据。如果您不小心重置为较旧的提交,或错误地进行了基准调整,或任何其他在视觉上“删除”提交的操作,则可以使用reflog查看以前的位置,然后git reset --hard返回该ref来恢复以前的状态。请记住,引用不仅仅意味着提交,还意味着它背后的整个历史。


26
请注意:您有时可能会丢失数据,因为reflog条目不会永久存在-在某些情况下会清除它们。请参阅此答案git-refloggit-gc的文档。通常,如果破坏性操作不超过2周前,则很可能是安全的。
mcmlxxxvi 2015年

@mcmlxxxvi我有两个本地文件夹用于同一仓库,可以合并两个文件夹的引用日志吗?
Tmx

@Tmx,我不太了解您的情况- 同一回购的两个本地文件夹是什么意思?如果您有两个相同的仓库,它们是最新的,并且您想“合并”它们的编辑历史,则.git/logs/refs/<branch>条目的格式为<old_rev> <new_rev> [...] <timestamp> [...]。您可以尝试按时间戳进行串联和排序。但是,有些行new_rev可能与下一行不匹配old_rev,在这种情况下,我怀疑reflog将无效。然后,您可以尝试插入伪造的条目来“修复”序列,但是对我来说似乎太麻烦了。
mcmlxxxvi

62
  • git log 显示可从ref(头,标签,远程)访问的提交日志
  • git reflog是一个记录是在任何时间在你的回购中引用的所有提交的。

这就是为什么在执行“破坏性”操作(如删除分支)时会使用(默认情况下90天后会删除git reflog本地记录),以便取回该分支引用的SHA1的原因。
git config

gc.reflogexpire
gc.<pattern>.reflogexpire

git reflogexpire删除比这个时间更旧的reflog条目;默认为90天。中间
带有“ <pattern>”(例如“ refs/stash”)的设置仅适用于匹配的裁判<pattern>

安全网

git reflog通常被称为“ 您的安全网

万一遇到麻烦,当git log不能向您显示所需内容时,通常的建议是:

保持冷静和使用git reflog

保持冷静

同样,reflog是SHA1的本地记录。
与之相反git log:如果将您的存储库推送到上游存储库,则会看到相同的内容git log,但不一定相同git reflog


14

这是Pro Git书中解释reflog

在您外出工作时,Git在后台执行的操作之一是保留reflog-记录最近几个月HEAD和分支引用的位置。

您可以使用来查看您的reflog 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

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

reflog命令还可用于删除条目或使reflog中的条目过期。从官方Linux Kernel Git文档中获得reflog

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

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


但是git log提供的信息不一样吗?抱歉,如果看起来很明显,我对GIT还是很陌生,想在我的第一个OMG之前获得一些基础知识。
Noich 2013年

2
Git日志是您的提交的记录。正如Pro Git所指出的那样,刷新日志记录了您的引用(基本上是分支指针和HEAD指针)以及它们所指向的提交。那有意义吗?另外,log还可以向您显示reflog信息,但是您必须传递一个特殊的选项标志作为参数--walk-reflogs

3
另外,由于您是Git初学者,因此我强烈建议您阅读Pro Git书,这是我学习有关Git的大部分知识的方式。我建议第1-3和6-6.5章。我也强烈建议您学习如何以交互方式和非交互方式进行基础调整。

8

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

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

  2. git reflog显示纸杯蛋糕所说的您的推荐记录。每次提交或签出时都有一个条目。尝试使用两次在两个分支之间来回切换,git checkoutgit reflog在每次签出后运行。您会看到每次更新的顶部条目都是“结帐”条目。您不会在中看到这些类型的条目git log

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


1

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

私人与公共

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

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

日志已打磨。刷新日志是简单的。

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

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

日志已打磨。 Reflog是单调的。

回到“安全网”的想法

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


-6

实际上,reflog是以下内容的别名

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

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


9
在中git log-g是的缩写--walk-reflogs。因此,这并不能解释任何事情。
阿德里安W
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.