团队如何选择合适的Git分支策略?

news2024/11/23 23:48:10

现代软件开发过程中要实现高效的团队协作,需要使用代码分支管理工具实现代码的共享、追溯、回滚及维护等功能。目前流行的代码管理工具,包括CVS,SVN,Git,Mercurial等。

相比CVS和SVN的集中管理,Git具有非常明显的优势,例如:去中心化的代码管理方式减少了开发者对中心服务器的依赖,每个成员在本地都有一个完整的代码库,在不联网的情况下也能提交代码;不同于SVN中的每个分支具有独立的代码,Git中的每一个分支只是指向当前版本的一个指针,Git的分支策略使创建和合并分支变得快捷灵活

从百度指数,也可以看到Git的优势被越来越多的人所认可。

image.png

Git的优势#

  • Git 可以在本地进行提交以支持离线工作;
  • Git 可以在本地创建分支并且没有命名空间冲突的问题;
  • Git 可以让提交通过 Pull Request 的方式进行,不需要所有的开发者都有主仓库的写权限;
  • Git 在优化性能时选择了合并分支作为主要的性能衡量指标,将合并分支变成了成本非常低的操作以鼓励分支的使用;
  • Git 通过 SHA-1 哈希来保证仓库中数据的可靠性,通过 SHA-1 就可以对数据进行校验,抵御了来自攻击者的恶意篡改;

Git作为分布式的代码管理工具,越来越多的团队开始使用它并逐步替代集中式的SVN 或 TFVC,同时也面临新的挑战。

版本管理的挑战#

大家工作在同一个仓库上,那么彼此的代码协作必然带来很多问题和挑战,如下:

  1. 如何开始一个Feature的开发,而不影响别的Feature?
  2. 由于很容易创建新分支,分支多了如何管理,时间久了,如何知道每个分支是干什么的?
  3. 哪些分支已经合并回了主干?
  4. 如何进行Release的管理?开始一个Release的时候如何冻结Feature, 如何在Prepare Release的时候,开发人员可以继续开发新的功能?
  5. 线上代码出Bug了,如何快速修复?而且修复的代码要包含到开发人员的分支以及下一个Release?

大部分开发人员现在使用Git就只是用三个甚至两个分支,一个是Master, 一个是Develop, 还有一个是基于Develop打得各种分支。这个在小项目规模的时候还勉强可以支撑,因为很多人做项目就只有一个Release, 但是人员一多,而且项目周期一长就会出现各种问题。

Git代码分支模型#

在使用Git管理代码以及多人协作的开发模式下,一个团队甚至一个公司对Git的使用有统一规范的工作流程尤为重要。
开发团队遵循统一的规则执行功能开发,问题修复,分支合并,版本迭代及发布等操作,可以使团队合作变得平滑顺畅,项目有序向前推进,我们把组织内这样的工作流程(workflow)称为Git代码分支管理模型

主流的git代码分支管理模型:

  • Git flow
  • GitHub flow
  • GitLab flow
  • TBD flow

1. Git flow#

image.png


Git flow存在两个长期的独立分支:主分支master和开发分支develop,

  • 主分支: 用于版本发布,主分支的每个版本都是质量稳定和功能齐全的发布版。
  • 开发分支: 用于日常开发工作,存放最新的开发版代码。当开发分支的代码达到稳定状态并可以发布版本时,代码需要被合并到 master 分支,然后标记上对应的版本标签(tag)。

如果需要开发新的功能或者解决代码中的问题,则创建辅助分支来解决问题,辅助分支常用于:

  • 功能开发(Feature),
  • 版本发布(Release),
  • 问题修复(Hotfix),

在辅助分支上的工作完成后,辅助分支将被删除。

Feature分支
目的是开发新模块或新功能以满足客户需求,从develop分支创建,开发结束后只需要合并回develop分支,并不需要合并回master主分支。

Release分支
是用于准备发布的版本分支,从develop分支创建,创建时已经包含了发布所需要的所有功能,所以在这个分支上不再开发新功能,仅对这个预发布版本进行修复问题,创建文档及其他与发布相关的工作,一切就绪后将Release分支合并回master主分支并打上相应的版本号标签(Tag),同时也合并回develop分支。
创建单独的Release分支可以避免在不同发布版本上的工作互相受影响,例如团队A准备发布版本1.0的同时,团队B正在进行版本1.1的功能开发,二者相互独立,不会互相影响。

