Git如何优雅地回退代码

嵌入式ARM 2020-07-17 00:00

来源:cnblogs.com/zhenbianshu/p/12018714.html

前言

从接触编程就开始使用 Git 进行代码管理,先是自己玩 Github,又在工作中使用 Gitlab,虽然使用时间挺长,可是也只进行一些常用操作,如推拉代码、提交、合并等,更复杂的操作没有使用过,看过的教程也逐渐淡忘了,有些对不起 Linus 大神。
出来混总是要还的,前些天就遇到了 Git 里一种十分糟心的场景,并为之前没有深入理解 Git 命令付出了一下午时间的代价。
先介绍一下这种场景,我们一个项目从 N 版本升到 A 版本时引入了另一项目的 jar 包,又陆续发布了 B、C 版本,但在 C 版本后忽然发现了 A 版本引入的 jar 包有极大的性能问题,B、C 版本都是基于 A 版本发布的,要修复 jar 包性能问题,等 jar 包再发版还得几天,可此时线上又有紧急的 Bug 要修,于是就陷入了进退两难的境地。
最后决定先将代码回退到 A 版本之前,再基于旧版本修复 Bug,也就开始了五个小时的受苦之路。

基础试探

revert

首先肯定的是 revert, git revert commit_id  能产生一个 与 commit_id 完全相反的提交,即 commit_id 里是添加, revert 提交里就是删除。
但是使用  git log  查看了提交记录后,我就打消了这种想法,因为提交次数太多了,中途还有几次从其他分支的 merge 操作。
”利益于”我们不太干净的提交记录,要完成从 C 版本到 N 版本的 revert,我需要倒序执行 revert 操作几十次,如果其中顺序错了一次,最终结果可能就是不对的。
另外我们知道我们在进行代码 merge 时,也会把 merge 信息产生一次新的提交,而 revert 这次  merge commit  时需要指定 m 参数,以指定  mainline
这个 mainline 是主线,也是我们要保留代码的主分支,从 feature 分支往 develop 分支合并,或由 develop 分支合并到 master 的提交还好确定,但 feature 分支互相合并时,我哪知道哪个是主线啊。
所以 revert 的文案被废弃了。

Reset

然后就考虑  reset  了, reset 也能使代码回到某次提交,但跟 revert 不同的是, reset 是将提交的 HEAD 指针指到某次提交,之后的提交记录会消失,就像从没有过这么一次提交。
但由于我们都在 feature 分支开发,我在 feature 分支上将代码回退到某次提交后,将其合并到 develop 分支时却被提示报错。
这是因为 feature 分支回退了提交后,在 git 的 workflow 里,feature 分支是落后于 develop 分支的,而合并向 develop 分支,又需要和 develop 分支保持最新的同步,需要将 develop 分支的数据合并到 feature 分支上,而合并后,原来被 reset 的代码又回来了。
这个时候另一个可选项是在 master 分支上执行 reset,使用  --hard  选项完全抛弃这些旧代码,reset 后再强制推到远端。
    
master> git  reset --hard commit_id
master> git  push --force origin master
但是还是有问题,首先,我们的 master 分支在 gitlab 里是被保护的,不能使用  force push ,毕竟风险挺大了,万一有人 reset 到最开始的提交再强制 push 的话,虽然可以使用  reflog  恢复,但也是一番折腾。
另外,reset 毕竟太野蛮,我们还是想能保留提交历史,以后排查问题也可以参考。

升级融合

rebase

只好用搜索引擎继续搜索,看到有人提出可以先使用  rebase  把多个提交合并成一个提交,再使用 revert 产生一次反提交,这种方法的思路非常清晰,把 revert 和 rebase 两个命令搭配得很好,相当于使用 revert 回退的升级版。
先说一下 rebase,rebase 是”变基”的意思,这里的”基”,在我理解是指[多次] commit 形成的 git workflow,使用 rebase,我们可以改变这些历史提交,修改 commit 信息,将多个 commit 进行组合。
介绍 rebase 的文档有很多,我们直接来说用它来进行代码回退的步骤。
  1. 首先,切出一个新分支 F,使用 git log 查询一下 要回退到 的 commit 版本 N。
  2. 使用命令   git rebase -i N , -i 指定交互模式后,会打开 git rebase 编辑界面,形如:
    pick 6fa5869 commit1
    pick 0b84ee7 commit2
    pick 986c6c8 commit3
    pick 91a0dcc commit4
  3. 这些 commit 自旧到新由上而下排列,我们只需要在 commit_id 前添加操作命令即可。

    在合并 commit 这个需求里,我们可以选择 pick(p) 最旧的 commit1,然后在后续的 commit_id 前添加 squash(s) 命令,将这些 commits 都合并到最旧的 commit1 上。

  4. 保存 rebase 结果后,再编辑 commit 信息,使这次 rebase 失效,git 会将之前的这些 commit 都删除,并将其更改合并为一个新的 commit5

    如果出错了,也可以使用 git rebase --abort/--continue/--edit-todo 对之前的编辑进行撤销、继续编辑。

  5. 这个时候,主分支上的提交记录是  older, commit1, commit2, commit3, commit4
    而 F 分支上的提交记录是  older, commit5 ,由于 F 分支的祖先节点是 older,明显落后于主分支的 commit4,将 F 分支向主分支合并是不允许的

    所以我们需要执行 git merge master 将主分支向 F 分支合并,合并后 git 会发现 commit1 到 commit4 提交的内容和 F 分支上 commit5 的修改内容是完全相同的,会自动进行合并,内容不变,但多了一个 commit5。

  6. 再在 F 分支上对 commit5 进行一次 revert 反提交,就实现了把 commit1 到 commit4 的提交全部回退。

