乐趣区

关于spring:10年经验17张图带你进入gitflow企业项目代码版本管理的最佳实践

前言

对于我的项目版本治理,你是否存在这样的痛点:我的项目分支多而杂不好治理,git log 界面 commit 信息错乱简单无标准,版本回退不晓得抉择什么版本适合……。

我的项目版本治理的最佳实际系列,笔者将以两篇文章的模式开展介绍(即根底篇与进阶篇)。本文为 gitflow 版本治理的最佳实际 - 根底篇。根底篇次要介绍 git 利用于生产的根本流程与怎么应用 gitflow 治理你的我的项目版本线(实用于麻利迭代的项目管理场景下)。进阶篇 将着重介绍 gitflow+jenkins+docker+DevOps+ 麻利 Scrum 实现我的项目继续构建与继续交付(CI/CD)。浏览本文须要有肯定 git 根底 ,基础知识则不在本文开展,善用网上冲浪工具便可学习到许多 Git 的基础知识。实际上, 本文介绍的并不是纯正的 gitflow,而是结合实际生产对 gitflow 的革新与最佳实际。

Git 的根本术语与简写

术语 解释
PR 即 pull request,拉取申请。申请 git 代码管理员将你的代码合并到仓库的分支中。个别的 PR 由题目局部,形容局部与代码局部组成。
code review 在 PR 过程中代码管理员对你提交的代码进行代码审查,即你的代码是否符合规范、是否存在格调问题、平安问题等,对你代码进行 cr 的同学并不一定是代码管理员,成熟的麻利团队,每一个成员都是 code owner,都能够对 pr 进行审阅。
squash PR 过程中,会将你的所有 commit 合并(榨取)成一个 commit 并提交到指标分支中,目标是缩小冗余提交、标准主分支提交信息(实际上是 rebase 的一种操作)。
LGTM look good to me(看起来很吊),个别存在于 PR 评论中,即对 pr 的内容没有问题,批准合并到版本库。

一、分支规约

在咱们的最佳实际中,近程版本库 永远只存在三条长期且互相独立的分支 ,他们别离为developreleasemaster,三条分支对应三个环境,别离为开发环境(集成开发环境)、测试环境(预发环境)与生产环境,三个分支别离都上权限,不可间接对其进行 pushcommit操作,即所有的批改均通过 PR 进行,以保障分支对应环境的平安与稳固。本地环境对应的近程分支均会在 PR 通过之后,主动进行删除,以保障版本线的简略。

环境 分支名
开发环境 origin/develop
测试环境(预发环境) origin/release
生产环境 origin/master
本地环境性能分支 develop_xxx (xxx 为具体的开发成员或具体的性能形容,origin/develop_xxx,即 feature 分支下沉到本地,生命周期短,只存在于 pr 过程)。

二、版本号规约

在正式介绍 gitflow 之前,咱们须要对版本号进行标准,不便接下来的行文开展。

在生产中,咱们罕用的版本号为三位数版本号(偶然带四位热修复号),其形成如下:

V 主版本号. 次版本号. 性能号(.${热修复版本号}). 环境

eg:V1.0.0.1.RELEASE、V1.1.0.DEVELOP、V1.0.0。(版本号并不以十进制,而是依照迭代布局推送)

2.1 主版本号(首位版本号)

主版本号,也叫首位版本号、顶位版本号,即 V 后第一个版本号。主版本号个别代表我的项目的期数与产品方向。除非我的项目合同扭转、大规模 api 不兼容、产品方向扭转、底层架构降级等状况外不轻易更新。

另外,我的项目未正式公布、未正式孵化、未正式上线,则首位版本号为 0,一期公布,则为 V1。

2.2 次版本号(迭代号)

次版本号,也叫迭代号,个别代表某个迭代公布的性能汇合(一个迭代发布会蕴含若干个性能更新)。

如 V1.1.0:第一期我的项目第一迭代公布版本、V1.2.0:第一期第二迭代公布版本。

2.3 性能号(PR 号)

一般来说,提交到我的项目分支内的代码均须要通过 PR,而为了保障单个 PR 的简洁性与纯正性,倡议一个 PR 形容一个性能。因而第三位数的版本号也叫做 PR 号或性能号,用来形容单个提交到主分支内的性能或代码批改。

如 V0.0.1:第一迭代的第一个提交、V0.0.98:第一迭代的第 98 个 PR。

2.4 热修复号

