如何使用Git优雅的回滚实现

所属分类: 网络编程 / 相关技巧 阅读数: 1341
收藏 0 赞 0 分享

开发过程中,我们经常会遇到代码回滚的情况。正常人都知道,git 回滚有两大宝:

  • git revert
  • git reset

当我们在本地开发,还未 git push 到远端时,可以毫无顾忌的使用 git reset 进行回滚。更多的情况中,我们不仅 push 了,而且由于开发周期长,在开发过程中不断的 merge mastermerge 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 清理一下版本树

多人并行开发,创建独立的分支进行合并测试 不要合并到某一个分支中,防止上线时间变化导致代码再次清洗

更多精彩内容其他人还在看

firefox 扩展开发技巧

firefox 扩展开发
收藏 0 赞 0 分享

php asp.net 比较 [推荐]

如今当提到 Web 开发时,您有许多选择。这些方法中许多都涉及到预处理 - 即,利用特定的标记将代码嵌入到 HTML 页面中
收藏 0 赞 0 分享

UTF-8 BOM 可能导致样式错乱的解决方法

utf-8 是一种在web应用中经常使用的一种 unicode 字符的编码方式,使用 utf-8 的好处在于它是一种变长的编码方式,对于 ANSII 码编码长度为1个字节,这样的话在传输大量 ASCII 字符集的网页时,可以大量节约网络带宽。
收藏 0 赞 0 分享

Web 开发常用工具 大家自己查找下载

看到了Web通信分析工具 这篇文章,除了burpsuite其他我日常都经常使用。于似乎我整理了一下我自己用的其他的WEB开发工具。
收藏 0 赞 0 分享

遇到不能复制的网站怎么办?

有时我们看到喜欢的网页内容时定会产生复制下来为我所用的冲动,不过当你点击鼠标时它却没有任何反应,选择的内容没有任何变化,不禁有点扫兴。不要紧,办法总比困难多!
收藏 0 赞 0 分享

URL 长度有限制吗?

众所周知, 传递小量参数(在没有其他原因,例如隐藏参数值的情况下)推荐使用GET方法,传递大量参数推荐使用POST方法。原因是什么呢?
收藏 0 赞 0 分享

声音验证码制作方法

收听验证码已经比较普遍了,使用户看不清楚的情况下可以通过耳朵来收听验证码,但网上搜了很久没看到有具体的制作方法,自己想了想,还是按自己的方法来实现了,呵呵。
收藏 0 赞 0 分享

防范SQL注入式攻击

SQL注入式攻击是利用是指利用设计上的漏洞,在目标服务器上运行Sql命令以及进行其他方式的攻击动态生成Sql命令时没有对用户输入的数据进行验证是Sql注入攻击得逞的主要原因。
收藏 0 赞 0 分享

Web 设计与开发者必须知道的 15 个站点

今天读到一篇文章,介绍了15个对 Web 设计与开发师极端有用的站点,里面有不少也是我们一直在使用的,也许对很多人都有用,翻译出来以饷同仁。
收藏 0 赞 0 分享

十分钟内学会 避免用户刷新导致重复POST提交

在Web应用中,采用POST提交信息是非常常见的,然而如果目标页面打开得太慢,用户就可能会刷新页面,这时候之前已经提交过的信息就会被重复提交。
收藏 0 赞 0 分享
查看更多