reflog能查到被reset--hard、rebase或merge--abort丢弃但未被gc清理(默认30天)的提交,它只记录本地head及分支等引用的移动历史,不推送、非共享、按时间倒序存储,仅反映本机操作。

reflog 能查到哪些“消失”的提交?
reflog 记录的是本地分支、HEAD、stash 等引用的每次更新,哪怕提交被 reset --hard、rebase 或 merge --abort 丢弃,只要没被 Git 垃圾回收(默认 30 天),它就还在。关键点在于:reflog 是本地的、非推送的、按时间倒序记录的。
常见误判是以为 reflog 能查到别人改了什么——不能。它只反映你本机的操作历史。执行 git reflog 后看到的 HEAD@{0}、HEAD@{1} 等,对应的就是你最近一次、上一次……的 HEAD 指向。
-
git reflog --date=iso加时间戳,便于和系统日志对齐 -
git reflog -n 20 origin/main可查远程跟踪分支的本地更新记录(比如git fetch时的更新) - 如果某次
git checkout后立刻git reset --hard,reflog 里会保留这两步,但git log里已不可见
如何用 reflog + 系统日志交叉验证变更时间?
Git reflog 给出的是 Git 层操作时间,系统日志(如 /var/log/auth.log 或 journalctl --since "2 hours ago")给出的是用户登录、SSH 登录、sudo 执行等系统级事件时间。两者时间戳对齐,才能确认“谁在什么时候做了什么”。
例如:reflog 显示 HEAD@{3}: reset: moving to HEAD~2 发生在 2024-05-22 14:23:11,而 journalctl -u sshd --since "2024-05-22 14:20:00" 显示同一时刻有 Accepted password for alice,就能锁定操作者。
- Linux 下优先用
journalctl --since "1 hour ago" | grep git查含 git 关键词的命令行记录(需启用 command logging) - macOS 可查
log show --predicate 'eventMessage contains "git"' --last 1h - 注意系统时区与 Git 时区是否一致,避免时间偏移导致错配
reflog 不可靠时,还能靠什么找丢失的提交?
reflog 清空、GC 已运行、或仓库被 clone 过多次后,reflog 就失效了。这时得依赖更底层的线索:
-
git fsck --lost-found扫描悬空对象,输出散列值;再用git show <hash></hash>或git log --oneline <hash>^!</hash>查看内容 - 检查
.git/objects/目录下文件修改时间(find .git/objects -type f -newermt "2024-05-22 14:00" | head -20),Git 对象写入时间往往接近 commit 时间 - IDE 缓存(如 VS Code 的
.vscode/.history、IntelliJ 的 Local History)可能保留未 commit 的修改快照 - 如果用了 CI/CD,构建日志里的
git rev-parse HEAD输出可能是唯一留存的 hash 线索
审计追踪时最容易忽略的 reflog 边界
reflog 默认只记录 HEAD 和当前分支,不自动记录其他分支的移动。比如你在 feature/a 上 commit,然后 checkout main,reflog 中 feature/a 的更新就停在那了——除非你显式操作它。
-
git reflog feature/a才能查该分支自己的 reflog,不是git reflog默认显示的 - 克隆新仓库时,reflog 是空的;所有记录从第一次本地操作开始,旧历史不会带过来
-
git gc默认保留 90 天的 reflog 条目,但gc.reflogExpire配置可被覆盖,有些 CI 环境会设为 0
真正难的不是找到那条 reflog 记录,而是判断它对应的是人为操作、脚本触发,还是 IDE 自动保存——这得结合命令上下文、终端历史、以及有没有 git commit -m "auto" 这类线索一起看。











