首页/开发/Git 与协作速查/reflog 过期与对象清理
进阶与大仓实践69 条

reflog 过期与对象清理

reflog 记录引用变动,是误操作的恢复通道;确认不再需要恢复时(如完成历史重写),过期 reflog 并 gc 才能让旧对象真正被回收。

Git 与协作速查开发更新于 2026-10-13

reflog expire 是什么

reflog 记录每个引用的移动历史,是误提交、误 reset、误 rebase 后的恢复通道:只要记录在,被丢开的提交就被视为受保护、不会被回收。git reflog expire 把过期记录清掉,再配合 git gc --prune 才能让旧对象真正消失。它常出现在历史重写(filter-branch、filter-repo)收尾:确认现场不再需要回退后,才执行过期与回收。

基本信息

过期命令git reflog expire --expire=now --all
回收命令git gc --prune=now
默认窗口条目默认保留 90 天,不可达条目更短(约 30 天)
恢复依据git reflog 找到旧位置后用 reset 或 hash 回退
作用范围仅本地仓库,不跨机器
不可逆性过期后对应恢复能力即时消失

典型使用场景

  • 历史重写收尾:filter-branch / filter-repo 后清理旧对象,让体积真正下降
  • 误操作善后完成:确认不再回退旧现场后,收缩本地保留
  • 敏感内容清理:误提交密钥后过期 reflog,避免旧提交仍能被捞出
  • 体积治理:大对象被重写移除后,expire 与 gc 配套才释放占用
  • 保留政策:按数据保留要求清理过期的引用历史
  • 先救后清:先看 reflog 找回现场,确认恢复完成再考虑过期

常用示例

常用示例
git reflog -5                              # 先看清最近引用变动,找回现场从这里开始
git reflog expire --expire=now --all       # 立即过期全部 reflog 条目
git gc --prune=now                         # 回收不再可达的旧对象
git fsck --unreachable | head              # 复核:不可达对象是否已清掉
git reflog -5                              # 过期后旧记录不再可见

命令对照

命令作用备注
git reflog查看恢复通道找回现场的第一步
reflog expire删除 reflog 条目过期后旧提交不再受保护
git gc --prune=now回收不可达对象只 expire 不 gc 时对象还在
git fsck --unreachable列出不可达对象复核清理效果
执行即失去对应恢复能力:只在确认现场不需要回退时使用,团队共享仓库要提前公告。
过期范围也包括 refs/stash 的条目(暂存栈依赖 reflog 保存),执行前确认没有还在依赖的暂存记录。
想局部处理可以加 --dry-run 先看清单,或指定具体引用过期单个分支,不必一上来就 --all --expire=now。

易错点

  • 把 reflog 当永久备份:它只在保留期内有效且不跨机器,关键操作前打 tag 或临时分支才是硬保障
  • 清理后旧提交仍可能在他人克隆或镜像:敏感内容清理要配合凭证轮换,不是本地删了就安全
  • 顺序错误:只 gc 不 expire,旧对象继续受 reflog 保护,白回收一场
  • stash 一并被清:--all 覆盖 refs/stash 记录,未注意的暂存条目会丢失
  • 无预演直接执行:先 --dry-run 看清单再真清理,回收前多一道保险

数据来源与参考

  • Git 官方文档:git-reflog(expire)
  • Git 官方文档:git-gc(--prune)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