手册页说log显示提交日志,reflog管理reflog信息。究竟什么是reflog信息,它有什么日志没有的?日志似乎更详细。
当前回答
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和reflog之间的区别看作是私有记录和公共记录之间的区别。
私人vs公共
使用git reflog,它会跟踪您在本地所做的所有事情。你答应了吗?Reflog跟踪它。你硬复位了吗?Reflog跟踪它。你修改commit了吗?Reflog跟踪它。你在本地做的所有事情,在reflog中都有一个条目。
这对对数来说不成立。如果修改了提交,日志只显示新的提交。如果您执行重置并回跳历史记录中的一些提交,那么您跳过的那些提交将不会显示在日志中。当您将更改推送给另一个开发人员或GitHub或类似的东西时,只会显示日志中跟踪的内容。对于另一个开发人员来说,这看起来就像从未发生过重置或修正。
圆木经过打磨。这是一种宝石。
所以,是的,我喜欢“私人vs公共”的类比。或者一个更好的原木vs reflog类比是“抛光vs宝石”。reflog显示了你所有的尝试和错误。日志只是展示了你工作历史的一个干净的版本。
看看这张图片来强调这一点。自存储库初始化以来,发生了许多修改和重置。这一切都体现在重新发行上。然而,log命令使它看起来好像只有一次针对repo的提交:
回到“安全网”的概念
此外,由于reflog会跟踪你修改过的东西并提交你重置的东西,它允许你返回并找到那些提交,因为它会给你提交id。假设您的存储库没有清除旧提交,这允许您复活日志中不再可见的项。这就是为什么当人们需要拿回他们认为自己无意中丢失的东西时,reflog有时会拯救他们的皮肤。
git日志显示当前HEAD和它的祖先。也就是说,它打印HEAD指向的提交对象,然后是它的父对象,它的父对象,等等。它通过递归查找每个提交的父节点,遍历回购的祖先节点。
(在实践中,一些提交有多个父文件。要查看更有代表性的日志,可以使用git log——oneline——graph——decoration这样的命令。)
git reflog根本不遍历HEAD的祖先。reflog是HEAD所指向的一个有序的提交列表:它是你的repo的撤销历史。reflog不是repo本身的一部分(它被单独存储到提交本身),并且不包括在push、fetch或clone中;这纯粹是本地的。
另外:理解reflog意味着一旦repo被提交,就不会真正丢失数据。如果你不小心重置到旧的提交,或者错误地重设基准,或者任何其他视觉上“删除”提交的操作,你可以使用reflog来查看之前的位置,然后git重置——硬回到那个引用来恢复之前的状态。记住,引用不仅意味着提交,还意味着它背后的整个历史。
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。
实际上,reflog是
git log -g --abbrev-commit --pretty=oneline
所以答案应该是:这是一个具体的情况。
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
推荐文章
- 如何将git配置存储为存储库的一部分?
- 如何修改GitHub拉请求?
- 如何在Github和本地删除最后n次提交?
- 我如何调试git/git-shell相关的问题?
- 错误:无法使用rebase进行拉取:您有未分阶段的更改
- Git隐藏未缓存:如何把所有未分期的变化?
- 真实的恶魔
- 如何从另一个分支获得更改
- Git:权限被拒绝(publickey)致命-无法从远程存储库读取。克隆Git存储库时
- git reflog和log有什么区别?
- git推挂在Total line之后
- 重命名git子模块
- 结合Git存储库的前两次提交?
- Xcode 6 gitignore文件应该包括什么?
- 我如何从现有回购的分支创建一个新的GitHub回购?