四位数版本号是可选版本号,为热修复版本号(也叫老爷保号 hh),惯例迭代与 develop 分支下并不会呈现,而常呈现在测试环境对应的 release 分支与生产环境对应的 master 分支(develop 分支对应的开发环境呈现 bug 间接提交 pr 修复并在原来的版本号上 + 1 便可)。这个版本号罕用于线上热修复,测试环境(预发环境)的热修复。

值得注意的是,四位数版本号通过线上热修复之后,要同步到本地 develop 环境的状况下,该当在 develop 分支下的三位数版本号上加一。

如:master 的热修复号为 V1.0.0.4,develop 分支以后版本为 V1.1.8.DEVELOP,那么这个修复要同步回 develop 分支保障 bug 不重现,那么在 develop 下面的版本则为 V1.1.9.DEVELOP

2.5 环境号

因为在 git 中的 tag 名称是惟一的,那么在 develop 分支下呈现了 V1.0.0 的 tag,那么在 release 和 master 下便不能够再打一个 tag 叫 V1.0.0。因而呈现环境号来对分支版本进行辨别(生产环境不加环境号)。

环境 环境名 版本号(示例)
开发环境 DEVELOP V1.0.0.DEVELOP
测试环境(预发环境) RELEASE V1.0.0.RELEASE
生产环境 MASTER V1.0.0

三、Gitflow 的最佳实际

3.1 总体流程图

3.2 最佳实际举例

这里要搬出两位同学进行接下来的解说,他们是【弓行】同学与【阿康】同学。

3.2.1 近程骨干分支创立

版本的最开始(指 V0.0.0),代码管理员会初始化近程仓库,并基于 master 的初始版本创立三条分支,他们是:

origin/master(对应生产),origin/release(对应测试环境),origin/develop(对应开发环境) 并为这三条分支设置爱护策略,三条分支均不容许间接的 commit 与 push 批改。

代码管理员将三个初始版本打上相应的 TAG:(V0.0.0.DEVELOP、V0.0.0.RELEASE 与 V0.0.0)

3.2.2 本地分支创立

实现迭代打算会议(迭代版本号为 V0.1.0)之后,弓行与阿康他们别离认领了两个工作:【开发性能】弓行,【开发性能 2】阿康。

此时,弓行与阿康会将近程仓库克隆下来,并基于 origin/develop 创立本地develop_gx 分支与 develop_kang 分支。

3.2.3 创立 PR

两人认领工作后进行同步开发,一段时间后,弓行率先实现【开发性能 1】的工作,因而他须要将以后开发版本提交到开发环境中进行自测与前后端联调。但此时【origin/develop】是被爱护的状态无奈被间接提交。因而,弓行须要对以后的开发的版本进行 PR 申请,即创立拉取申请,申请代码管理员对代码进行 code review,通过后进行合并。

此处波及的步骤大抵如下:

1、push 以后本地分支到 origin,失去 origin/develop_gx。

2、创立 PR:即:origin/develop_gx 合并到 origin/develop 的拉取申请

3、期待代码管理员(或小组内同学)进行 code review,若须要批改,则间接在 pr 中提出正文,作者批改后间接 push 到近程分支中,持续期待代码管理员进行 code review。

4、通过后,将以后 commit list 以 squash 的模式合并到 origin/develop 中,失去 V0.0.1.DEVELOP 的 commit

5、最初抉择删除 origin/develop_gx 的近程分支

此时,弓行同学实现了第一个性能的开发,并在【origin/develop】分支上对本人的 pr commit 进行 tag 操作:将此 commit 记录为【V0.0.1.DEVELOP】

3.2.4 合并抵触提交版本

​ 不久后,阿康同学也实现了【开发性能 2】的开发,他也须要将代码提交到 origin/develop 分支进行测试与联调。但此时,origin/develop 曾经与他的基版本不一样了(基版本为 V0.0.0.DEVELOP,近程版本为 V0.0.1.DEVELOP,当先一个版本)如果间接创立 PR,可能因为代码抵触的问题无奈实现版本合并,如下图。

此时阿康须要将 origin/develop 版本拉取到本地,并执行以下操作(举荐间接应用 ide 自带的 git 工具,会不便不少)

// 查看近程仓库是否有新版本

git fetch origin

// 发现新版本,须要拉取到本地解决抵触后进行代码合并

// 暂存本地批改

git stash

// 拉取近程版本

git pull origin/develop

// 取出本地批改

git unstash

// 手工解决抵触(举荐间接应用 idea)

// 提交批改

git commit -m’1、解决抵触合并版本 ’

应用 ide 自带的抵触解决工具则如下图

