如何使用Git优雅的回滚实现
作者:方凳雅集 发布时间:2022-03-17 15:49:15
开发过程中,我们经常会遇到代码回滚的情况。正常人都知道,git 回滚有两大宝:
git revert
git reset
当我们在本地开发,还未 git push
到远端时,可以毫无顾忌的使用 git reset
进行回滚。更多的情况中,我们不仅 push 了,而且由于开发周期长,在开发过程中不断的 merge master
和 merge other-branch
以发布到预发环境测试或者多需求合并测试。
突然
上线后用户投诉,需要马上下线本次需求中的 A、B、C,只保留 D、E、F,迅速回滚,不要影响更多用户。
撕逼?那肯定是来不及了。一群人在你背后眼巴巴地盯着你,就问你慌不慌...
接下来,我们来说说,如何在紧急回滚面前,镇定(假)自若(装)地进行 git 操作
简单场景
本地操作使用 git reset
随便玩玩就行了,我们主要讲讲 git revert
回滚“单一提交”
回滚“连续提交”
回滚一次“合并”
回滚合并时,如果直接使用 git revert mergeCommit
实际上是递归回滚里面的每一个节点,指定 -m
是指定以哪一个分支为主线,当前所在分支为 1,依次类推(一次合并多个分支时会 > 2,正常只有 1 和 2)
高级场景
如果我们遇到的问题都像上面一样,那怎么能体现一个程序员的价值?
回滚“混合场景”
如以下场景中,我们期望回归的节点之间含有一次合并导致我们无法一次回滚到位。有两种方式:
1. 按顺序见招拆招回滚(三次操作)
2. 先回滚 D + F,再回滚合并(两次操作)
【推荐】使用方案1,按顺序回滚会处理更少的 conflict,否则假设 D、F 是一系列提交合集,那么回滚成本很高
回滚有点复杂“混合场景”
如下的场景中,特殊的地方在于,我有一个 feature,搭车了一个 bugfix,我需要回滚需求但不回滚 bug
这种情况下,有两种选择:
回滚 G,通过 git 引一步一步回滚 F-F'-E‘-D'-C‘-E'‘(不滚)-D'‘(不滚)-C'‘(不滚) ,回滚 E+D 【推荐】回滚 G,回滚 F 丢弃 F',回滚 D+E,复原 C‘'..E‘' 比第一种方案更快更简单,不用处理第一种方案中的 conflict
git revert G
git revert F -m 1
git revert D..E
git cherry-pick C``
git cherry-pick D``
git cherry-pick E``
回滚复杂的”混合场景“
标注解释
蓝色代表已经合并到远程分支 Master 生成了 tag
红色代表需要回滚的 commit
绿色代表正常 commit
场景解释 一开始你所在的团队接到一个需求,这个需求中可以分拆出一个自需求,最终可以实现两人并行开发
两个人 Pa 和 Pb 分别在 Master 基础上创建了新分支
在开发过程中 Master 上发布了两次 bugfix(v2、v3)
由于需要在预发上持续测试,所以 Pa 主动合并了 Master
Pb 在自己分支 B‘ C' D‘ 中废弃了之前的旧逻辑和一些代码的小幅重构(稳定性更新),之后 一直在本地开发新功能 & 验证
最后即将上线时需要合并自需求一起验证,验证后 Pb 发布了 v3
后续又经过了一次 bugfix 发布了 v4
结果,产品反悔了 WTF ???
最后,要废弃新功能,需要重新设计产品,但是旧有逻辑仍然按原计划废弃 >> F(v2) + B'-D'
回滚方式
遇到这样的场景,一般有如下几种方案回滚:
回到最新的远端 Master (v4) 手动识别需求代码进行人工删除 删除自己的代码还好,删除别人的代码就有点难度了,而且当提交量很大时很耗时耗力
复制 F(v2) 替换 Master(v4),手动或应用 B'-D‘ commit 图示情况,直接复制粘贴是个便捷的方法,再次回复 B'-D' 也费不了多大事,只是手动操作难免失误,尤其是增加/删除文件的情况,复制粘贴容易出错
【推荐】按时序回滚(O'-T‘、L'‘、F'‘-K'‘^、B'‘-C'‘、E'-N‘) 版本控制本来就是为了代码管理更便捷,使用 git 操作后面的人不仅能看懂回滚了哪些 / 如何回滚的 / 怎么处理回滚中的 conflict 的,如果回滚错了还可以回滚“回滚了的”操作
git revert N`..S`
// 仅回滚非 merge Master 节点,保留 Master 代码
git log B``^..L`` --first-parent --no-merges --pretty=format:%H | xargs | xargs git cherry-pick -n
git revert E`..F`
最后多说一点
想要回滚不头痛,提前就要做好功课并且保持清晰的提交记录,否则几百个 commit 回滚起来就变成了一场灾难。提几个好方法
保持 Commit 清晰
一次 commit 的做一件完整的事,不要掺杂别的需求和 bugfix,未完成需求前不要轻易提交编译代码;
commit 有清晰的描述
善用 rebase
如果有几次 commit 干的是一件事,可以通过 rebase 合并,不要出现很多 init、update 之类的无效 log
刚刚提交代码后,又想起来某个配置需要改个版本,可以先 commit,最后使用 rebase 清理一下版本树
多人并行开发,创建独立的分支进行合并测试 不要合并到某一个分支中,防止上线时间变化导致代码再次清洗
来源:https://juejin.im/post/5f156981e51d4534b208c4ce


猜你喜欢
- 本文实例讲述了Python基于贪心算法解决背包问题。分享给大家供大家参考,具体如下:贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在
- 支付宝支付和微信支付是当今互联网产品常用的功能,我使用Django Rest Framework实现了网页上支付宝支付和微信支付的一个通用服
- 10月15日,Adobe公司正式面向全球公布了第10个版本的Flash播放器,这一版本播放器的昵称是大家已经所熟知的“宇宙”。这是一款增加了
- 概述微服务是一种思想,与编程语言无关,编程语言是思想下具体的一种实现方式,怎么设计架构方案和实现主要看主要面临的业务场景。业务场景主站核心业
- 使用socket中的struck来实现客户端发送服务端:客户端:# -*- coding: UTF-8 -*-import socket,
- 使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载刷新整个页面,这使得程序能够更快地回应用户的操作,如下笔记将简单介
- 这篇博客主要写flatten()作用,及其参数的含义flatten()是对多维数据的降维函数。flatten(),默认缺省参数为0,也就是说
- 例子:(简 > 繁)面包 > 麵包 (zh-tw)寮国 > 老撾 (zh-hk)中国人寿 > 中國人壽 (zh-hk
- 一、JDBC是什么?JDBC 指 Java 数据库连接(Java Database Connectivity),是一种标准Java应用编程接
- 如何让animate在显示图片的过程保持窗口的标题不变animate -title "My Image Sequence"
- 用python实现的一个井字棋游戏,供大家参考,具体内容如下#Tic-Tac-Toe 井字棋游戏#全局常量X="X"O=
- PyQt5布局控件QVBoxLayout简介采用QVBoxLayout类,按照从上到下的顺序添加控件本节内容较少,演示两个实例,便于明白QV
- Yoho, 大家好,又是我哟~ 首先抱歉让大家等了这么多时间。最近实在比较繁忙啦。不过我还是会尽量抽空出来给大家讲点有的没的,欢迎大家继续
- 简单方法:models.pyclass IceCreamBar(models.Model): title
- 上篇文章介绍了ROS TF坐标变换基本概念及使用案例,今天给大家介绍ROS机器人底盘坐标像素变换,一起看看吧对于ROS
- 仿照微信朋友圈做了一个界面如下,先看效果:1、点开界面2、选择图片3、点击上传4、动态显示第一个页面的wxml:<view class
- 在开发django项目时,启动开发服务器的命令为:python manager.py runserver [port]其中,[port]选项
- 目的在刷算法题中经常遇到关于链表的操作,在使用go语言去操作链表时不熟悉其实现原理,目的是为了重温链表这一基础且关键的数据结构。1、链表的特
- 导语贪吃蛇,大家应该都玩过。当初第一次接触贪吃蛇的时候 ,还是我爸的数字手机,考试成绩比较好,就会得到一些小奖励,玩手机游戏肯定也在其中首位
- 前言在Python中元组是一个相较于其他语言比较特别的一个内置序列类型。有些python入门教程把元组成为“不可变的列表”,这种说法是不完备