Hotfix分支
通常用于紧急修复当前发布的版本中出现的严重问题,从发布版本的标签或master主分支创建,问题修复后合并回master主分支并打上新的版本号标签(Tag),同时也合并回develop分支或者正在进行中的Release分支。
创建单独的Hotfix分支可以避免打断正在进行中的各项开发工作,客户也不需要等到下一个发布周期才能拿到修复。

优点&缺点
Git flow需要同时维护两个甚至更多分支,Hotfix分支从master创建,Release和Feature分支从develop创建,工作完成后又需要将代码合并回 develop 和 master。

在实际应用中,很多开发者会忘记合并回 develop 或者 master,并且各辅助分支之间互相独立,如果从master上pull代码不够及时,一方面可能造成某个分支长期使用已经过时或者错误的代码,另一方面如果与master相隔较远,合并分支时可能会有大量代码冲突,往往需要花费很多时间来消除代码冲突,并且非常容易出错,影响项目的持续集成。

Git flow的优点在于流程清晰,分支管理严格,适用于发布周期比较长的“版本发布”,发布周期可能是几周,几个月,甚至更长时间。
由于保持两个长期分支同步的开销较大,所以Git flow并不适用于快速的“持续发布”,ThoughtWorks还专门将Git flow列为不被推荐的技术,建议彻底停止使用。

综合考虑了开发、测试、新功能开发、临时需求、热修复,理想很丰满,现实很骨干,这一套运行起来实在是太复杂了

2. GitHub flow#

image.png

GitHub flow是由Scott Chacon于2011年提出的代码分支管理模型,这是GitHub官方推荐的开发流程,以快速部署为目标,目前大部分开源项目都遵循这一流程。

Github flow最大的特点是只有一个长期分支,即主分支master,且主分支始终保持可发布状态。
从master上创建新分支进行功能开发、问题修复等,这些分支通过pull request将代码合并到master。为了保证主分支的代码质量,master的权限只开放给一部分人。
Pull request是请求别人pull你的代码库(repository),也就是把开发分支的代码经过代码评审并通过测试后,让有权限的管理员合并回master。

不过在实际情况中,代码评审不可能检查出提交的代码中的所有问题,所以对于每次提交的代码进行自动化测试,
主分支代码的自动化部署尤其重要,自动化测试能在产品部署前及时发现一部分问题,如果产品部署之后发现严重问题,自动化部署可以在最短时间内把产品回滚到上一个版本。

优点&缺点
Github flow的优点在于流程简单灵活,不需要考虑及管理太多的分支,适用于需要快速集成及“持续发布”的项目,这类项目可能需要每天发布一个版本,甚至一天发布多个版本。但是对于应用场景比较复杂的情况,例如:多个环境下的产品部署,多个版本的发布或问题修复,只有一个master便会显得力不从心。

github flow这种方式,要保证高质量,对于贡献者的素质要求很高,换句话说,如果代码贡献者素质不那么高,质量就无法得到保证。

3. Gitlab flow#

image.png


GitLab flow是由GitLab 的 CEO Sytse Sijbrandij 于 2014 年正式发布的代码分支管理模型,属于GitHub flow的演进版本。

与GitHub相同之处是也存在一个长期主分支master,从master上创建新分支进行功能开发、问题修复等,结束后合并回master。
与GitHub不同之处是GitLab flow又考虑多环境部署等现实因素,增加production产品分支用于在不同的环境下部署产品,或者从master的稳定版本创建release发布分支用于发布软件。

如果在产品分支或者发布分支发现问题,就从对应版本分支创建修复分支,修复完成之后,GitLab flow遵循 “上游优先” 的合并策略,也就是将代码先合并到 master,再合并到下游的production或release分支。

和Github flow类似,master的修改权限只开放给部分人,开发分支的工作完成后,代码通过merge request(类似于GitHub flow中的pull request)请求有权限的管理员把代码合并(merge)回主分支

4. TBD flow#

image.png

TBD (Trunk-based Development) flow是由Paul Hammant于2013年提出的模型。