提交批改后(留神肯定要和抵触代码的作者磋商代码的变更),便能够创立 PR,期待团队内同学进行 code review。团队成员通过之后,阿康的批改便能够胜利被合并到 origin/develop 中进行联调与测试了。阿康此时须要将改 commit 打上 tag【V0.0.2.DEVELOP】,如下图:

至此,V0.1.0 所布局的开发工作全副实现。

3.2.5 测试环境版本公布

实现 V0.1.0 版本开发工作后,弓行同学认领了一个新工作:【V0.1.0 版本提测】。正在其余进行其余性能开发工作的弓行同学此时须要将本地代码 stash 起来,并将 origin/develop 分支的代码与本地代码进行合并(即 git pull origin develop 操作),并进行代码抵触的解决工作。

因为要将代码公布到 origin/release 分支进行版本提测,所以弓行同学须要同时将 origin/release 上的代码与本地代码进行合并操作(即 git pull origin release 操作)并进行代码抵触的解决工作。

实现 git pull origin develop 与 git pull origin release 之后,本地会造成一个新的 commit 版本。弓行同学须要将此 commit 版本通过 pr 的形式合并到 origin/release 上,方可实现 release 分支的测试版本公布工作。因而弓行同学须要反复 3.2.3 步骤的 PR 创立过程,并通过 release 分支的分支管理员审批后,方可将版本公布到测试环境。

3.2.6 版本标记

将 commit 通过 pr 的模式提交到 release 后,接下来就是对版本进行标记的过程,因为此 release 曾经实现了版本的开发工作,因而,以后版本在 release 分支上会被标记为【V0.1.0.RELEASE】。又因为在 develop 分支上,V0.0.2.DEVELOP 版本对应着 release 的 V0.1.0.RELEASE 版本,针对 origin/develop 的分支上的该 commit,会被打上第二个 tag:【V0.1.0.DEVELOP】。

而后,对于 develop 分支的 tag 解决,将会间接从 V0.1.0.DEVELOP 持续往下走(如 V0.1.1.DEVELOP 等)

3.2.7 热修复

origin/release 分支对应着测试环境,对于某些状况而言,测试环境相当于我的项目的 beta 版本,有可能间接面对客户。

那么版本提测之后,测试同学针对该【V0.1.0.RELEASE】版本进行各种测试后发现以后版本存在 BUG,那么开发的同学就要针对改 bug 进行热修复。

假如当初在测试环境呈现一个 BUG,该 BUG 的修复工作仍旧由弓行同学认领解决,那么此时弓行同学就须要将手头上的开发工作暂停(git stash),而后拉取最新版本的 origin/release 分支到本地,而后进行 bug 修复工作。实现修复后,提交本地代码到 origin/release_hotfix_gx 分支,对该分支进行 PR 操作,由 release 管理员进行 code review 并合并到 release 中,并将该修复版本记录为【V.0.1.0.1.RELEASE】。

当然了,因为分支 commit 存在映射关系,呈现在 V0.1.0.RELEASE 上的 BUG,也肯定会呈现在 V0.1.0.DEVELOP。那么此时修复了测试环境的版本仍不够,弓行须要将该修复合并到 origin/develop 上。因而弓行同学须要将新发的版本【V0.1.0.1.RELEASE】拉取到本地,而后对 origin/develop 进行版本提交工作,造成【V.0.1.1.DEVELOP】

至此实现热修复的过程(master 的热修复也是同理,不过是将修复版本依据理论状况合并到 release 和 develop 上的不同罢了)。

3.2.8 生产公布

实现 release 版本的提测工作、BUG 修复工作后,弓行同学须要将 release 分支的版本公布到 master 上,实现生产环境版本的公布,实际上这个过程也与 3.2.5 并无太大差别。同学们能够联合本人理论状况,在这一步减少团队 code review、checklist 查看,公布危险管制等操作,对生产公布进行平安保障。

在实现 origin/master 的公布工作后,将 master 的 tag 更新到 V0.1.0 便实现了整个迭代的公布工作。


仔细的同学读到这里可能曾经发现了,origin/develop、origin/release、origin/master 这三条分支在整个过程中都相互独立,互不影响,因而本工作流程属于三独立分支模式的 gitflow,同学们若为缩小流程,release 分支可优化掉,间接在 develop 分支上进行测试,(也合乎测试驱动开发)

四、双周迭代制与 gitflow

4.1 麻利的双周迭代制

以上图为例,一个麻利团队中有三种垂直的职能角色:开发、测试、与 Scrum master(我的项目),咱们假设以后迭代为N,下个迭代为N+1,上个迭代为N-1

双周迭代制,即一个冲刺迭代设置为两周(或若干周),在这两周中的第一周,这几位垂直职能角色能够如下分工:

