Git 故障恢复技巧:reflog、bisect 与安全回退
Git 中很多“代码丢了”其实只是引用移动了。真正危险的不是操作失误,而是在不理解工作区、暂存区、提交和远端状态时继续执行破坏性命令。先停下来查看状态,通常都能恢复。
Reflog 找回移动前的提交
误执行 Reset、Rebase 或删除分支后:
git status
git reflog --date=local
找到操作前的提交后先建立保护分支:
git branch rescue/<date> <commit>
git show <commit>
确认内容无误,再决定 Cherry-pick、Merge 或重新移动分支。不要一上来再次 reset --hard,它可能覆盖尚未保存的工作区。
Revert 与 Reset 的边界
- 已推送、多人共享的提交:使用
git revert创建反向提交,保留历史。 - 仅本地、确定没人依赖的提交:可以 Reset 调整历史。
- 工作区有未提交修改:先
git diff、创建临时提交或 Stash。
合并提交回退需要指定主线:
git revert -m 1 <merge-commit>
执行前要理解哪个父提交代表主线,并在测试环境验证结果。
Bisect 自动定位回归
已知一个好版本和当前坏版本时:
git bisect start
git bisect bad HEAD
git bisect good v1.8.0
每轮测试后标记 good 或 bad。如果有稳定自动测试,可以让 Git 完成二分:
git bisect run ./scripts/regression-test.sh
git bisect reset
测试脚本退出 0 表示 Good,1 到 127(除 125)表示 Bad,125 表示当前提交无法测试并跳过。脚本应可重复、无人工交互,并清理自己的临时状态。
Worktree 并行处理版本
需要保持当前工作区不动,同时修复生产版本:
git worktree add ../project-hotfix -b hotfix/issue origin/main
它比复制仓库更节省空间,也不必频繁 Stash。处理完删除工作树:
git worktree remove ../project-hotfix
git worktree prune
Stash 不是长期仓库
git stash push -u -m 'wip: article editor'
git stash list
git stash show -p stash@{0}
git stash apply stash@{0}
先 apply 验证,再决定 drop;pop 在冲突时更容易让人误判状态。重要工作最好形成临时提交并推到个人分支,远比长期堆在 Stash 安全。
日常安全规则
- 破坏性操作前先看
git status与git diff。 - 不对共享分支强推;必须强推时使用
--force-with-lease。 - 批量回退前创建保护分支或 Tag。
- 提交保持小而可验证,Bisect 才有意义。
- CI 记录构建对应 Commit,线上版本才能追溯。

评论
0 条讨论