TBD flow最大的特点是所有开发都基于主干trunk,不再有长期的开发分支,要求所有的提交尽快回到主干,这样可以共享最新的代码,并且能尽可能地减少合并冲突。如果需要发布版本,可以基于trunk直接生成新的分支用于发布。

TBD flow没有pull或者push request,要求开发人员尽快把代码提交到主干分支,但是TBD flow缺乏严格的流程来保证每一份提交代码的质量,如果一些项目开发人员众多且水平不一,同时工作在主分支上可能会在产品发布时才发现不可预知的问题,

所以TBD flow更适用于需要快速迭代的产品,如果在主干分支上发现问题,可以快速进行修复再合并回主干分支。

5. TBD++ flow#


 

image.png


TBD++ flow是Arrus公司软件研发部门从2015年开始一直沿用的Git分支管理模型,产品项目的客户主要是电信级服务运营商,每个国家或地区的需求在主要功能上一致,但在客户定制化方面又存在不少差异,同时项目开发周期较长,整个周期一般在3个月到2年之间,软件产品在项目前期需要有快速的迭代,在项目后期需要有稳定的发布版本。(PS: 前面这些因素是选择该模型的重要考量因素,产品型开发,主线功能大体一致,维护客户多,发布周期固定且稍长)

TBD++ flow以敏捷开发为核心,同时吸收了以上几个主流模型的优点,主要特点如下

1. 基于功能的主分支#

只存在一个长期的独立分支,即主分支master,主分支上功能齐全,通过自动测试保证基本功能运行正常,因为自动测试覆盖不全面或者手动测试不及时,所以无法保证主分支的每个版本都是质量稳定的发布版,但是可以根据功能的完成程度直接从主分支上创建迭代版本用于针对不同客户或者不同时期的功能演示。基于master开发功能或者修复问题需要用到以下两个辅助分支:

  • Feature分支:为了开发新模块或新功能以满足客户需求,从主分支上创建Feature分支,但是并不要求Feature分支上所有的提交尽快回到主分支,开发完成并且通过代码评审及功能测试后才能合并回master主分支。为了共用主分支上的最新代码以及避免合并代码时解决代码冲突引起的额外开销,在功能开发过程中Feature分支需要始终与master保持同步。
  • Bugfix分支:基于主分支创建Bugfix分支修复主分支上发现的问题,修复完成并且通过代码评审后代码合并回master主分支。

基于主分支的Feature分支和Bugfix分支完成后,开发者直接将代码合并回主分支master,不需要像GitLab或GitHub那样依赖于少数几个有权限的管理员,这是因为如果一个项目中开发人员比较多的话,管理员没办法做到对每部分代码都熟悉或掌握,所以代码质量交由代码评审和功能测试来掌控,合并代码回主分支的操作由开发者自己完成。

主分支上的新代码有时候可能因为评审或测试不全面而带来新问题,例如破坏其他功能模块,甚至影响整体功能。为了能尽早发现问题,主分支上的每次提交都会触发系统级自动化测试,并且周期性地对主分支进行人工测试。一旦发现问题,主分支的专职配置管理员(Software Configuration Manager,SCM)将根据问题的严重性和紧迫性决定是否需要直接回退引起问题的提交,或者基于master创建bugfix分支进行问题修复。

2. 基于发布的Release分支#

Release分支负责对外发布软件产品,每个Release分支也会配备专职版本配置管理员SCM,SCM具有对Release分支的最高管理权限。当master上已经包含了某个发布所需要的所有功能,并且没有已知的严重问题,此时由SCM从主分支上创建Release分支准备系统集成测试,和Git flow相同,在此分支上不再进行新功能的开发,仅在这个分支上进行修复问题,创建文档,客户参数配置及其他与发布相关的工作,这些代码同时也需要合并回master以确保主分支功能的完整性。

在每个Release分支正式发布前可能还需要将主分支上的一部分关键问题的修复选择性地同步(Cherry-pick)到Release分支,这个操作也是由SCM完成。
Release分支上的工作一切就绪并通过系统集成测试后,SCM在Release分支上打上相应的版本号标签(Tag)进行发布,这点和Git flow在主分支上进行发布不同。

软件产品发布之后,如果发现紧急或者严重的问题,此时需要基于版本发布时的Release分支标签创建Hotfix分支来修复此类问题,问题修复后合并回该Release分支以及其他同样需要此修复的Release分支,并打上新的版本号标签(Tag)用于发布,同时代码也需要合并回master以确保主分支的健壮性。