· 开发:进行 N 迭代 (以后迭代) 的开发与 N - 1 版本 (上个版本) 的 hotfix 工作,并在每周五进行对立提测;

· 测试:进行 N 迭代 (以后迭代) 的 develop 环境测试与 N - 1 迭代 (上个迭代) 的 release 环境测试,在每周五前实现 N - 1 版本的测试工作;

· 我的项目:进行 N +1 (下个迭代) 的迭代布局工作与上两个迭代 (N-2) 的迭代公布工作

如此一来,N- 1 版本,N 版本,N+ 1 版本便可实现交织进行,井井有条(需要源源不断地来 hhh)当然了,迭代开发工夫与测试工夫能够适当变动(如 开发:测试 = 6:4 或 7:3)。

采纳双周迭代的益处在于:

· 开发同学有短缺和弹性的工夫进行迭代的开发工作与 bug 修复工作与需要了解

· 测试同学有短缺的工夫进行测试工作以保障我的项目品质 (在 develop 环境上一个性能测一个性能,并在 release 环境能够实现充沛的功能测试)

· 我的项目有更多工夫去布局我的项目的迭代与合成具体需要做更欠缺的设计(疯狂布局迭代)。

试想一个场景:开发在迭代最初一天实现开发工作,测试只有最初 2 小时进行测试便令人非常抓狂。

4.2 双周迭代联合 gitflow 的最佳实际

基于双周迭代制的 gitflow 版本治理,即在迭代中:

· 开发在 origin/develop 上进行开发,进行 3.2.4 步骤的开发工作,与上个 release 版本的 hotfix 工作;

· 测试紧跟开发进行 develop 分支的测试与上个 release 版本的测试;

· 第一周完结,对立发版本到 origin/release,测试在第二周开始以后版本 release 环境的功能测试;

· 第三周的周一,我的项目进行版本发版工作(即公布到 origin/master)

五、FAQ

Q1 : 微服务架构下,每个我的项目独立一个版本库怎么做到版本号对立,是每个微服务独自编制版本号还是全局对立版本号?

A1 : 对于微服务架构下(或者分布式架构我的项目)的每个微服务独立版本库的状况,倡议全局编制版本号,即同一个公布窗口,对所有的指标公布分支与的二位数版本号进行编制(即全局对立迭代号或者产品号)。对于没有更新的微服务,可间接在原 release 的 commit 上进行 Tag 公布。

Q2 : 三分支版本线绝对独立,对于版本合并比拟苦楚。

A2 : 这个问题是切实存在的,倡议固定公布人,在本地分支保留 release 分支、master 分支与 develop 分支的合并记录,避免抵触过多。

Q3 : 对于指标公布的性能,若性能在公布前存在危险,则无奈下有危险的分支。

A3 : 问题切实存在,能够配合开关配置做公布。

Q4 : 我的项目处于疾速开发阶段,大家始终往 develop 分支下面提 PR,然而没有人做 code review。

A4 : 能够尝试 PR 题目带上 tag 信息作为 commit title,即:V0.0.1 xxx 性能开发 V0.0.2 XXX 性能开发,这样一来,就相当于做了资源锁,大家都想往 develop 下面提 pr,然而上一个人把三位数版本号占用了,那么就须要有人把这个 pr 解决掉,本人能力应用下一个版本号,直到团队 code review 习惯成熟,如下图(develop 的版本线是不是很清晰)。

Q5 : 容许 origin/develop、origin/release 与 origin/master 三条分支之间相互合并吗?

A5 : 不容许,只能通过 PR 模式进行分支版本合并

Q6 : 应用此种 gitflow 后,三个分支的版本线会是什么样子的?

A6 : 如下图,无论是 develop 分支还是 release 分支与 master 分支,分支永远只有一条直线,不会有分支之间进行合并的状况,所以显得版本线非常洁净整洁。

Q7 : 如同整个过程都没有看到 feature 分支

A7 : 是的,在此种版本治理中,feature 分支其实曾经下沉到了每个人的本地版本库中,不间接在 origin 库中体现。

Q8 : 近程 feature 分支能够不删除吗?

A8 : 为了保障 git log 洁净,倡议集体分支合并到 develop 分支后便执行删除,但不删除近程 feature 也是能够的,能够尝试应用同一个 feature 合并到 release_${version}中,而后执行 release_${version}->release 的 PR。

以上便是我的项目版本治理的最佳实际:gitflow 生产实践篇的所有内容,欢送在下方评论区探讨与提出改良意见!

退出移动版