这种方法的取巧之处在于巧妙地利用了 rebase 操作历史提交的功能和 git 识别修改相同自动合并的特性,操作虽然复杂,但历史提交保留得还算完整。
rebase 这种修改历史提交的功能非常实用,能够很好地解决我们遇到的一个小功能提交了好多次才好使,而把 git 历史弄得乱七八糟的问题,只需要注意避免在多人同时开发的分支使用就行了。
遗憾的是,当天我并没有理解到 rebase 的这种思想,又由于试了几个方法都不行太过于慌乱,在 rebase 完成后,向主分支合并被拒之后对这些方式的可行性产生了怀疑,又加上有同事提出听起来更可行的方式,就中断了操作。

文件操作

这种更可行的方式就是对文件操作,然后让 git 来识别变更,具体是:
  1. 从主分支上切出一个跟主分支完全相同的分支 F。

  2. 从文件管理系统复制项目文件夹为 bak,在 bak 内使用 git checkout N 将代码切到想要的历史提交,这时候 git 会将 bak 内的文件恢复到 N 状态。

  3. 在从文件管理系统内,将 bak 文件夹下 除了 .git 文件夹下的所有内容复制粘贴到原项目目录下。git 会纯从文件级别识别到变更,然后更新工作区。

  4. 在原项目目录下执行 add 和 commit,完成反提交。

这种方式的巧妙之处在于利用 git 本身对文件的识别,不牵涉到对 workflow 操作。

小结

最后终于靠着文件操作方式成功完成了代码回退,事后想来真是一把心酸泪。
为了让我的五个小时不白费,复盘一下当时的场景,学习并总结一下四种代码回退的方式:
  • revert 适合需要回退的历史提交不多,且无合并冲突的情景。

  • 如果你可以向 master 强推代码,且想让 git log 里不再出现被回退代码的痕迹,可以使用 git reset --hard + git push --force 的方式。

  • 如果你有些 geek,追求用”正规而正统”的方式来回退代码,rebase + revert 满足你的需求。

  • 如果你不在乎是否优雅,想用最简单,最直接的方式,文件操作正合适。

git 真的是非常牛逼的代码管理工具,入手简单,三五个命令组合起来就足够完成工作需求,又对 geeker 们非常友好,你想要的骚操作它都支持,学无止境啊。
        
            


-END-




推荐阅读



【01】GitHub 上100个优质前端项目整理,非常全面!
【02】这位小姐姐用动图展示了10个Git命令,看完过目不忘!
【03】重磅!一次登录,终身免费:GitHub宣布向所有人免费开放所有核心功能
【04】Github上这几个沙雕项目,够我玩三天!
【05】工程师深度:嵌入式项目开发的 Git & GitHub 实用教程


