Git误操作急救手册
常见误操作场景
误删本地分支
恢复未同步到远程的已删除分支
bash
# 1. 查看所有操作记录,找到删除分支前的提交哈希(找refs/heads/[分支名]对应的哈希)
git reflog
# 2. 从提交哈希恢复分支(替换 [分支名] 和 [提交哈希])
git checkout -b [分支名] [提交哈希]
# 示例:恢复名为feature/user的分支,提交哈希为a1b2c3d
git checkout -b feature/user a1b2c3d
误提交到错误分支
场景1:未推送到远程,暂存更改切换分支
bash
# 1. 暂存当前未提交/已提交的更改
git stash
# 2. 切换到正确分支
git checkout [正确分支名]
# 3. 恢复暂存的更改
git stash pop
# 4. 提交更改到正确分支
git add .
git commit -m "修复:误提交到错误分支,迁移至正确分支"
场景2:已提交到错误分支,移植提交到正确分支
bash
# 1. 查看提交记录,找到错误提交的哈希(替换 [错误提交哈希])
git log --oneline
# 2. 切换到正确分支
git checkout [正确分支名]
# 3. 移植指定提交到当前分支
git cherry-pick [错误提交哈希]
# 4. 回退错误分支的提交(如果需要)
git checkout [错误分支名]
git reset --hard HEAD^ # 回退到提交前版本
误覆盖或丢失未提交的更改
从暂存区/悬空对象恢复未提交文件
bash
# 方式1:从暂存区恢复(未执行git add的文件)
git checkout -- [文件名] # 替换 [文件名],如 src/main/java/Test.java
# 方式2:通过git fsck查找悬空对象恢复
# 1. 查找所有悬空的blob对象(未关联的文件内容)
git fsck --lost-found
# 2. 查看悬空对象内容,确认是否是丢失的文件(替换 [blob哈希])
git show [blob哈希]
# 3. 恢复文件到工作区(替换 [blob哈希] 和 [目标文件名])
git show [blob哈希] > [目标文件名]
# 示例:恢复blob哈希为e4f5g6h的内容到Test.java
git show e4f5g6h > src/main/java/Test.java
误强制推送覆盖远程历史
从本地备份/同事仓库恢复远程分支
bash
# 1. 先拉取同事仓库(替换 [同事仓库地址] 和 [分支名])
git remote add colleague [同事仓库地址]
git fetch colleague
# 2. 恢复本地分支到正确版本
git checkout [分支名]
git reset --hard colleague/[分支名]
# 3. 强制推送到远程恢复(谨慎!确保团队已暂停操作)
git push -f origin [分支名]
# 示例:恢复远程main分支
git remote add colleague git@github.com:colleague/project.git
git fetch colleague
git checkout main
git reset --hard colleague/main
git push -f origin main
核心恢复工具与命令
git reflog(必备:找回所有操作记录)
bash
# 查看完整操作日志(包含分支创建、删除、提交等)
git reflog
# 筛选指定分支的操作记录(替换 [分支名])
git reflog show [分支名]
git reset(回退提交,按场景选择参数)
bash
# 场景1:保留更改到暂存区(仅撤销commit,不撤销add)
git reset --soft [提交哈希/HEAD^]
# 场景2:彻底丢弃更改(慎用!无法恢复未备份的更改)
git reset --hard [提交哈希/HEAD^]
# 示例:回退到上一个提交,保留更改
git reset --soft HEAD^
# 示例:回退到指定提交(哈希a1b2c3d),彻底丢弃后续更改
git reset --hard a1b2c3d
git fsck(恢复丢失的文件/提交)
bash
# 检查仓库完整性,列出所有悬空对象(丢失的提交/文件)
git fsck --full --lost-found
# 查看悬空提交的内容(替换 [commit哈希])
git show [commit哈希]
# 查看悬空文件内容(替换 [blob哈希])
git show [blob哈希]
数据备份与预防措施
定期推送远程备份
bash
# 每次开发完成后,推送本地分支到远程(替换 [分支名])
git push -u origin [分支名]
# 示例:推送feature/pay分支到远程
git push -u origin feature/pay
启用pre-push钩子拦截强制推送(创建.git/hooks/pre-push)
bash
#!/bin/sh
# 拦截强制推送操作
if [[ "$*" == *"--force"* || "$*" == *"-f"* ]]; then
echo "禁止强制推送!如需执行请先联系管理员"
exit 1
fi
exit 0
bash
# 赋予钩子脚本执行权限
chmod +x .git/hooks/pre-push
分支保护规则(远程仓库配置,以GitHub为例)
- 进入仓库 → Settings → Branches → Branch protection rules
- 点击 "Add rule",填写分支名(如main)
- 勾选:
- "Require pull request reviews before merging"
- "Dismiss stale pull request approvals when new commits are pushed"
- "Require status checks to pass before merging"
- "Do not allow bypassing the above settings"
- "Restrict who can push to matching branches"
高级恢复案例
恢复被git reset --hard覆盖的提交
bash
# 1. 查找reset操作前的提交哈希(找reset: moving to ... 上一行的哈希)
git reflog
# 2. 重置到该提交(替换 [提交哈希])
git reset --hard [提交哈希]
# 示例:恢复到哈希为9876543的提交
git reset --hard 9876543
从损坏的仓库中提取数据
bash
# 1. 先镜像备份损坏的仓库
git clone --mirror [损坏仓库地址] backup-repo.git
# 2. 修复损坏的对象库
cd backup-repo.git
git fsck --full
git gc --prune=now
# 3. 克隆修复后的仓库到本地使用
git clone backup-repo.git fixed-project
紧急联系与工具
开源工具推荐
bash
# 安装git-damage-control(恢复Git灾难的工具)
git clone https://github.com/git/git-damage-control.git
cd git-damage-control
chmod +x git-damage-control
cp git-damage-control /usr/local/bin/
# 使用工具检测并修复仓库
git-damage-control check
git-damage-control recover
团队协作恢复流程
- 立即通知所有成员:
暂停对[分支名]的推送/提交操作 - 从本地/同事仓库恢复正确版本(参考上文命令)
- 确认恢复完成后,通知成员:
执行 git pull --rebase origin [分支名] 同步最新代码
注:所有命令执行前,务必先在临时目录克隆仓库测试,避免二次损坏!