繁体   English   中英

git reflog 和 log 有什么区别?

[英]What's the difference between git reflog and log?

手册页说 log 显示提交日志,而 reflog 管理 reflog 信息。 reflog 信息究竟是什么,它有哪些日志没有的信息? 日志似乎要详细得多。

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

  • git log显示可从 refs (heads, tags, remotes) 访问的提交日志
  • git reflog是任何时候在您的 repo 中引用或引用的所有提交的记录

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

gc.reflogexpire
gc.<pattern>.reflogexpire

git reflog expire 删除早于这个时间的 reflog 条目; 默认为 90 天。
使用“ <pattern> ”(例如“ refs/stash ”)在中间,该设置仅适用于与<pattern>匹配的引用。

安全网

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

万一出现问题,一般建议,当 git log 没有显示您正在寻找的内容时,是:

保持冷静,使用git reflog

保持冷静

同样,reflog 是 SHA1 的本地记录。
git log :如果你将你的仓库推送到上游仓库,你会看到相同的git log ,但不一定是相同的git reflog

这是Pro Git 书中对reflog解释

当你在工作时,Git 在后台做的一件事就是保留一个 reflog——一个记录你的 HEAD 和分支引用在过去几个月里的位置的日志。

您可以使用git 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 中删除太旧的条目或使条目过期。 来自reflog官方 Linux 内核 Git 文档

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

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

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

  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

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

私人与公共

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

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

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

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

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

日志是抛光的。 Reflog 是宝石般的。

回到“安全网”的想法

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

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/logsgit reflog为空。

无论如何,即使您丢失了日志文件夹中的所有标签、所有分支和所有日志,提交对象也在.git/objects目录中,因此如果您发现所有悬空提交,您可以重建树: git fsck

实际上,reflog 是一个别名

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM