文章目录
- 原因分析
- 1. `git log` 只能显示 **可达的** 提交
- 2. `git reflog` 记录所有引用的变更
- 常见导致 `git log` 看不到提交的原因
- 1. `git reset` 操作
- 2. `git rebase` 操作
- 3. 分支删除
- 4. `git commit --amend`
- 5. 垃圾回收(GC)*
- 如何恢复 `git log` 看不到的提交?
- 总结
在 Git 中,有些提交记录只能通过
git reflog
查看,而
git log
无法显示。这种情况通常是因为提交历史已经发生了某种形式的“变更”,导致这些提交不再是当前分支或其他引用(如标签、远程分支)的可达提交。
原因分析
1. git log
只能显示 可达的 提交
git log
的工作机制是基于 可达性(reachability)原则。它只会显示从当前分支 HEAD 或其他引用(如标签、远程分支)可达的提交。所谓“可达”,指的是从某个提交开始,通过提交的父子关系可以沿链条一直追溯到该提交。
- 如果一个提交从当前分支的链条上“消失”了(例如通过
git reset
、git rebase
等操作导致提交链被重写或分支被删除),那么这些提交将不再被视为“可达”。 git log
不会显示这些提交,因为它只展示当前分支上的提交历史。
2. git reflog
记录所有引用的变更
git reflog
不同,它记录的是 本地引用(HEAD、分支等)的所有变化,无论提交是否可达。因此,git reflog
可以看到很多“隐藏”的提交,包括被 git reset
或 git rebase
覆盖掉的提交、误操作后丢失的提交,甚至是分支被删除后的提交。
只要你在本地进行过操作,git reflog
会记录:
- 提交、合并、拉取等操作。
- 分支的切换(
checkout
)。 - 重置(
reset
)或变基(rebase
)。 - HEAD 指针的移动。
即便你删除了一个分支或者重置了当前分支,git reflog
依然能显示这些操作的历史。
常见导致 git log
看不到提交的原因
1. git reset
操作
git reset
是一种常用的操作,用于回滚分支到某个特定的提交。它有三种模式:--soft
、--mixed
和 --hard
。其中,git reset --hard
不仅会回滚分支指针,还会重置工作目录。
如果你使用了 git reset --hard
回退到某个较早的提交,那么中间的提交将不再被当前分支所引用,也就是说,这些提交就 不可达 了。在 git log
中你将看不到这些提交,但 git reflog
依然记录了它们。
示例:
git reset --hard HEAD~3 # 回滚到3个提交之前
在执行这个操作后,最近的 3 次提交虽然丢失了,但可以通过 git reflog
找回。
2. git rebase
操作
git rebase
是一个用于重写提交历史的操作,它会将提交重新应用到新的基点上。过程中,原有的提交会被替换为新的提交,这样就导致了原来的提交从分支历史中“消失”。
即使 git log
不再显示这些被替换的提交,它们仍然会保留在 git reflog
中,直到这些提交被垃圾回收(GC)。
3. 分支删除
当你删除一个分支时,该分支上最后的提交不再被任何引用指向,导致这些提交成为“悬空”提交(dangling commit)。这些提交虽然无法在 git log
中看到,但在 git reflog
中,分支的删除和之前的提交历史仍然可以被追踪。
示例:
git branch -d feature_branch
删除 feature_branch
后,你不能再通过 git log
看到该分支的提交记录,但 git reflog
仍然会记录你删除该分支的操作。
4. git commit --amend
使用 git commit --amend
修改最近一次提交时,实际上会创建一个新的提交,原来的提交被替换掉。git log
只能显示修改后的提交,而 git reflog
可以看到原始提交及修改过程。
5. 垃圾回收(GC)*
Git 的垃圾回收机制(git gc
)会清理那些没有被引用且过期的对象。当一个提交没有任何分支、标签等引用指向它时,经过一段时间后,这些提交可能会被垃圾回收从 Git 数据库中删除。不过在被 GC 删除之前,git reflog
仍然能看到这些提交。
如何恢复 git log
看不到的提交?
如果你在 git log
中看不到某个提交,但它在 git reflog
中依然存在,你可以通过以下方法恢复这些提交:
-
使用
git reset
恢复到某个提交- 在
git reflog
中找到想要恢复的提交哈希值。 - 然后使用
git reset
或git checkout
恢复。
例如:
git reflog # 找到需要恢复的提交,假设是 abc1234 git reset --hard abc1234
- 在
-
创建一个新的分支指向该提交
如果你不想影响当前的分支,可以创建一个新的分支指向丢失的提交:git branch recovered-branch abc1234
这样你就能在新的分支上查看并操作该提交的历史。
总结
git log
只显示当前分支上的 可达提交,即有分支或标签引用的提交。git reflog
记录了所有本地引用(如HEAD
)的变化,能够显示git log
看不到的提交,尤其是那些通过reset
、rebase
、分支删除等操作被“丢失”的提交。- 可以通过
git reflog
找到丢失的提交,并通过git reset
或创建新分支来恢复这些提交。
git reflog
是一个非常有用的工具,特别是在你需要恢复意外丢失的提交时。
结束语
Flutter是一个由Google开发的开源UI工具包,它可以让您在不同平台上创建高质量、美观的应用程序,而无需编写大量平台特定的代码。我将学习和深入研究Flutter的方方面面。从基础知识到高级技巧,从UI设计到性能优化,欢饮关注一起讨论学习,共同进入Flutter的精彩世界!