201

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

4

7 回答 7

265

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 不仅意味着提交,还意味着它背后的整个历史。

于 2013-07-25T14:01:13.077 回答
80
  • git log显示可从 refs 访问的提交日志(heads、tags、remote)
  • git reflog是您的存储库中随时引用或曾经引用的所有提交的记录。

这就是为什么git reflog(默认情况下在 90 天后修剪的本地记录)在执行“破坏性”操作(如删除分支)时使用的原因,以便取回该分支引用的 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:如果你将你的 repo 推送到上游 repo,你会看到相同的git log,但不一定相同git reflog

于 2013-07-25T13:47:47.877 回答
19

这是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})。

于 2013-07-25T12:33:54.487 回答
12

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

  1. git log显示您所在分支的所有提交的历史记录。签出一个不同的分支,你会看到不同的提交历史。如果您想查看所有分支的提交历史记录,请输入git log --all.

  2. git reflog正如 Cupcake 所说,显示了您的参考记录。每次提交或签出时都会有一个条目。尝试在两个分支之间来回切换几次,并在每次结帐后git checkout运行。git reflog您会看到每次更新的顶部条目作为“结帐”条目。您在 中看不到这些类型的条目git log

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

于 2015-08-19T09:46:17.387 回答
8

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

私人与公共

使用 git reflog,它可以跟踪您在本地所做的一切。你答应了吗?Reflog 跟踪它。你做了硬重置吗?Reflog 跟踪它。你修改了一个提交吗?Reflog 跟踪它。您在本地所做的一切,在 reflog 中都有一个条目。

这不适用于日志。如果你修改了一个提交,日志只显示新的提交。如果您进行重置并跳过历史记录中的一些提交,那么您跳过的那些提交将不会显示在日志中。当您将更改推送给其他开发人员或GitHub或类似的东西时,只会显示日志中跟踪的内容。对于另一位开发人员来说,看起来重置从未发生过,或者修改从未发生过。

日志被抛光。reflog 是宝石的。

所以,是的,我喜欢“私人与公共”的类比。或者也许更好的日志与 reflog类比是“抛光与宝石”。reflog 显示了您所有的试验和错误。该日志仅显示您的工作历史的干净和完善的版本。

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

日志被抛光。 Reflog 是宝石级的。

回到“安全网”的想法

此外,由于 reflog 会跟踪您修改的内容并提交您reset,它允许您返回并找到这些提交,因为它会为您提供提交 ID。假设您的存储库尚未清除旧提交,这允许您恢复日志中不再可见的项目。这就是当某人需要找回他们认为无意中丢失的东西时,reflog 有时最终会挽救他们的皮肤的方式。

于 2020-06-12T10:53:32.577 回答
3

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

实验:将 HEAD 直接指向某个提交:(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

于 2020-07-31T20:44:21.593 回答
-8

实际上, reflog 是

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

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

于 2018-07-03T19:26:20.133 回答