写点什么

2021Java 春招面试真题详解,Git- 如何优雅地回退代码

发布于: 2021 年 08 月 04 日

前言

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。


Sentinel 具有以下特征:


  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。

  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。

  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。

  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。


以上内容引自 Sentinel 官方介绍。在本文中,笔者将从实际应用的角度,来学习 Sentinel 的使用。


这个时候另一个可选项是在 master 分支上执行 reset,使用?--hard?选项完全抛弃这些旧代码,reset 后再强制推到远端。


master> git reset --hard commit_idmaster> 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
复制代码


  1. 这些 commit 自旧到新由上而下排列,我们只需要在 commit_id 前添加操作命令即可,在合并 commit 这个需求里,我们可以选择?pick(p)?最旧的 commit1,然后在后续的 commit_id 前添加?squash(s)?命令,将这些 commits 都合并到最旧的 commit1 上。

  2. 保存 rebase 结果后,再编辑 commit 信息,使这次 rebase 失效,git 会将之前的这些 commit 都删除,并将其更改合并为一个新的 commit5,如果出错了,也可以使用?git rebase --abort/--continue/--edit-todo?对之前的编辑进行撤销、继续编辑。

  3. 这个时候,主分支上的提交记录是?older, commit1, commit2, commit3, commit4,而 F 分支上的提交记录是?older, commit5,由于 F 分支的祖先节点是 older,明显落后于主分支的 commit4,将 F 分支向主分支合并是不允许的,所以我们需要执行?git merge master?将主分支向 F 分支合并,合并后 git 会发现 commit1 到 commit4 提交的内容和 F 分支上 commit5 的修改内容是完全相同的,会自动进行合并,内容不变,但多了一个 commit5。

  4. 再在 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 操作。

小结



最后终于靠着文件操作方式成功完成了代码回退,事后想来真是一把心酸泪。


为了让我的五个小时不白费,复盘一下当时的场景,学习并总结一下四种代码回退的方式:

最后

面试题文档来啦,内容很多,485 页!

由于笔记的内容太多,没办法全部展示出来,下面只截取部分内容展示。有想获取完整版笔记的朋友,点赞后点击这里免费领取哦

1111 道 Java 工程师必问面试题


MyBatis 27 题 + ZooKeeper 25 题 + Dubbo 30 题:



Elasticsearch 24 题 +Memcached +?Redis 40 题:



Spring 26 题+ 微服务 27 题+ Linux 45 题:



Java 面试题合集:



用户头像

还未添加个人签名 2021.07.29 加入

还未添加个人简介

评论

发布
暂无评论
2021Java春招面试真题详解,Git-如何优雅地回退代码