gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

安国
• 阅读 4949

gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

少年, 你点击过gitlab下图中的金灿灿按钮么? 本篇文章将告诉你如何正确使用这个按钮。

gitlab上代码回滚把自己坑了后, 陷入思考🤔

一、 背景

     原计划xx号下午3点我开发的功能要上线, 下午2点将开发分支合并入master分支准备跑上线流水线, 但是不巧这一天server同学遇到了点问题, 导致上线时间延期了, 与此同时前端还有其他分支今天要上线, 已经准备合并入master分支, 当时我要做的就是快速将master回滚。

     我提交的"mr"信息里面有"revert"按钮, 一看就知道这个按钮负责回滚代码, 鬼使神差的就点击了这个按钮, 当然啦代码被成功回滚并且也没有影响后续同学的上线, 但故事并没有这么简单。

     当n天后我负责的代码计划再次上线时, git merge branchmasetrmerge我的分支竟然失效了, 我的代码中新增的部分无法合并入master, 当时情况紧急眉头都皱成了一个"川"字, 焦急兽进化(🧬)钢铁焦急兽。

gitlab上代码回滚把自己坑了后, 陷入思考🤔

二、 强推灰飞烟灭

     当时现场求助了同组的其他同学, 将本地我的分支git merge master, 此时我的分支就是最新的, 再去gitlab上关闭master的保护机制, 强行将分支内容推到master上进行覆盖, 再将master的保护机制重新打开。

     这一套操作当然存在问题, 强推master可还行? 并且这种操作需要相关人员的审核, "费力+有风险"。

     当一切尘埃落定了也该开始思考了, 那么到底为什么会出现代码无法合并入master, 到底是哪一步出了问题, 当时我的gitlab使用的语言是中文, 按钮只显示"还原"两个字, 我赶快将语言切换至英语, 此时按钮的文案变成了"revert", 我就从嫌疑人"revert"开始调查吧, 看看他与不在场的"reset"有什么关联。

三、静下来学习reset与revert的区别

revert

     移除某个commit记录, 并且生成一条新的commit记录。

     假设当前的分支状态是下图:

gitlab上代码回滚把自己坑了后, 陷入思考🤔

     执行

git revert -n gt56th

git add .

git commit -m'feat: rm a'

gitlab上代码回滚把自己坑了后, 陷入思考🤔

reset

     移动HEAD到某个commit上, 这个commit之后的commit全部舍弃, 并且你本地的代码是没有变化的。

     假设当前的分支状态是下图
gitlab上代码回滚把自己坑了后, 陷入思考🤔

     执行git reset gt56th

gitlab上代码回滚把自己坑了后, 陷入思考🤔

四、解释为何代码合不进去

     通过对比我们就可以知道为什么, 那天下午我无法把代码合并入master分支的原因了。

     由上面的步骤图可知, revert后的代码里是明确记录了删除目标commit也就是commit idgt56th的这条数据, 那么我们再将含有commit idgt56th的提交mergemaster分支时, git的算法会判断出这个commit已被移除, 所以git会认为我分支的代码落后于master, master里面移除了这条commit的代码才是最新的。

     git这样判断是没问题的, 我们多人开发的时候, 假设'a'与'b'一起开发一个项目, 'a'删除了a.js文件并且mergemaster, 第二天'b'改动了其他地方也mergemaster, 此时就算b的代码上没有移除a.js, merge后也不会在master分支上增加a.js文件。

五、默认revert此事有蹊跷

     我们来聊聊既然gitlab默认使用revert功能来回退代码, 也就是说官方认为这种回滚方式是最棒的, 那么它棒在哪里?

第一: 连续性

     就算是回退操作, 也算是对master的正常操作, 但是直接reset会导致时间线的缺失, 让我们不知道中间发生了什么, 长期来看这样不利于解决问题。

第二: 中途有人拉代码

     'a'的代码push到了master上, 2个小时后a将master代码reset掉, 看似一切正常, 但是殊不知'b'刚刚pullmaster的代码到本地, 此时就埋下了隐患, 因为如果'b'进行master的合并操作, 会将'a'之前删掉的代码再次发布到master分支, 导致代码的错误上线。

第三: 方便回滚

     比如说我们的gitlab是默认merge完毕就删除源分支的, 此时我们可以直接拉取master的最新代码, 因为可以在git log里面找到所有的commit这样就不怕玩坏了分支代码找不到了。

六、reset 里的大学问

     讲了不少revert的好处与坏处改说说reset了:

     假设我当前项目里有 a.jsb.jsc.js三个文件, a.jsgit commit -m'', b.jsgit add, c.js没有被git监控:
gitlab上代码回滚把自己坑了后, 陷入思考🤔

gitlab上代码回滚把自己坑了后, 陷入思考🤔

git reset --hard CommitId (暴力删除)

     这个写法直接将HEAD回退到目标分支, 并且删除所有当前分支之后编写的代码, 也就是说会将你的代码清除哦。

     这个方法适合完全舍弃某些代码的场景, 因为你在git log命令里面都无法查到被删除的commit记录了。

gitlab上代码回滚把自己坑了后, 陷入思考🤔

gitlab上代码回滚把自己坑了后, 陷入思考🤔

git reset --soft CommitId (舒服的?)

     这个写法直接将HEAD回退到目标分支, 并且保留你在目标commit之后的修改, 这些修改都在暂存区, 我们可以继续开发相关的功能, 最后统一 git add. && git commit -m '' 一次即可。

     这种方式让我想到了我们可以平时在自己电脑上提交多个commit, 但是push之前我们可以先回退, 然后把commit合一再提交。

gitlab上代码回滚把自己坑了后, 陷入思考🤔

gitlab上代码回滚把自己坑了后, 陷入思考🤔

git reset --mixed CommitId (默认的, 当我们不写参数就是这个指令)

     将目标提交之后的代码还原成未被监控的状态, 也就是你的代码需要git add .一下才可以进行管理, 这个招式相当于重置了提交态, 但是也有一些小小问题, 比如我们有一些没有被git add的文件会与其他文件不好分割开, 给我的感觉就是向我们当前的代码里面塞入很多新的代码, 使用git status 查看的话就全是红色的。

gitlab上代码回滚把自己坑了后, 陷入思考🤔

gitlab上代码回滚把自己坑了后, 陷入思考🤔

七、流程梳理得出方案

     已经了解了上述的知识点, 那么可以推导出一套比较可靠的回滚流程了, 当我们要将已经mergemaster的代码暂时回滚, 并且后续还会上线这些代码时, 先点击gitlab上的revert按钮, 再将自己本地的代码git reset 线上commit版本这样就可以将这些代码变成新的commit, 这样就可以再次申请mergemaster也不会合并不上了。

八、问题的出现与思索

     刚出现这个问题的时候, 习惯性的认为gitlab出问题了, git的某些算法出问题了, 但是通过系统性的分析才明白, 出问题的是自己的操作。
gitlab上代码回滚把自己坑了后, 陷入思考🤔

     将gitlab平台设置成了中文, 导致某些英文可以表达的含义无法表达, 这也是个问题点, 写代码最好能更清楚的知道代码的本意, 而不是翻译过后的意思。

gitlab上代码回滚把自己坑了后, 陷入思考🤔

end

     这次就是这样, 希望与你一起进步。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这