选择合适的分支模型#

Git代码分支管理模型各具特点,流程只是一个辅助工具,没有最好,只有最合适。

  • 如果开发团队规模较小又比较分散,产品发布周期较短(例如:初创公司,或者开发的是一个网站或 Web 应用程序,在一天内可能需要发布多个版本),可以选择GitHub flow或者GitLab flow;
  • 如果开发团队规模较大,产品发布周期较长(例如:团队超过20人,采用了月度或季度发布周期,并且由一个团队负责并行开发多个项目),可以选择Git flow,发布周期较短可以选择TBD flow;
  • 如果开发团队规模大,产品发布周期长,同时对敏捷的要求比较高,可以考虑TBD++ flow。每个组织根据产品、项目、人员的特点找到最合适的模型才是共同的目标。对于某个长期产品的开发和客户版本维护场景,这种分支是笔者比较推荐的。

以上这些分支策略,仅仅是作为大家实践的参考,不同的开发模式和发布节奏,以及团队的人员水平,基础设施水平等都是选择分支模型的参考因素。

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

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

相关文章

【stable diffusion】保姆级入门课程03-Stable diffusion(SD)图生图-涂鸦(绘图)的用法

目录 0.本章素材 1.涂鸦有什么用 2.涂鸦的使用场景是什么 3.操作面板 4.提示词与涂鸦 5.涂鸦与重绘幅度 6.涂鸦的其他用法(自由创作) 7.课后训练 0.本章素材 Realistic Vision V3.0模型(真实系模型)百度网盘链接:https://pan.baidu.com/s/1HkSKW2t4L6wMg…

openlayers系列:加载arcgis和geoserver在线离线切片

https://www.freesion.com/article/1751396517/ 1.背景 有个项目需要使用openlayer加载各种服务上发布的数据,坐标系也不同,我们都知道openalyer默认可以加载EPAG:3857,要加载4490的坐标系的数据需要重新定义一下,之后再加载。一想起要重新…

[SQL系列] 从头开始学PostgreSQL 事务 锁 子查询

[SQL系列] 从头开始学PostgreSQL 索引 修改 视图_Edward.W的博客-CSDN博客https://blog.csdn.net/u013379032/article/details/131818865 事务 事务是一系列逻辑相关的数据库操作,可以作为一个整体进行操作或者回滚。事务通常会包含一个序列的读或者写操作&#xf…

No4: Python脚本的交互式运用

No4: Python脚本的交互式运用 1、 先安装了Python和环境变量设置 2、编写Pthon脚本 3、在脚本所在目录位置下,Python 脚本;

Nginx系列之 一 负载均衡

目录 一、Nginx概述 1.1 负载均衡概述 1.2 负载均衡的作用 1.3 四/七层负载均衡 1.3.1 网络模型简介 1.3.2 四层和七层负载均衡对比 1.3.3 Nginx七层负载均衡实现 1.4 Nginx负载均衡配置 1.5 Nginx负载均衡状态 1.6 Nginx负载均衡策略 二、负载均衡实战 2.1 测试服…

论文笔记--Won’t Get Fooled Again: Answering Questions with False Premises

论文笔记--Won’t Get Fooled Again: Answering Questions with False Premises 1. 文章简介2. 文章概括3 文章重点技术3.1 大模型面对FPQs的表现3.2 False QAs数据集3.3 训练和评估 4. 文章亮点5. 原文传送门 1. 文章简介 标题:Won’t Get Fooled Again: Answerin…

LLMs之LLaMA2:LLaMA2的简介(技术细节)、安装、使用方法(开源-免费用于研究和商业用途)之详细攻略

LLMs之LLaMA2:LLaMA2的简介(技术细节)、安装、使用方法(开源-免费用于研究和商业用途)之详细攻略 导读:2023年7月18日,Meta重磅发布Llama 2!这是一组预训练和微调的大型语言模型(LLM),规模从70亿…

(三)springboot实战——web新特性之函数式实现

前言 本节内容我们主要介绍一下web访问的另一种形式,通过函数式web实现一个restful风格的http请求案例。函数式web是spring5.2之后的一个新特性,可以通过函数去定义web请求的处理流程,使得代码更为简洁,耦合性也降低了。 正文 …

