Appearance
恢复删除
概述
Git 提供了多种机制来恢复误删的提交、分支和文件。理解这些恢复机制可以帮助你在操作失误时挽回损失。
git reflog 查看操作历史
git reflog 是恢复操作的利器,它记录了 HEAD 的所有移动历史。
基本用法
bash
# 查看所有操作历史
git reflog
# 输出示例:
# e5f6g7h (HEAD -> main) HEAD@{0}: reset: moving to HEAD~1
# f6g7h8i HEAD@{1}: commit: Add feature C
# g7h8i9j HEAD@{2}: checkout: moving from feature to main
# h8i9j0k (feature) HEAD@{3}: commit: Add feature B
# i9j0k1l HEAD@{4}: checkout: moving from main to feature
# j0k1l2m HEAD@{5}: commit: Add feature A
# k1l2m3n HEAD@{6}: clone: from https://github.com/user/repo.git查看特定分支的历史
bash
# 查看特定分支的操作历史
git reflog show main
# 查看特定分支的最近 10 条记录
git reflog show main -10理解 reflog 输出
bash
# 输出格式
# <commit-hash> (<refs>) HEAD@{n}: <action>: <message>
# HEAD@{n} 表示第 n 次操作之前
# HEAD@{0} 是最近一次操作
# HEAD@{1} 是倒数第二次操作reflog 配置
bash
# 查看默认过期时间
git config gc.reflogExpire
# 默认 90 天
# 查看未可达对象的过期时间
git config gc.reflogExpireUnreachable
# 默认 30 天
# 设置过期时间
git config gc.reflogExpire 180
git config gc.reflogExpireUnreachable 90恢复已删除的提交
场景:误用 reset --hard
bash
# 1. 误操作
git reset --hard HEAD~3
# 丢失了 3 个提交
# 2. 查看操作历史
git reflog
# a1b2c3d HEAD@{0}: reset: moving to HEAD~3
# d4e5f6g HEAD@{1}: commit: Important commit <-- 这是丢失的提交
# 3. 恢复到误操作前的状态
git reset --hard HEAD@{1}
# 或使用提交哈希
git reset --hard d4e5f6g场景:误删分支后恢复提交
bash
# 1. 查看所有操作历史
git reflog
# 2. 找到分支删除前的提交
# 例如:e5f6g7h HEAD@{5}: checkout: moving from feature to main
# 3. 恢复提交
git checkout e5f6g7h
# 4. 创建新分支保存
git checkout -b recovered-feature场景:恢复特定提交
bash
# 查找特定提交
git reflog | grep "commit message"
# 恢复
git cherry-pick <commit-hash>
# 或创建分支
git branch recovered-branch <commit-hash>恢复已删除的分支
使用 reflog 恢复
bash
# 1. 查看操作历史
git reflog
# 输出示例:
# a1b2c3d HEAD@{0}: checkout: moving from feature to main
# b2c3d4e HEAD@{1}: commit: Last commit on feature <-- feature 分支最后的提交
# 2. 找到分支最后的提交
# 查找 "moving from <branch-name>" 之前的提交
# 3. 恢复分支
git branch feature b2c3d4e
# 或使用 reflog 引用
git branch feature HEAD@{1}完整恢复流程
bash
# 假设误删了 feature 分支
# 1. 查看操作历史
git reflog
# 2. 找到分支最后的提交
# 输出:
# abc1234 HEAD@{0}: branch: Deleted feature
# def5678 HEAD@{1}: commit: Feature work <-- 这是 feature 最后的提交
# 3. 恢复分支
git branch feature def5678
# 4. 验证恢复
git log feature --oneline -5恢复远程删除的分支
bash
# 如果分支曾经推送到远程
# 1. 查看远程引用
git remote show origin
# 2. 如果远程分支还存在
git fetch origin
git checkout -b feature origin/feature
# 3. 如果远程分支已删除,使用本地 reflog
git reflog
git branch feature <commit-hash>git fsck 检查仓库
git fsck 用于检查仓库的完整性和一致性。
基本用法
bash
# 检查仓库
git fsck
# 输出示例:
# Checking object directories: 100% (256/256), done.
# Checking objects: 100% (1234/1234), done.查找悬空对象
bash
# 查找悬空提交
git fsck --lost-found
# 输出示例:
# dangling commit a1b2c3d4e5f6...
# dangling blob b2c3d4e5f6g7...
# 查看悬空提交内容
git show a1b2c3d4e5f6
# 恢复悬空提交
git branch recovered-branch a1b2c3d4e5f6悬空对象类型
bash
# dangling commit:悬空提交
# dangling blob:悬空文件内容
# dangling tree:悬空目录树
# 查看所有悬空对象
git fsck --unreachable
# 查看特定类型
git fsck --unreachable --no-reflogs恢复悬空 blob
bash
# 查找悬空 blob
git fsck --lost-found
# 输出:
# dangling blob a1b2c3d4
# 查看内容
git cat-file -p a1b2c3d4
# 恢复到文件
git cat-file -p a1b2c3d4 > recovered-file.txt恢复场景详解
场景 1:恢复误删的文件
bash
# 方法 1:从最新提交恢复
git checkout HEAD -- deleted-file.txt
# 方法 2:从特定提交恢复
git checkout a1b2c3d -- deleted-file.txt
# 方法 3:使用 restore
git restore --source=HEAD deleted-file.txt场景 2:恢复误删的提交
bash
# 1. 查看操作历史
git reflog
# 2. 找到提交
# HEAD@{3}: commit: Important work
# 3. 恢复
git reset --hard HEAD@{3}
# 或 cherry-pick
git cherry-pick <commit-hash>场景 3:恢复被覆盖的分支
bash
# 假设 feature 分支被其他分支覆盖
# 1. 查看 reflog
git reflog show feature
# 2. 恢复到之前的提交
git checkout feature
git reset --hard HEAD@{n}场景 4:恢复 stash
bash
# 查看所有 stash
git stash list
# 恢复最近的 stash
git stash pop
# 恢复特定 stash
git stash apply stash@{2}
# 如果误删了 stash
git fsck --lost-found
# 查找 dangling commit
git show <commit-hash>
git stash apply <commit-hash>场景 5:恢复 rebase 丢失的提交
bash
# 1. 查看 reflog
git reflog
# 2. 找到 rebase 前的提交
# HEAD@{5}: rebase finished: ...
# 3. 恢复
git reset --hard HEAD@{5}预防措施
定期备份
bash
# 创建备份分支
git branch backup-$(date +%Y%m%d)
# 推送到远程
git push origin backup-$(date +%Y%m%d)
# 创建标签
git tag -a v1.0.0-backup -m "Backup before risky operation"使用标签
bash
# 重要操作前打标签
git tag pre-reset
# 操作后如果需要恢复
git reset --hard pre-reset保持 reflog
bash
# 不要频繁执行 git gc
# gc 会清理不可达对象
# 延长 reflog 保留时间
git config gc.reflogExpire 365
git config gc.reflogExpireUnreachable 180安全操作习惯
bash
# 1. 危险操作前检查
git status
git log --oneline -5
# 2. 创建备份分支
git branch backup
# 3. 执行操作
git reset --hard HEAD~3
# 4. 如果出错,恢复
git reset --hard backup
git branch -d backup恢复工具对比
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| reflog | 最近删除的提交/分支 | 快速、简单 | 有时间限制 |
| fsck | 悬空对象 | 可找回更老的对象 | 需要手动识别 |
| 远程仓库 | 已推送的内容 | 可靠 | 需要网络 |
| 备份分支 | 主动备份 | 最安全 | 需要提前创建 |
总结
git reflog记录所有 HEAD 移动历史git fsck可查找悬空对象- 恢复分支需要找到最后的提交
- 定期备份重要分支和提交
- 危险操作前创建备份分支
下一步
恭喜你完成了 Git 进阶篇的学习!建议继续学习:
