软件协作开发方法论

news2025/1/17 15:18:20

引言

作为程序员,你是否有过这样的经历?软件发版前,你需要把你的代码合并到主分支,拉取主分支代码后,发现有数十个文件冲突,你开始小心翼翼地解决冲突,有些其实你也不知道咋处理,几番确认后,最后终于提交上去了。之后测试人员对主干代码进行测试,还是发现了一个之前别人已经解决过的Bug,之后别人就找你了,质问你为什么把他的代码合丢了。。。

最要命的是,这种事情每隔一两个月就会发生一次,每次弄得大家都很痛苦,有时着急发版本,但是因为代码中的大量冲突却总是拖后腿,甚至遇到大版本发布,解决冲突就要耗费长达一两天的时间,团队也因此加班,并出现版本发布Delay。

有时,我们会想,有没有好方法能解决这个问题,要是不出现那么多代码冲突就好了。

当然有,如果我们把各个服务对应的代码仓库或者模块拆分得比较细,每个人单独负责一两个代码仓库或者模块,每位程序员在一个版本周期内,只会修改自己单独负责的代码,这样就不冲突了嘛。

是的,模块职责拆分得越清晰,版本周期越短(比如一周一个版本),冲突的概率就会越小,上面的问题也越容易解决。但是,我们无法避免一份代码库由多个人维护,尤其是现在大仓很流行,被视为卓越工程水平的体现,版本周期需要尽可能短,但是项目制推进的大版本,或者研发团队很多人的时候,代码合并时冲突的概率还是很大。

其实,不只是代码合并冲突问题,线上问题如何修复,新功能开发时团队如何选择分支,这就需要我们选择一个适合团队的分支策略来解决。只有明确了这些规则,团队才能基于共同的代码仓库来高效工作。

分支策略一般会规定基于哪个分支进行需求迭代、基于哪个分支来发布版本;如果线上出现问题,基于哪个分支进行修复,修复后如何同步该修复到相关分支;不同的部署环境采取什么样的分支策略等等。分支策略是多人软件协作开发的灵魂,基于此可以构建代码提交、审核、集成、测试、发布等工作流程,进而形成优秀的软件协作模式和发布模式,选择一个适合团队的分支策略对于DevOps的实践落地大有裨益。

总之,分支策略不仅能够帮助我们解决代码合并冲突,更能够规避因此带来的质量、效率问题。实质上,分支策略关乎产品、研发、测试和运维人员的整个研发协作流程,好的分支策略可以帮助我们建立产品协作开发的规范,提升软件交付效率,让研发人员更多的时间投入需求开发等真正创造价值的活动中,而不是解决代码冲突,也让我们可以清楚了解到代码改动关联什么需求、当前的哪个代码版本是稳定可靠的,增强团队的交付信心。

一、分支策略

分支策略大致可以分为主干开发和特性分支开发,主干开发包括分支发布和主干发布两种,而我们熟知的Git Flow、GitHub Flow以及GitLab Flow都是属于特性分支开发。如下图所示:
在这里插入图片描述

主干开发

在主干开发模式中,团队将所有的工作直接在主分支(通常命名为 master 或 trunk)上完成。主干发布的核心理念是快速、频繁地将代码变更合并至主分支,确保主分支始终处于可随时发布的状态。这种模式尤其适用于那些采用持续集成与持续部署(CI/CD)实践的敏捷团队,通过自动化测试和部署流水线,实现高效且低风险的版本迭代。

在主干发布的场景下,当线上出现紧急问题时,开发者可以直接在主分支上进行热修复,修复完成后立即部署上线。但这也要求团队具备较高的自动化测试覆盖率和高效的代码审查机制,以保证主分支代码的质量和稳定性。

主干开发又可分为分支发布主干发布两种。

主干开发----分支发布

采用主干开发,一般在发布时会拉取发布分支,问题修复先提交到 trunk 主分支,之后再合并到release发布分支进行发布。如下图所示[1]:
在这里插入图片描述

主干开发----主干发布

更彻底的做法是,直接在 trunk 分支发布,这通常需要完善的流程、工具链和高质量的自动化测试保障质量。GitHub、Etsy、Netflix等公司都是采用这种方式。这个方式笔者认为比较极端,就一个主分支,发布的时候也采用主分支发布。

在这里插入图片描述

特性分支开发

Git Flow

从Develop开发分支拉取一条Feature分支,开发团队在Feature分支上进行新功能开发;开发完成后,将Feature分支合入到Develop分支,并进行开发环境的验证;开发环境验证完成,从Develop分支拉取一条Release分支,到测试环境进行SIT/UAT测试;测试无问题后,可将Develop分支合入Master分支,待发版时,直接将Master分支代码部署到生产环境。如下图所示[2]:
在这里插入图片描述
Git Flow的优点是每个分支都有明确的定义,严格按照GitFlow管理项目代码的话,很难出现代码混乱;其缺点是:如果特性分支过多的话很容易造成代码冲突,从而提高了合入的成本;由于每次提交都涉及多个分支,所以Git Flow也不太适合提交频率较高的项目