在vue3中配置ByteMD掘金同款markdown编辑器

最近因为想要一个富文本编辑器集合到项目中,在查找网上很多资料后,选择了ByteMD 编辑器,ByteMD 编辑器是字节跳动的掘金团队所开源的一个编辑器组件,还挺好用的,那如果要在vue3项目中配置ByteMD编辑器要如何配置呢&…

【YOLO】关闭控制台推理日志

问题 每次推理时,控制台都会打一条日志 消除方法 外部库里找到\site-packages\ultralytics\engine\predictor.py 将代码的282、283、292、293,这四行注释掉(v5和v8一样) 也可以搜关键词# Print time (inference-only)可以定位代…

基于PHP+ vue2 + element +mysql自主研发的医院不良事件上报系统

医院不良事件上报管理系统源码 不良事件上报是为了响应卫生部下发的等级医院评审细则中第三章第9条规定:医院要有主动报告医疗安全(不良)事件的制度与工作流程。由医疗机构医院或医疗机构报告医疗安全不良事件信息,利用报告进行研…

WEB安全测试通常要考虑的测试点

1、问题:没有被验证的输入 测试方法: 数据类型(字符串,整型,实数,等) 允许的字符集 最小和最大的长度 是否允许空输入 参数是否是必须的 重复是否允许 数值范围 特定的值(枚举型&a…

基于UDP的可靠传输,文件+目录(C++,Qt)

一、基础知识 UDP(UserDatagramProtocol)是一个简单的面向消息的传输层协议,尽管UDP提供标头和有效负载的完整性验证(通过校验和),但它不保证向上层协议提供消息传递,并且UDP层在发送后不会保留…

【Tomcat】无法将位于-的资源添加到Web应用程序-的缓存中,因为在清除过期缓存条目后可用空间仍不足 - 请考虑增加缓存的最大空间

1、问题 org.apache.catalina.webresources.Cache.getResource Unable to add the resource at [xxx] to the cache for web application [/xxx] because there was insufficient free space available after evicting expired cache entries - consider increasing the maxim…

为Android构建现代应用——设计原则

为Android构建现代应用——设计原则 - 掘金 state”是声明性观点的核心 在通过Compose或SwiftUI等框架设计声明性视图时,我们必须明确的第一个范式是State(状态)。UI组件结合了它的图形表示(View)和它的State(状态)。UI组件中发生变化的任何属性或数据都可以…

Kotlin~Observer观察者模式

概念 定义一对多的依赖关系,让多个观察者同时监听一个主题对象。 角色介绍 Subject:主题,也称被观察者,它是具有状态的对象维护着一个观察者列表。提供添加、删除和通知观察者的方法。ConcreteSubject:具体主题&…

mfc140.dll丢失的解决方法(最新解决方法)

一:mfc140.dll的作用: mfc140.dll的主要作用是提供了(简称MFC)的函数和资源,它是用于构建Windows应用程序的一组C类库。MFC是微软开发环境中提供的一个工具集,它封装了Windows操作系统的底层API&#xff0…

2.多线程-初阶(中)

文章目录 4. 多线程带来的的风险-线程安全 (重点)4.1 观察线程不安全4.2 线程安全的概念4.3 线程不安全的原因4.3.1原子性4.3.2可见性4.3.3代码顺序性 4.4 解决之前的线程不安全问题 5. synchronized[ˈsɪŋkrənaɪzd] 关键字-监视器锁monitor lock5.1 synchronized 的特性5.…

【限流】4 种常见的限流实现方案

在微服务应用中,考虑到技术栈的组合,团队人员的开发水平,以及易维护性等因素,一个比较通用的做法是,利用 AOP 技术 自定义注解实现 对特定的方法或接口进行限流。 下面基于这个思路来分别介绍下几种常用的限流方案的…

OceanBase 压测时为什么冻结阈值在变化?

本文从源码角度分析了 OceanBase 压测中冻结阈值动态变化的原因,并给出运维建议。 作者:张乾 外星人2号,兼任五位喵星人的铲屎官。 本文来源:原创投稿 爱可生开源社区出品,原创内容未经授权不得随意使用,转…