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,你想知道的都在这里。
评论
  • 日前,商务部等部门办公厅印发《手机、平板、智能手表(手环)购新补贴实施方案》明确,个人消费者购买手机、平板、智能手表(手环)3类数码产品(单件销售价格不超过6000元),可享受购新补贴。每人每类可补贴1件,每件补贴比例为减去生产、流通环节及移动运营商所有优惠后最终销售价格的15%,每件最高不超过500元。目前,京东已经做好了承接手机、平板等数码产品国补优惠的落地准备工作,未来随着各省市关于手机、平板等品类的国补开启,京东将第一时间率先上线,满足消费者的换新升级需求。为保障国补的真实有效发放,基于
    华尔街科技眼 2025-01-17 10:44 87浏览
  • 晶台光耦KL817和KL3053在小家电产品(如微波炉等)辅助电源中的广泛应用。具备小功率、高性能、高度集成以及低待机功耗的特点,同时支持宽输入电压范围。▲光耦在实物应用中的产品图其一次侧集成了交流电压过零检测与信号输出功能,该功能产生的过零信号可用于精确控制继电器、可控硅等器件的过零开关动作,从而有效减小开关应力,显著提升器件的使用寿命。通过高度的集成化和先进的控制技术,该电源大幅减少了所需的外围器件数量,不仅降低了系统成本和体积,还进一步增强了整体的可靠性。▲电路示意图该电路的过零检测信号由
    晶台光耦 2025-01-16 10:12 84浏览
  • 实用性高值得收藏!! (时源芯微)时源专注于EMC整改与服务,配备完整器件 TVS全称Transient Voltage Suppre,亦称TVS管、瞬态抑制二极管等,有单向和双向之分。单向TVS 一般应用于直流供电电路,双向TVS 应用于电压交变的电路。在直流电路的应用中,TVS被并联接入电路中。在电路处于正常运行状态时,TVS会保持截止状态,从而不对电路的正常工作产生任何影响。然而,一旦电路中出现异常的过电压,并且这个电压达到TVS的击穿阈值时,TVS的状态就会
    时源芯微 2025-01-16 14:23 128浏览
  • 电竞鼠标应用环境与客户需求电竞行业近年来发展迅速,「鼠标延迟」已成为决定游戏体验与比赛结果的关键因素。从技术角度来看,传统鼠标的延迟大约为20毫秒,入门级电竞鼠标通常为5毫秒,而高阶电竞鼠标的延迟可降低至仅2毫秒。这些差异看似微小,但在竞技激烈的游戏中,尤其在对反应和速度要求极高的场景中,每一毫秒的优化都可能带来致胜的优势。电竞比赛的普及促使玩家更加渴望降低鼠标延迟以提升竞技表现。他们希望通过精确的测试,了解不同操作系统与设定对延迟的具体影响,并寻求最佳配置方案来获得竞技优势。这样的需求推动市场
    百佳泰测试实验室 2025-01-16 15:45 185浏览
  • 80,000人到访的国际大展上,艾迈斯欧司朗有哪些亮点?感未来,光无限。近日,在慕尼黑electronica 2024现场,ams OSRAM通过多款创新DEMO展示,以及数场前瞻洞察分享,全面展示自身融合传感器、发射器及集成电路技术,精准捕捉并呈现环境信息的卓越能力。同时,ams OSRAM通过展会期间与客户、用户等行业人士,以及媒体朋友的深度交流,向业界传达其以光电技术为笔、以创新为墨,书写智能未来的深度思考。electronica 2024electronica 2024构建了一个高度国际
    艾迈斯欧司朗 2025-01-16 20:45 91浏览
  • 百佳泰特为您整理2025年1月各大Logo的最新规格信息,本月有更新信息的logo有HDMI、Wi-Fi、Bluetooth、DisplayHDR、ClearMR、Intel EVO。HDMI®▶ 2025年1月6日,HDMI Forum, Inc. 宣布即将发布HDMI规范2.2版本。新规范将支持更高的分辨率和刷新率,并提供更多高质量选项。更快的96Gbps 带宽可满足数据密集型沉浸式和虚拟应用对传输的要求,如 AR/VR/MR、空间现实和光场显示,以及各种商业应用,如大型数字标牌、医疗成像和
    百佳泰测试实验室 2025-01-16 15:41 134浏览
  • 数字隔离芯片是现代电气工程师在进行电路设计时所必须考虑的一种电子元件,主要用于保护低压控制电路中敏感电子设备的稳定运行与操作人员的人身安全。其不仅能隔离两个或多个高低压回路之间的电气联系,还能防止漏电流、共模噪声与浪涌等干扰信号的传播,有效增强电路间信号传输的抗干扰能力,同时提升电子系统的电磁兼容性与通信稳定性。容耦隔离芯片的典型应用原理图值得一提的是,在电子电路中引入隔离措施会带来传输延迟、功耗增加、成本增加与尺寸增加等问题,而数字隔离芯片的目标就是尽可能消除这些不利影响,同时满足安全法规的要
    华普微HOPERF 2025-01-15 09:48 162浏览
  • 近期,智能家居领域Matter标准的制定者,全球最具影响力的科技联盟之一,连接标准联盟(Connectivity Standards Alliance,简称CSA)“利好”频出,不仅为智能家居领域的设备制造商们提供了更为快速便捷的Matter认证流程,而且苹果、三星与谷歌等智能家居平台厂商都表示会接纳CSA的Matter认证体系,并计划将其整合至各自的“Works with”项目中。那么,在本轮“利好”背景下,智能家居的设备制造商们该如何捉住机会,“掘金”万亿市场呢?重认证快通道计划,为家居设备
    华普微HOPERF 2025-01-16 10:22 148浏览
  • 随着智慧科技的快速发展,智能显示器的生态圈应用变得越来越丰富多元,智能显示器不仅仅是传统的显示设备,透过结合人工智能(AI)和语音助理,它还可以成为家庭、办公室和商业环境中的核心互动接口。提供多元且个性化的服务,如智能家居控制、影音串流拨放、实时信息显示等,极大提升了使用体验。此外,智能家居系统的整合能力也不容小觑,透过智能装置之间的无缝连接,形成了强大的多元应用生态圈。企业也利用智能显示器进行会议展示和多方远程合作,大大提高效率和互动性。Smart Display Ecosystem示意图,作
    百佳泰测试实验室 2025-01-16 15:37 138浏览
  • 一个易用且轻量化的UI可以大大提高用户的使用效率和满意度——通过快速启动、直观操作和及时反馈,帮助用户快速上手并高效完成任务;轻量化设计则可以减少资源占用,提升启动和运行速度,增强产品竞争力。LVGL(Light and Versatile Graphics Library)是一个免费开源的图形库,专为嵌入式系统设计。它以轻量级、高效和易于使用而著称,支持多种屏幕分辨率和硬件配置,并提供了丰富的GUI组件,能够帮助开发者轻松构建出美观且功能强大的用户界面。近期,飞凌嵌入式为基于NXP i.MX9
    飞凌嵌入式 2025-01-16 13:15 137浏览
  • 随着消费者对汽车驾乘体验的要求不断攀升,汽车照明系统作为确保道路安全、提升驾驶体验以及实现车辆与环境交互的重要组成,日益受到业界的高度重视。近日,2024 DVN(上海)国际汽车照明研讨会圆满落幕。作为照明与传感创新的全球领导者,艾迈斯欧司朗受邀参与主题演讲,并现场展示了其多项前沿技术。本届研讨会汇聚来自全球各地400余名汽车、照明、光源及Tier 2供应商的专业人士及专家共聚一堂。在研讨会第一环节中,艾迈斯欧司朗系统解决方案工程副总裁 Joachim Reill以深厚的专业素养,主持该环节多位
    艾迈斯欧司朗 2025-01-16 20:51 84浏览
  • 全球领先的光学解决方案供应商艾迈斯欧司朗(SIX:AMS)近日宣布,与汽车技术领先者法雷奥合作,采用创新的开放系统协议(OSP)技术,旨在改变汽车内饰照明方式,革新汽车行业座舱照明理念。结合艾迈斯欧司朗开创性的OSIRE® E3731i智能LED和法雷奥的动态环境照明系统,两家公司将为车辆内饰设计和功能设立一套全新标准。汽车内饰照明的作用日益凸显,座舱设计的主流趋势应满足终端用户的需求:即易于使用、个性化,并能提供符合用户生活方式的清晰信息。因此,动态环境照明带来了众多新机遇。智能LED的应用已
    艾迈斯欧司朗 2025-01-15 19:00 71浏览
  • 故障现象 一辆2007款法拉利599 GTB车,搭载6.0 L V12自然吸气发动机(图1),累计行驶里程约为6万km。该车因发动机故障灯异常点亮进厂检修。 图1 发动机的布置 故障诊断接车后试车,发动机怠速轻微抖动,发动机故障灯长亮。用故障检测仪检测,发现发动机控制单元(NCM)中存储有故障代码“P0300 多缸失火”“P0309 气缸9失火”“P0307 气缸7失火”,初步判断发动机存在失火故障。考虑到该车使用年数较长,决定先使用虹科Pico汽车示波器进行相对压缩测试,以
    虹科Pico汽车示波器 2025-01-15 17:30 87浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