Skip to content

git reflog —— 最后的安全网

git reflog(Reference Log,引用日志)记录了 HEAD 的所有移动历史,是 Git 中最强大的"后悔药"。即使你执行了 reset --hard、删除了分支,也能通过 reflog 找回丢失的提交。

reflog 的工作原理

每当 HEAD 移动时(提交、切换分支、reset、rebase 等),Git 都会在 reflog 中记录一条日志。

reflog 存储位置:

  • .git/logs/HEAD:HEAD 的 reflog
  • .git/logs/refs/heads/<branch>:每个分支的 reflog
bash
# 查看 HEAD 的 reflog
cat .git/logs/HEAD

# 格式:
# <旧 SHA-1> <新 SHA-1> <用户信息> <时间戳> <操作描述>
# 0000... abc123 Zhang San <zhang@ex.com> 1704067200 +0800 commit (initial)
# abc123 def456 Zhang San <zhang@ex.com> 1704067260 +0800 commit: feat: 功能A

查看与解读 reflog

bash
# 查看 HEAD 的 reflog
git reflog
git reflog HEAD    # 等价

# 输出示例:
# abc123 HEAD@{0}: reset: moving to HEAD~3      ← 最近的操作(刚才执行的 reset)
# def456 HEAD@{1}: commit: feat: 添加功能C       ← reset 之前的状态(要恢复的)
# ghi789 HEAD@{2}: commit: feat: 添加功能B
# jkl012 HEAD@{3}: commit: feat: 添加功能A
# mno345 HEAD@{4}: checkout: moving from develop to main
# pqr678 HEAD@{5}: commit: fix: 修复 bug

输出格式解读:

  • abc123:操作后 HEAD 指向的 SHA-1
  • HEAD@{0}:reflog 索引(0 是最新的)
  • reset: moving to HEAD~3:操作描述
bash
# 查看特定分支的 reflog
git reflog show main
git reflog show feature/login

# 查看所有引用的 reflog
git reflog --all

# 限制显示数量
git reflog -10

# 显示时间信息
git reflog --date=relative   # 相对时间(如 "2 hours ago")
git reflog --date=iso        # ISO 格式时间

通过 reflog 恢复丢失的提交

场景1:误执行了 reset --hard

bash
# 误操作:reset 到 3 个提交前
git reset --hard HEAD~3

# 查看 reflog 找到 reset 前的状态
git reflog
# abc123 HEAD@{0}: reset: moving to HEAD~3
# def456 HEAD@{1}: commit: feat: 功能C   ← 这是 reset 前的 HEAD

# 恢复到 reset 前的状态
git reset --hard def456
# 或者使用 HEAD@{1} 语法
git reset --hard HEAD@{1}

场景2:误删了提交后的操作

bash
# 找到丢失的提交
git reflog | grep "feat: 重要功能"
# xyz789 HEAD@{5}: commit: feat: 重要功能

# 方案1:直接重置到该提交
git reset --hard xyz789

# 方案2:创建新分支保存该提交
git branch recovered-branch xyz789
git switch recovered-branch

通过 reflog 恢复删除的分支

bash
# 误删了 feature/important 分支
git branch -D feature/important

# 找到该分支最后一次 commit 的 SHA-1
git reflog | grep "feature/important"
# abc123 HEAD@{3}: checkout: moving from feature/important to main
# def456 HEAD@{4}: commit: feat: 重要功能  ← 该分支的最后提交

# 找到后重建分支
git branch feature/important abc123
# 或
git switch -c feature/important abc123

更精确的方法:

bash
# 查看分支专属的 reflog(即使分支已删除,记录还在一段时间内)
git reflog show feature/important
# error: 已删除则无法查看

# 替代:搜索所有 reflog
git reflog | grep "feature/important"

reflog 的过期时间配置

reflog 不会永远保留,Git 会定期清理过期记录:

bash
# 查看过期配置
git config --get gc.reflogExpire         # 默认 90 天
git config --get gc.reflogExpireUnreachable  # 默认 30 天(不可达对象)
配置项默认值说明
gc.reflogExpire90 天从主分支可达的提交的 reflog 保留时间
gc.reflogExpireUnreachable30 天不可达提交的 reflog 保留时间

修改过期时间:

bash
# 延长 reflog 保留时间(更安全)
git config --global gc.reflogExpire "180 days"
git config --global gc.reflogExpireUnreachable "60 days"

# 永不过期(不推荐,占用空间)
git config --global gc.reflogExpire never
git config --global gc.reflogExpireUnreachable never

手动清理 reflog:

bash
# 清理所有过期的 reflog
git reflog expire --expire=now --all

# 清理不可达对象(配合 reflog expire 使用)
git gc --prune=now

reflog 的使用场景

bash
# 查找某个时间点的 HEAD 状态
git reflog --date=iso | grep "2026-03-01"

# 恢复到昨天某个时间的状态
git reset --hard HEAD@{yesterday}
git reset --hard HEAD@{"2 days ago"}
git reset --hard HEAD@{"2026-03-01 10:00:00"}

# 查看最近 24 小时内的所有操作
git reflog --since="24 hours ago"

reflog vs git log

对比项git loggit reflog
显示内容提交历史(DAG)HEAD 移动历史
包含操作只有提交提交、reset、checkout、rebase 等
持久性永久(在引用可达时)有过期时间(默认 90 天)
适用场景查看项目历史找回丢失操作
范围所有人只有本地操作记录

重要:reflog 是本地的,克隆后的新仓库没有原仓库的 reflog。

最佳实践

  1. 遇到问题,先查 reflog:几乎所有"丢失"的提交都能在 reflog 中找到

  2. 操作前查看 reflog 序号:危险操作前记录当前 HEAD@{0} 的值,便于回滚

  3. 不要手动清理 reflog:让 Git 自动管理,避免过早失去安全网

  4. 理解 reflog 的时效性:不可达对象只保留 30 天,重要数据及时创建分支或标签

bash
# 危险操作前的好习惯
git reflog         # 记下当前 HEAD@{0} 的哈希
git tag backup-before-rebase  # 创建临时标签作为保险

# 操作后如果出错
git reset --hard backup-before-rebase
git tag -d backup-before-rebase  # 清理临时标签

总结

操作命令
查看 refloggit reflog
查看含时间的 refloggit reflog --date=iso
恢复到某个 reflog 点git reset --hard HEAD@{n}
从 reflog 恢复分支git branch <name> <sha>
搜索特定操作git reflog | grep "关键词"

git reflog 是 Git 学习者最应该知道的"后悔药"。记住:在 Git 中,只要提交过,几乎总能找回——前提是 reflog 还未过期。