GitHub Flow

GitHub Flow 来源于GitHub团队的工作实践,这个模型中,通常只有一个Master分支是固定的,而且GitHubFlow中的Master分支通常是受保护的,只有特定权限的人才可以向Master分支合入代码。

在GitHub Flow中,新功能开发或修复Bug需要从Master分支拉取一个新分支,在这个新分支上进行代码提交;功能开发完成,开发者创建Pull Request(简称PR),通知源仓库开发者进行代码修改review,确认无误后,将由源仓库开发人员将代码合入Master分支。

很多人可能会问,提交代码通常是commit或者push,拉取代码才是pull,为什么GitHubFlow中提交代码提出的是“Pull Request”。因为在GitHubFlow中,PR是通知其他人员到你的代码库去拉取代码至本地,然后由他们进行最终的提交,所以用“pull”而非“push”[5]。大致流程如如下图所示[4]:
在这里插入图片描述
GitHubFlow优点是相对于GitFlow来说比较简单,其缺点是因为只有一条Master分支,万一代码合入后,由于某些因素Master分支不能立刻发布,就可能会影响发布。另外,每个特性都Fork代码仓库对于企业来说也过于繁琐,这种方式更适合开源项目。

GitLab Flow

GitLabFlow出现的最晚,GitLabFlow是开源工具GitLab推荐的做法[6]。GitLabFlow支持GitFlow的分支策略,也支持GitHubFlow的“Pull Request”(在GitLabFlow中被称为“Merge Request”)。

相比于GitHub Flow,GitLabFlow增加了对预生产环境和生产环境的管理,即Master分支对应为开发环境的分支,预生产和生产环境由其他分支(如Pre-Production、Production)进行管理。在这种情况下,Master分支是Pre-Production分支的上游,Pre-Production是Production分支的上游;GitLabFlow规定代码必须从上游向下游发展,即新功能或修复Bug时,特性分支的代码测试无误后,必须先合入Master分支,然后才能由Master分支向Pre-Production环境合入,最后由Pre-Production合入到Production。具体如下图所示[4]:
在这里插入图片描述
GitLab Flow中的Merge Request是将一个分支合入到另一个分支的请求,通过Merge Request可以对比合入分支和被合入分支的差异,也可以做代码的Review。

需要发布版本时,GitLab Flow提倡先创建一个stable分支,之后修复bug先合并到Master分支,之后再合入到stable分支。如下图所示[6]:
在这里插入图片描述

特性分支组合发布

阿里云效的分支模式如下图所示[7]。基于 master 分支最新版本创建 feature 分支。然后在 feature 分支上开发、测试,直到这个 feature 功能完成,质量 OK,准备好去集成和发布。release 分支用于集成和发布。基于 master 分支最新版本创建一条 release 分支,然后把想要集成的各条feature分支合并到这条release分支,进行部署和测试工作。当 release 分支上的质量足够好,本次想上线的功能也都具备之后,就要考虑发布上线的问题啦。如前面讲的,发布上线前,会确保它基于基础分支(常见的如 master )最新。而发布后会把 release 分支合并回 master,让 master 代表最新发布版本。
在这里插入图片描述

二、几种分支策略的比较

DevOps倡导主干开发[8],然后主干开发也对开发人员提出了很高的要求,个人觉得真正落地还是比较难的。在此也对比下各个分支模式的优缺点,根据优缺点,大家可自行根据团队情况选取,也可结合不同分支模式使用。
在这里插入图片描述

三、特性分支开发+主干发布的分支策略

笔者推荐一种普适性比较高的分支策略
基本流程如下:

  1. A同学要开始需求 f1 的开发,从代码仓库A的 dev分支 中检出 feature-f1 分支,开始开发;B同学负责相关需求 f2,也从代码仓库A dev分支 中检出 feature-f2 分支;C同学是需求 f1 的下游,由于公司采用的微服务架构,并且独立代码仓库,所以从代码仓库 C dev 分支中检出 feature-f1 分支。

  2. A、B、C三位同学都有良好的持续集成意识,每天都从dev拉取最新代码,由于拉取频次高,且一个代码仓库基本上只有2、3位同学负责,所以冲突很少。

  3. A、B、C三位同学完成单元测试、分支测试后,把代码提交Code Review,Review通过后,按需提交测试人员进行分支测试,之后代码合并到dev分支。

  4. 合入到dev分支后,提交测试人员进行测试,如果发现Bug,就在各自的特性分支修改验证通过后,再合入到dev分支。

  5. dev分支验证通过后,代码合入master分支,master分支作为稳定分支,时刻都能进行发布,之后打Tag,部署到预发布环境中验证。如果预发布环境中验证出现问题,就还把修改提交到特性分支,之后dev验证,通过后再合入master,出新Tag,部署到预发布环境中再次验证。

  6. 预发布环境验证通过后,使用验证过的Tag,灰度发布到生产环境,之后全量部署到生产环境。

  7. 如果生产环境发布过程中发现问题,或者线上出现紧急严重Bug,可以从Master分支或者生产部署的tag检出Hotfix分支,之后部署到预发布环境进行验证,验证通过后部署到生产,确认已修复,再把本次提交合并到master和dev分支。

  8. 如果生产环境发现非紧急问题需要修复,当新特性/缺陷处理,从dev分支检出feature-xxx分支,之后按照上述流程上线发布即可。