免责声明:整理文章为传播相关技术,版权归原作者所有,如有侵权,请联系删除
嵌入式ARM 关注这个时代最火的嵌入式ARM,你想知道的都在这里。
评论 (0)
  • ​在为期三天的上海国际嵌入式展会中,树莓派和上海晶珩一起展示了众多的基于树莓派和CODESYS的解决方案,没去过展会现场的小伙伴千万别错过这篇文章!视频地址:https://www.bilibili.com/video/BV1c1421k7ne/?vd_source=a637ced2b66f15709d16fcbaceeb47a9这个基于Raspberry Pi 5的嵌入式系统解决方案集成了16个EtherCAT总线控制的步进电机,旨在实现高性能的多轴运动控制。Raspberry Pi 5作为核
    树莓派开发者 2024-06-21 14:29 69浏览
  • ​Raspberry Pi 已在伦敦证券交易所上市,股票代码为 Raspberry Pi Holdings plc。这是 Raspberry Pi 的分水岭,也是发展新阶段的开始:进入公开市场将使树莓派能够更快地制造出更多我们喜爱的产品。Raspberry Pi 基金会在首次公开募股中筹得的资金将支持其在第二个十年中影响全球的雄心壮志;有关首次公开募股对基金会意味着什么的更多信息,请点击这里查看菲利普的博文。博文地址:https://www.raspberrypi.org/blog/what-w
    树莓派开发者 2024-06-20 15:15 85浏览
  • 电脑显示器已逐渐成为现代人时常会接触到的3C产品,能带给消费者愉快的视听娱乐,不管是看电影、追剧、听音乐放松心情,或是玩一场紧张刺激的电竞游戏。忙碌之余,能够偶尔享受闲暇时光,也是一种释放。 您是否也曾遇过,在享受电影或游戏的过程当中,显示器带给我们的影像和声音突然出现不协调的情况呢?这就像是两者间没有互相搭配好,节奏步调变得不一样!这种情况我们称为「影音延迟」或「影音不同步」。 当这类问题持续发生时,无法好好享受电影或者追剧,会让人心情烦躁。对于电竞玩家来说更是硬伤,除了分心、受干扰外,更
    百佳泰测试实验室 2024-06-20 15:55 105浏览
  •  经过近几年的618大促之后,如今的618已经被默认的低价竞争给包围了。随着低价竞争的持续蔓延,曾经积极参与其中的一些品牌商,态度也从积极转为消极;各种被“忽悠”的消费者,也在想着法逃离电商平台设置的套路。与此同时,不甘心被大主播绑架的电商平台,与胃口不断加大的头部主播,开始展开极限拉扯。以往热闹的618,如今变成了各路参与者的围城,渴望进去的不停向里面张望,渴望出来的则变着法地希望,跳出618这个牢笼。虚假繁荣背后的暗流涌动在直播电商红利之下,抖音、淘宝、京东、唯品会等各路平台,在直
    刘旷 2024-06-21 09:58 98浏览
  • 随着汽车电子技术的发展,车辆上配备了越来越多的电子装置,这些设备多采用点对点的方式通信,这也导致了车内存在庞大的线束。造成汽车制造和安装的困难并进一步降低汽车的配置空间。因此,汽车总线逐步开始向网络化方向发展。在此背景下,CAN(Controller Area Network)总线应运而生,以其高可靠性和灵活性,成为汽车通信系统中不可或缺的一部分,承载着车辆控制、监控和诊断等关键任务。一、技术演进:从CAN到CAN FD随着技术的持续发展,传统的CAN总线在数据传输速率和带宽上逐渐显现出局限性。
    康谋 2024-06-20 13:55 73浏览
  • 翻新料指的是通过回收旧的或废弃的电子元器件,经过修整、清洁、测试等过程,使其看起来像是新的元器件,并重新投入市场销售使用的一种元器件。这些翻新料在电子元器件市场中并不少见,但由于其质量和性能无法保证,使用翻新料可能存在一定风险。翻新料的来源回收的旧电子设备:例如废弃的计算机、手机、电器等。生产过程中淘汰的次品:一些在生产过程中被淘汰的次品通过修整再次销售。售后维修过程中更换下来的旧件:如保修或维修拆下的元器件。翻新过程回收:通过各种渠道回收旧的或废弃的电子元器件。清洁:对回收的元器件进行清洁,去
    大鱼芯城 2024-06-20 12:09 137浏览
  • 在汽车的复杂电路网络中,仪表网关扮演着信息枢纽的角色。对于驾校使用大众朗逸车主而言,了解仪表网关的位置不仅有助于日常维护,更是故障诊断和车辆升级的关键所在。大众朗逸作为一款深受消费者喜爱的车型,凭借其稳定的性能和经济的油耗赢得了广泛的市场认可。然而,即便是这样一款优秀的车型,在驾校使用过程中也难免会遇到一些技术问题,这时候对仪表网关的了解就显得尤为重要。18年后的大众,网关都是标配,直接从OBD通过CAN监听是没有数据报文对外发出的,不是没有,而是避开诊断请求,这个后边说。朗逸CAN总线技术的引
    lauguo2013 2024-06-21 08:18 74浏览
  • GPIO的功率、电压和电流取决于具体的GPIO类型和配置。 GPIO(General Purpose Input/Output)通用型输入输出端口,是一种多功能的电子接口,广泛应用于微控制器、微处理器以及各种电子设备中,用于读取或输出信号。理解GPIO的功率、电压和电流的相关特性是进行电子电路设计和编程的基础。这些参数决定了GPIO端口能安全处理的电量,以及它与其他电子组件交互时的兼容性。 从电压角度来看,GPIO端口通常设计有一定的耐压限度,这意味着它们可以安全地在特定的电压范围内工作。例
    丙丁先生 2024-06-21 17:43 78浏览
  • 站上风口,交付量狂飙,装机量翻番……是什么让LiDAR再次“翻红”? 一波三折。如果要用一个词形容近两年的激光雷达市场,恐怕它最为合适。人类纪元,2022年。开启量产元年的车载激光雷达,一度风光无限。当时OEM厂商对激光雷达关键指标提升的需求仿佛“军备竞赛”。加速批量上车,进一步控制成本,将其控制在500美元左右……那一年,产业链上下游众志成城,万众一心。转眼到了2023年,车企在面向ADAS和自动驾驶的感知技术上逐渐分化成两派,纯视觉路线的落地以及价格战带来的降本压力,让很多车企出现
    艾迈斯欧司朗 2024-06-21 17:10 70浏览
  • TT电机(直流电机)的功率、电压、电流、瞬间启动电压和电流是其运行的关键参数。这些参数决定了电机的性能和适用场景**。在探讨TT电机的这些特性时,需要综合考虑其电气特性以及启动和运行条件。以下将逐一解析这些关键参数: 1. 功率:    - TT电机的功率通常取决于其设计和应用场景。例如,普通TT电机的额定功率可以在几瓦到几十瓦不等[^4^]。    - 对于不同的TT电机型号,如370电机和310电机,它们的功率输出也会有所不同。例如,370电机通常适
    丙丁先生 2024-06-21 17:18 66浏览
  • 反激电源包含原边反激何副边反激,原边反馈动态响应比副边反馈慢,但是相对成本低,无论是原边反馈还是副边反馈由于反激电源电路简单,成本低广泛的用在在电动两轮车Escooter,电动工具,打印机,清洁电器等充电场景,也广泛的应用在电表,家电,新能源等场景作为辅助电源给芯片供电,下面就以无锡明芯微的MX1210E作为例子详细的介绍下一款24v2.5A的一个方案,从该方案来看输入口有NTC防止过流,采用10D561K 的压敏作输入过压保护,有个滤波的0.47uF的X电容并采用分压电阻做X电容放电,串联差模
    王萌 2024-06-21 09:27 235浏览
  • 1. 版权保护芯片RJGT102介绍为了防止硬件电路与固件被抄袭,核心在于加密芯片和安全解决方案的设计,目前大多MPU并不具备安全防护功能,所以最好的办法是使用一颗专用的加密芯片,通过加密芯片对接MPU,进行认证,授权,保存关键数据等。RJGT102采用了SHA256对称加密算法,256位的大数加密, 加密算法强度高。每片RJGT102都有唯一的客户编码,非常适合做防抄板,防抄软件,管控工厂生产数量,防止方案外泄等。参与SHA256运算的数据为:8字节Key(可动态更换),8
    万象奥科 2024-06-20 17:37 64浏览
  • Matter是连接标准联盟(CSA)所推出的统一连接标准,旨在让不同品牌的智能装置可以互通互联。并且支持包含Wi-Fi、Ethernet、Thread和Bluetooth等多种连接协议。 随着Matter被广泛运用于智能家居生态圈,目前Apple Homekit、Amazon Alexa、Google Home和Samsung SmartThings等智能语音助理都已支持Matter。然而,要是网络服务供货商的网络突然断线了,家里的智能装置是否还能正常操作?还是必需连接到外部网络才能控制智能装
    百佳泰测试实验室 2024-06-20 15:40 113浏览
  • 随着时代的飞速发展,新能源汽车以其绿色环保、能效高等特点在全球范围内迅速普及。然而,伴随着这一进程的不断推进,我们不得不面对一个前所未有的现实——新能源汽车的第一波动力系统已步入了报废的爆发期。积尽六年繁华,不过弹指刹那,2024,标志着新能源汽车生命周期管理的新阶段,对于整个行业乃至社会的影响深远且复杂。新能源汽车的推广始于对传统燃油车引起的环境问题的担忧和对可再生能源利用的追求。经过多年的发展,早期的电动车电池技术已经难以满足当前的需求,电池寿命终结成为用户面临的直接问题。随之而来的,是大量
    lauguo2013 2024-06-20 14:23 78浏览
  • 随着科技的进步不断更迭,电子设备的传输速度越来越快,时至今日对于高速传输带宽的要求也愈来愈高。印刷电路板(PCB,以下简称PCB) 在高速传输接口中扮演不可或缺的角色,其高频特性直接影响了整体传输效能。高频特性是指PCB在高频率下的电气性能,包括阻抗、插入损耗、回波损耗、群延迟等。这些参数会影响信号的传输速度、完整性和可靠性。 PCB潜在风险 你知道吗?如果PCB的高频特性不佳时,可能会导致以下问题: 信号传输速度变慢信号衰减增加信号反射增加信号失真 这些问题都会影响电子设备的性能,甚至
    百佳泰测试实验室 2024-06-20 16:05 114浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