编写代码,是软件开发交付过程的起点,发布上线,是开发工作完成的终点。代码分支模式贯穿了开发、集成和发布的整个过程,是工程师们最亲切的小伙伴。那如何根据自身的业务特点和团队规模来选择适合的分支模式呢?本文分享几种主流 Git 分支模式的流程及特点,并给出选择建议。
分支的目的是隔离,但多一个分支也意味着维护成本的增加。我们可以分别从开发和发布分支的多寡,做个简单组合,即:
主干开发,主干发布。
分支开发,主干发布。
主干开发,分支发布。
分支开发,分支发布。
一个好的分支模式,可以大大提高软件的开发、集成和发布效率。选择什么样的分支策略,是每一个开发团队开始工作时面临的第一个问题。那么,git怎么上传文件到远程仓库,选择什么样的分支模式才适合我们呢?在回答这个题之前,我们先了解一下几种常见的分支模式。主流的分支模式常见的分支模式有 TBD(即主干开发模式)、Git-Flow 模式、Github-Flow 模式及 Gitlab-Flow 模式。TBD(主干开发模式)即所有开发者,仅在一个开发分支(即主干)上进行协作开发的模式,在这种模式下,不允许新建任何长期存在的开发分支,有且仅保留主干分支进行开发协作。因为没有长期分离的其他开发分支,任何代码变更持续地更新到主干上,在一定程度上避免了 merge 代码带来的困扰。同时,在这种开发模式下,建议采用发布分支的策略,根据软件版本的发布节奏拉出发布分支。在 TBD 模式下,所有的修改都是在主干上,哪怕是缺陷的修改也是,修改完缺陷后,再 cherry pick 到发布分支上。其特点总结一下就是:
有且仅有一个开发分支,即主干分支。
我们可以通过命令:git checkout -b mdr_branch 来创建分支并切换到该分支上。当然,使用 git checkout master 和 git checkout mdr_branch 可以在主干和分支上来回切换。可以使用 git branch -d mdr_branch 来删除分支,。
所有改动都发生在主干分支。
发布可以从主干拉发布分支。
使用 git checkout 命令进行分支的切换,实际上有三个地方更改了 而切换分支的最佳实践:每次切换分支前,确保当前分支一定得是干净的(已提交状态)。因为要避免一下情况:在切换分支时,如果当前分支上有新增且未暂存的修改。
主干上进行的修复需要根据缺陷的修复策略,确定是否 cherry pick 到对应版本的发布分支。
因为团队共享一个开发分支,并且在开发分支上进行集成验证,而每次代码提交都会触发集成验证,这就要求每次代码的变更在主干上都能快速地验证,以确定是否接受下一次代码变更(每次代码变更都应该基于前一个稳定的版本进行),为了保证主干一直处在可工作状态,这就需要:
每一次的变更要小,这样在验证的过程中才能控制范围。
快速完成验证,这就要求有相对完善的自动化检查验证机制。
所以,主干开发模式可以说是持续集成的关键推动者。主干开发模式非常利于持续集成,并且根据稳定和主干基线,做到随时发布,以达到持续交付。但这些是建立在团队成熟的协作能力和相对成熟的工程配套的基础上,快速地对主干的变更提交完成编译、检查及验证;同时,因为采取发布分支的实践方式,在产品版本、分支、部署场景的对应关系需要梳理清楚,避免发布分支混乱,及缺陷修改在各分支上的修复策略。因为主干开发要求每次变更提交都要小,并且要快速验证完,保证主干是处在可发布状态。对于一些处在开发过程中的特性,如每次变更提交,并非意味着完整特性的完成,为了隔离“特性半成品”对主干的影响,一般会采用特性开关(Feature Toggle)的方式进行隔离。即频繁的代码变更提交,可以先做集成及验证,但是在发布的角度,通过(Feature Toggle)先隐藏相关特性,只有当特性都完成之后,才打开开关,特性完全透出。但是,特性开关的引入也并不是没有成本,因为特性开关是配置,本质上跟我们常常用到的宏定义(else)没啥区别,从本质上,它也是一种代码的分支。特性开关的使用,在一定程度上让你的代码变得更脆弱。所以,特性开关的使用,是建立在良好的代码设计基础上。为了弥补诸如特性开关这样针对某个特性开发的需要,而且现在软件开发中,越来越多的团队共同协作在一起完成某一个特性这样的场景,一种针对特性开发的分支模式就应运而生,这就是特性分支开发模式,最有代表性的就是 Git-Flow。Git-FlowGit-Flow 是为了解决多个不同特性之间并行开发需要的一种工作方式。当开始一个特性的开发工作的时候,从主干上拉出一个特性分支,所有的关于该特性的开发工作都发生在这个特性分支上,当完成该特性的工作之后,再把特性分支合并回代码主路径上,并准备发布。Git-Flow 有以下几种分支:
feature 分支:开发者进行功能开发的分支。
develop 分支:对开发的功能进行集成的分支。
release 分支:负责版本发布的分支。
hotfix 分支:对线上缺陷进行修改工作的分支。
master:保存最新已发布版本基线的分支。
是不是觉得这个模式很专(fu)业(zha)的样子,那我们通过开发者做一个特性开发,按 happy path 捋捋:
开发者接到一个开发需求,从 develop 分支拉一个 feature 分支。
大家完成自己本地的开发工作,完成本地验证,提交代码到 feature 分支。
基于 feature 分支进行验证,并持续合并新的开发代码。
\x0d\x0a创建新分支:\x0d\x0a $ git branch testing 创建一个名为testing的分支\x0d\x0a\x0d\x0a切换分支:\x0d\x0a $ git checkout teting 切换到testing分支上。通过向该命令传递一个-b。
完成特性的开发,并且 feature 分支验证无误,将 feature 分支的代码合并到 develop 分支。
在 develop 分支进行集成验证(此处,可能和其他合并进来的特性分支一起进行验证),集成验证完毕,feature 分支会被删除。
当 develop 分支是一个成熟的发布版本时,如完成了彻底的测试及问题的修复,拉出 release 分支进行发布。
完成发布之后,将 release 分支合并入 develop 和 master(master 保存的永远都是已发布的最新代码),并删除 release 分支。
Hotfix 的流程如下:
如果发布之后,发现了缺陷,基于 master 拉出一个 hotfix 分支。
在 hotfix 对问题进行修改及验证。
问题的修复合并到 develop 和 master 上。
删除 hotfix 分支。
Git-Flow 的分支模式,提供了相对完备的各种分支,以覆盖软件开发过程中的大部分场景,以致于在相当长的一段时间内,人们认为这就是标准的 Git 的分支模式(因为从它的名字上看,也很容易产生这样的幻觉)。但是,Git-Flow 也存在着明显的一些问题,如:
分支特别多,而且每类分支都有特定限定的用法,开发者很难记住什么分支是干什么的。
整个分支模式过于复杂,大大超出大部分团队和项目的需求。
feature 分支的生命周期过长导致的合并冲突。如果一个特性所在 feature 分支生命周期过长,它跟 develop 分支的差异就越大,这样,在该特性集成到 develop 的过程中,潜在的代码冲突将是集成的噩梦。
像 develop 分支,感觉其实存在的意义不是太大,完全通过 master 就可以替代集成的作用,额外为变更提交的集成引入 develop 分支,对分支模式来说,变得更加的复杂;同样,如果取消 develop 分支,那么,hotfix 分支存在的意义也就没有必要了,因为这个时候,hotfix 分支与 feature 分支就没有任何的差别。
那么,有没有一种分支模式,既包含开发任务对于主线的隔离,又相对 Git-Flow 轻量一点?我认为,真正的解决方案,应该是本质极简单的。这里,我们就不得不给大家介绍另一种分支模式,叫做 GitHub-Flow。GitHub-Flow在 GitHub-Flow 上,第一步就是没有 Git-Flow 中所介绍的 release 分支。对于 GitHub-Flow 来说,发布应该是持续地,当一个版本准备好,它就可以被部署。同样,在 hotfix 上的处理,GitHub-Flow 认为,hotfix 与那些小的特性修改没有任何区别,它的处理方式也应该与之相似。在 GitHub-Flow 的整体流程是:
在 master 分支上的所有代码都应该是最新可部署、可工作的版本。
如果要进行新的工作,从 master 分支上拉出一个新的分支,并以工作任务清晰命名,如 “new-scheduling-strategy”。
打开版本控制进行对git的设置。1.打开你的版本控制软件,受控制的程序都会有个标示,如下图所示 2.邮件会发现,提交的分支名称,可能它不是你想要的名称。3.接着有右键选择tortoisegit,展示开会发现有个切换、检出标签。4。.
尽可能频繁地提交代码变更到本地分支,与此同时,尽可能频繁地同步到服务端相同分支名的分支。
当准备合并代码到 master 主干分支上,通过发起 Pull Request,提请代码评审。
通过代码评审后,或与此同时,需要将该分支部署到测试环境,进行验证。
如果评审通过及验证通过,代码则合并到 master 主干分支上,应该立即部署到生产环境。
除了以上这种按环境,将主干发布向下游合并,并依次部署发布的过程。GitLab-Flow 同样支持不同版本的发布分支,即不同的版本会从 master 上拉出发布分支,不同的发布分支再走 pre-production 分支和 production 分支的方式进行发布。从上面的介绍中,我们发现,GitLab-Flow 更多是在发布侧做了更多的工作。同样 GitLab-Flow 因为跟 GitLab 工具强依赖,所以 GitLab-Flow 与 GitLab 中的 Issue 系统也有很好的集成,在其推荐的工作模式中,每次新建一个新的 feature 分支,都是从一个 issue 上发起的,即建立 issue 与 feature 开发分支之间的映射。pros vs cons所以,如果我们还是按照开发和发布的分支多寡来分类的话,以上这些分支模式分别属于:
TBD 应该是主干开发,可以是分支发布,也可以是主干发布。
Git-Flow 应该是分支开发,分支发布。
GitHub-Flow 应该是分支开发,主干发布。
GitLab-Flow 支持分支开发,但支持主干发布,也支持分支发布。
另外,从需要发布版本的多寡的角度来看:
支持一个产品多个发布版本,用 Git-Flow。
支持一个简单产品单个发布版本,用 GitHub-Flow 或 TBD。
支持一个复杂产品单个发布版本,用 GitLab-Flow。