流程图如下所示:
在这里插入图片描述
当然了,只有分支策略还不够,更重要当然是人了。所以要求开发团队有一定的纪律性,分支策略一定要结合团队纪律来使用,包括如下几个方面:

1、短分支:特性分支的存活时间要短,一般认为不要超过3天,最长不超过1周。

2、尽早集成:尽可能早地集成到主干分支。

3、微服务:微服务切分也是减少冲突的重要基础,一人一个服务或者一人一个模块,肯定不会冲突。

4、合入前充分测试:尽可能保障dev分支的代码质量,master分支更是要保障随时都能分布,发现有Bug应第一时间修复。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1682642.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Cloud Alibaba-08-SMS短信服务

Lison <dreamlison163.com>, v1.0.0, 2024.5.1 Spring Cloud Alibaba-08-SMS短信服务 短信服务介绍 短信服务(Short Message Service)是阿里云为用户提供的一种通信服务的能力。 产品优势:覆盖全面、高并发处理、消息堆积处理、开发管理简单、智能监控调度 产品功能:短…

linux 排查java内存溢出(持续更新中)

场景 tone.jar 启动后内存溢出,假设pid 为48044 排查 1.确定java程序的pid(进程id) ps 或 jps 都可以 ps -ef | grep tone jps -l 2.查看堆栈信息 jmap -heap 48044 3.查看对象的实例数量显示前30 jmap -histo:live 48044 | head -n 30 4.查看线程状态 jstack 48044

5.23 学习总结

一.项目优化&#xff08;语音通话&#xff09; 实现步骤&#xff1a; 1.用户发送通话申请&#xff0c;并处理通话请求&#xff0c;如果同意&#xff0c;为两个用户之间进行连接。 2.获取到电脑的麦克风和扬声器&#xff0c;将获取到的语音信息转换成以字节数组的形式传递。 …

宇宙“超级地球”系列,你知道几个?

在宇宙中&#xff0c;可能存在着类地行星&#xff0c;这样的行星可能同样也拥有适宜生命存在的条件。银河系大约有60亿颗类地行星。 开普勒442b 这是脱离太阳系以后&#xff0c;人类发现的第二颗离地球最近的类地行星。开普勒442b这颗类地行星位于天鹅座&#xff0c;离地球约有…

机器学习势系列教程(3):cp2k的安装

大家好&#xff0c;我是小马老师。 本文继续介绍机器学习势相关内容&#xff1a;cp2k的安装。 和abacus一样&#xff0c;cp2k也是一款开源的第一性原理模拟软件&#xff0c;模拟的数据也可作为机器学习势的训练数据集。 cp2k安装方法也很多&#xff0c;常见的有docker安装、…

数据可视化第十天(爬虫爬取某瓣星际穿越电影评论,并且用词云图找出关键词)

开头提醒 本次爬取的是用户评论&#xff0c;只供学习使用&#xff0c;不会进行数据的传播。希望大家合法利用爬虫。 获得数据 #总程序 import requests from fake_useragent import UserAgent import timefuUserAgent()headers{User-Agent:fu.random }page_listrange(0,10) …

AI绘画Stable diffusion小白入门:文生图精讲,超全干货一定要看!

大家好&#xff0c;我是设计师阿威 今天&#xff0c;我们将深入了解Stable diffusion的文生图功能&#xff0c;让你也能生成满意的图片&#xff01; 如上图&#xff0c;这是Stable diffusion的文生图界面&#xff0c;这个界面总体可以分为五个区域&#xff1a; 模型区&#xf…

NegativePrompt:利用心理学通过负面情绪刺激增强大型语言模型

【摘要】大型语言模型 (LLM) 已成为各种应用不可或缺的一部分&#xff0c;从传统的计算任务到高级人工智能 (AI) 应用。这种广泛的应用促使社会科学等各个学科对 LLM 进行了广泛的研究。值得注意的是&#xff0c;研究表明 LLM 具有情商&#xff0c;可以通过积极的情绪刺激进一步…

