线上回滚一般是指最近 一次或几次 发布的新功能中,线上回归或用户端发现bug,需要回退到之前某一稳定版本. 本身并不复杂,但会有几种情况:
-
最近一次MR合并的代码有bug
这种最常见, 发布到线上在测试回归时,由于数据或者测试环境遗漏,导致bug发布到线上才被暴露.这个时候通常只需要回滚最近一次MR合并的代码即可.
这种方式还包含一种特殊情况,比如小红的开发分支是feature/xh, 包含多次commit :按时间升序比如 c1、c2、c3, 小红确定是c2导致的,希望你帮助只回滚c2这次commit.
我给的建议是,小红既然确定c2那次提交导致的,如果修改很快,没必要操作回滚,让小红修改完再次提交即可. 如果修改起来耗时较长,线上时间紧迫,我还是建议首选回滚整次MR合并而非单次commit.因为以规范的分支模型来讲,feature/xh上的所有commit组成了这次完整的功能.
-
非最后一次MR合并的代码有bug
这种情况通常会发生在组内同时有多个功能一起开发且都在一天上线. 比如小红和小明在各自的开发分支上(feature/xh, feature/xm)开发着新功能, 小红代码测试完成优先上线了,随后小明的代码也测试完成,测试通知可以上线了,由时间顺序来看小红的MR合并非最后一次,这个时候小红跑来跟你说她的这次修改需要回滚(因为后端数据没有准备好balabala等等原因),但小明的功能线上回归没有问题! 这个时候操作回滚依旧有几种选择:
1.回滚小红MR合并后的所有合并,意味着小明的功能也会下掉
2.小明的功能不要下掉,依旧有多种处理方式,我习惯下边两种不需要太复杂的操作:
a. 回滚小红MR合并后的所有合并之后,让小明再单独合一次代码 [建议]
b.单独回滚小红的MR合并[可能会有冲突解决的步骤,除非你很了解小红和小明的需求和代码,否则还是建议选择a]
-
特殊情况
有可能会出现Fast-Forward合并的情况,就是没有MR合并,提交历史与feature/xh一致.
产生这种问题的原因是没有通过github或gitLab创建MR或者PR,小红直接手动merge+push.
回滚最近一次MR合并
找到最近MR合并前的commit-hash
执行
git reset --hard 3c10c2f(直接撤销本次MR合并)
或
git reset --hard 3c10c2f1f234e890fc2b5e1c3affb72f9cd398f6都可以.
会让你main回到当前提交,并且删掉之后的所有提交历史,(不要觉得删掉提交历史很可怕, reset之后确实需要注意几点,后边我会强调)
此时只是更改了你本地的main分支,远程分支没有受到影响,可以执行git status 查看,会提示当前本地分支的代码落后于远程.
接下来检查本地main分支代码确实回归到之前你想要的版本了之后,执行
git push -f
也就是常说“强推”即可.
明天等小红修复完问题,再将feature/xh合并到主分支就这么点事.
这就是reset的好处,真正的时光倒流, 等小红改完再重复昨天的合并即可.
如果使用revert,小红第二天需要重新从主分支拉取代码,再修改,以保证合并到主分支时历史记录保持正确的顺序.
那reset需要注意的是什么?
其实还是团队开发会遇到, 就在我reset前,小刚恰好基于主分支开了一个新分支feature/xg开发功能. 那么我reset之后,一定要同步小刚,不然可能会导致小刚在不知情的情况下将之前有bug的代码又重新带到线上.
同步小刚后小刚如何处理?
-
就在我操作回滚的过程中,小刚也不会写太多东西,让小刚删除feature/xg,重新从主分支拉feature/xg(基本都这么玩).
-
如果小刚开发半天了 咋办?
- Git cherry-pick
- 待补充.. 我建议还是让小刚删了重拉吧...
回滚最近n次MR合并
同上,找到对应的commit-hash
回滚单独某一次MR合并
...待补充
最后,Git自由度很高能做的事也很多,但回滚操作是一个团队性的操作,能用最简单、线上影响最小的方式处理,同时保证接下来对团队的开发影响最小即可.