Workflows
发布后热修失败,如何回滚与稳定主线
当发布后热修本身引入问题时,优先判断回滚粒度、共享影响和后续补丁路径,而不是立刻继续叠加修复。
- 要把命令组合成稳定流程的团队成员
- 需要处理协作顺序和分支边界的人
- 知道 fetch / pull / push / branch 的基本作用
- 能理解一条分支为什么会分叉
- 照抄流程却没确认当前分支关系
- 在共享分支上用错整合方式
热修失败时,最危险的往往不是 bug 本身,而是慌着继续往生产线上叠修复。
事故一旦进入“再补一刀看看”的状态,主线、发布线、标签和排查上下文都会一起变乱。
如果热修已经被别人拉取、已经进入发布线,或者已经对应线上部署记录,通常应优先考虑 git revert。共享历史里最怕的是“回滚手段本身又改写了上下文”。
第一步不是继续提交,而是判断事故边界
先把这几个问题问清楚:
- 问题是否只来自这次 hotfix
- 要回滚的是一个提交、一个 patch,还是整次发布范围
- 当前线上部署对应哪个 tag 或提交
- 哪条分支是现在最可信的真相来源
这些判断的价值在于:它能阻止你把“代码修复”问题,误做成“历史结构”问题。
为什么很多情况下优先考虑 revert
如果 hotfix 已经共享并部署,git revert <hotfix-commit> 通常比 reset 更稳,原因不是它更高级,而是它更容易保留事故轨迹:
- 历史可追踪
- 团队成员更容易同步
- 发布线和主线都更好解释
- 后续复盘时能看清“修复”和“撤销修复”各自发生了什么
git revert <hotfix-commit>
如果有多次相关提交,也应该先确认范围,再决定是单次 revert 还是多次 revert,而不是直接把分支倒回到某个旧位置。
一个更稳的事故顺序
1. 先标记当前线上状态
如果目前线上状态已经不稳定,第一件事不是继续改代码,而是先把当前状态标清楚。
这可以是:
- 一个 tag
- 一条 incident 记录
- 一次 release note 备注
核心目的是让“问题版本”有名字,后面排查和沟通都更容易。
2. 回滚最小必要范围
如果只是 hotfix 本身出问题,就优先回滚 hotfix,而不是把整次发布一起推翻。
如果是整次发布边界本来就判断错了,再考虑更大粒度的撤回。
3. 在独立分支重做修复
不要在已经混乱的发布线里继续边试边修。
回滚让系统先稳定,新的修复应该在新的分支里完成、验证,再决定怎么回补。
4. 再决定如何回补主线和发布线
真正危险的地方往往在这里:
热修失败不只是“线上坏了”,还意味着主线和发布线可能已经分叉表达不同状态。后续必须明确:
- 哪条分支先恢复正确修复
- 是否需要 backport
- 是否需要补新的 tag
什么时候 reset 反而更危险
以下几种情况里,直接 reset 往往会让问题更复杂:
- 提交已经 push 到共享分支
- 别人已经基于这次 hotfix 继续工作
- 发布系统、CI、tag 或审计链已经记录了这次提交
- 你还没完全确认要回滚的粒度
这类场景里,reset 的问题不是“命令不能用”,而是它会把协作上下文一起抹掉。
一个适合团队执行的最小事故协议
可以非常简单:
- 先确认线上对应提交和标签
- 优先使用可追踪的回滚方式
- 先稳定系统,再重做修复
- 修复完成后再统一回补主线和发布线
- 所有事故分支、标签和回滚动作都留下明确说明
这套协议的价值是让“事故处理”不只靠个人经验,而是能被团队复用。
常见误区
“线上坏了,就赶紧在当前分支继续修”
这通常会把第一层事故变成第二层事故。先稳住系统,再重做修复,更容易控制。
“回滚就是把分支退回去”
在共享历史里,回滚更常常意味着新增一条明确的“撤销历史”,而不是抹掉已有历史。
“只要 hotfix 修好了,主线自然也就对了”
不一定。你还需要确认发布线、主线、tag 和后续补丁路径是不是重新对齐了。
重点不是练命令本身,而是练习在共享历史里如何先稳定、再修复、再回补。
git switch main git switch -c hotfix/login-timeout echo patch >> app.txt git commit -am "hotfix: adjust login timeout" # 假设这次提交已经发布并出现问题步骤
- 先记录当前状态对应的 tag 或提交
- 判断是否只需回滚 hotfix 提交
- 用 `git revert <sha>` 设计一条可追踪回滚路径
- 新开分支重新实现修复并补验证
- 再决定主线和发布线各自如何回补
- 回滚动作和重做修复是两件不同的事
- revert 能保留事故路径
- 分支和 tag 会成为排查上下文的一部分
- 主线和发布线需要被重新对齐
- 没判断范围就直接 reset
- 在事故分支上连续叠修补丁
- 回滚完不处理主线与发布线的后续一致性
一个最重要的原则
事故处理中,先把系统带回稳定状态,再追求历史优雅。
稳定优先,漂亮其次,可解释性贯穿始终。