Git 生产环境救火指南:Reset、Rebase 与 Cherry-Pick 实战
深夜,客户突然反馈线上的某个核心功能挂了,打开 Git 分支记录一看,居然有人把错误的代码合进了主分支,甚至更糟糕的是——它已经被部署到生产环境。
这种时候,git revert 已经不够用了。你需要的是 Git 的**”救火三件套”**:Reset、Cherry-Pick 以及进阶的 Rebase。
Reflog:找回丢失的一切
在进行任何危险的 Git 操作之前,先牢记一个保命指令:git reflog。
Git 的 reflog 记录了你在这个仓库中做过的所有 HEAD 移动操作——包括那些已经被删除的分支、已经被 reset 掉的提交。只要操作发生在 30 天内(默认),reflog 就能帮你找回来。
1 | git reflog |
场景 1: 不小心 git reset --hard 回退了 3 个提交。
1 | git reset --hard HEAD@{1} # 回到 reset 之前的状态 |
场景 2: 误删了一个分支。
1 | git branch feature/resurrected ghi9012 # 从 reflog 中找到 hash 重建分支 |
Cherry-Pick:只摘”樱桃”
git merge 会把整个分支的所有改动一次性倒进来。但很多时候,你只需要另一个分支上的某一个特定提交。
1 | # 假设 main 线上崩了,修好 Bug 的代码在 hotfix/login-bug 分支 |
更精细的操作——连续摘取多个提交:
1 | git cherry-pick commitA..commitD # 从 A 之后到 D 的所有提交(不含 A) |
冲突处理:
1 | git add . |
Reset 三模式详解
| 模式 | 效果 | 适用场景 |
|---|---|---|
--soft |
回退 HEAD,保留暂存区和工作区 | 把多个 commit 合并成一个 |
--mixed(默认) |
回退 HEAD 和暂存区,保留工作区 | 撤销 add 但保留写的代码 |
--hard |
回退一切 | 彻底丢弃脏代码 |
1 | # 合并最近 5 个零散的 WIP 提交为一个 |
交互式 Rebase:提交历史整理
当你开发了一个功能,本地有 15 个 “fix typo”、”WIP”、”test again” 之类的提交,直接推到远程太不专业了。交互式 Rebase 让你可以像编辑文档一样编辑提交历史:
1 | git rebase -i HEAD~15 |
编辑器会打开一个列表,每个提交前面有一个操作关键字:
pick:保留这个提交squash:合并到上一个提交(保留 commit message)fixup:合并到上一个提交(丢弃 commit message)drop:删除这个提交reword:修改 commit message
将中间 14 个提交的 pick 改为 fixup,只留第一个 pick,最终会得到一个干净优雅的提交历史。
Git Bisect:二分法定位 Bug
当你不确定 Bug 是哪个提交引入的,Git Bisect 用二分查找法自动帮你定位:
1 | git bisect start |
这个功能在大型项目中极其有用——当 commit 数量成百上千时,手动逐个排查几乎不可能,Bisect 能在 log2(N) 步内锁定问题。
总结
Git 远不止 add、commit、push。Reflog 是你的后悔药,Cherry-Pick 是你的手术刀,Reset 是你的时光机,Rebase 是你的史书修撰官。掌握这些命令,你就是团队里那个能”徒手接锅并优雅化解”的 Git 宗师。