UNION的使用

UNION的使用 给出将多条查询语句组合成单个结果集&#xff0c;两个表对应的列数和数据类型必须相同 UNION操作符&#xff1a; 返回两个查询结果集的并集&#xff0c;并去除重复记录 UNION ALL操作符 返回两个查询的结果集的并集。不去掉两个结果集的重复部分&#xff0c;重…

为什么说change Buffer写缓冲区,仅适用于辅助索引页

change buffer: 写缓冲区&#xff0c;是针对于二级索引页的更新优化措施。 change Bufer作用:在进行DML操作的时候&#xff0c;如果请求的是辅助索引(非唯一索引)并且没有在缓冲池中&#xff0c;并不会立刻将磁盘页加载到缓冲池&#xff0c;而是在CB记录缓冲变 更&#xff0c…

JVM(7):虚拟机性能分析和故障解决工具之jstat工具

1 jstat(JVM Statistics Monitoring Tool)作用 监视虚拟机各种运行状态信息&#xff0c;可以显示本地或者是远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据 2 命令格式 jstat [options vmid [interval[count]]] 参数解释 第一个参数&#xff1a;options 代…

linux:信号深入理解

文章目录 1.信号的概念1.1基本概念1.2信号的处理基本概念1.3信号的发送与保存基本概念 2.信号的产生2.1信号产生的五种方式2.2信号遗留问题(core,temp等) 3.信号的保存3.1 信号阻塞3.2 信号特有类型 sigset_t3.3 信号集操作函数3.4 信号集操作函数的使用 4.信号的处理4.1 信号的…

CSS学习笔记之中级教程(三)

14、CSS 下拉菜单 14.1 示例1&#xff1a;普通弹窗 思路&#xff1a;弹窗内容先隐藏display: none;&#xff0c;:hover时候修改弹窗部分的 display: block; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><me…

IT学习笔记--Kafka

Kafka概述: 定义: Kafka是一个分布式的基于发布/订阅模式的消息队列&#xff0c;主要应用于大数据实时处理领域。 消息队列消息队列的两种模式: 点对点模式: 消息生产者生产消息发送到Queue中&#xff0c;然后消息消费者从Queue中取出并且消费消息。 消息被消费以后&#…

C语言游戏实战(12):植物大战僵尸(坤版)

植物大战僵尸 前言&#xff1a; 本游戏使用C语言和easyx图形库编写&#xff0c;通过这个项目我们可以深度的掌握C语言的各种语言特性和高级开发技巧&#xff0c;以及锻炼我们独立的项目开发能力&#xff0c; 在开始编写代码之前&#xff0c;我们需要先了解一下游戏的基本规则…

git拉取项目前需要操作哪些?

1.输入 $ ssh-keygen -t rsa -C "秘钥说明" 按enter键 2.出现 ssh/id_rsa&#xff1a;(输入也可以不输入也可以) 然后按enter键 3.出现empty for no passphrase&#xff1a;(输入也可以不输入也可以) 然后按enter键 4.出现same passphrase again: (输入也可以不输入也…

FreeRTOS_互斥量_学习笔记

互斥量 数值只有0或1 谁获得互斥量&#xff0c;就必须由谁释放同一个互斥量。 但其实在freeRTOS中&#xff0c;任务A获取的互斥锁&#xff0c;任务B也能释放。因此谁上锁谁开锁只是约定&#xff0c;在程序实现上不是强制的。 “可重入的函数"是指&#xff1a;多个任务同时…

Python筑基之旅-MySQL数据库(一)

目录 一、MySQL数据库 1、简介 2、优点 2-1、开源和免费 2-2、高性能 2-3、可扩展性 2-4、易用性 2-5、灵活性 2-6、安全性和稳定性 2-7、丰富的功能 2-8、结合其他工具和服务 2-9、良好的兼容性和移植性 3、缺点 3-1、对大数据的支持有限 3-2、缺乏全文…

OSPF路由聚合

原理概述 与RIP不同&#xff0c;OSPF不支持自动路由聚合&#xff0c;仅支持手动路由聚合。OSPF的路由聚合有两种机制&#xff1a;区域间路由聚合和外部路由聚合。区域间路由聚合必须配置在ABR路由器上&#xff0c;指的是ABR在把与自己直接相连区域&#xff08;Area&#xff09…

运营美区TikTok小店常见问题汇总,你中了几个?

大家好&#xff0c;我是IPdodo的小编&#xff0c;专注于分享出海网络解决方案&#xff0c;致力于为TikTok运营人提供解决视频0播放、直播间卡顿、不进人甚至封号等问题的跨境网络专线。目前已经帮助数千位用户成功开启跨境业务。 今天&#xff0c;将针对美区TikTok小店的常见问…