一. Git管理说明
采用功能驱动开发(feature-driven develop ment,简称FDD)
需求是开发的起点,先有需求再有功能分支或者补丁分支。完成开发后,该分支就合并到常驻分支,然后被删除.
采用Git Flow(Git工作流)的方式
"工作流程"在英语里,叫做"workflow"或者"flow",原意是水流,比喻项目像水流那样,顺畅、自然地向前流动,不会发生冲击、对撞、甚至漩涡.
二. Git Flow
项目中长期存在两个分支: master
和 develop
常驻分支 | 常用名 | 分支用途 |
---|---|---|
主分支 | master | 生产环境的稳定分支,生产环境基于该分支构建。仅用来发布新版本 |
开发分支 | dev / develop | 开发环境的稳定分支,公共开发环境基于该分支构建 |
项目中的三种短期分支
短期分支名 | 常用名 | 分支作用 |
---|---|---|
功能分支 | feature-* |
开发某个特定功能的分支 |
补丁分支 |
hotfix-* / fixbug-*
|
又叫bug分支,做bug修复的分支 |
预发布分支 |
pre-release-* / release-*
|
预发布分支,提交测试的分支 |
完成开发,该分支会合并到 develop
或 master
中,合并完成之后该分支的生命周期结束,删除该分支。
*是取通配符的意思,用来代替不同的命名
看图说话:
只有
master
和develop
一直是实体线。说明这两条是常驻分支。其他分支是阶段性实体线,用完就删除。master
分支merge(版本发布或者bug修复)都要设置tag。master
分支只会被bug分支和release
分支merge。develop
只有创建的时候才跟master
有关系。。(严格上来讲每一次版本都应该拉develop
分支支持小版本的开发迭代(视情况而用),不需要再拉feature
分支feature
分支)feature
分支只与develop
分支有关系。是从develop
中拉出来的,并且合并回develop
。feature
分支之间没有关系。release
分支只从develop
拉出来,release
分支测试的bug,要及时merge到develop
,最终release
分支要合并到master
和develop
分支,并删除。bug分支是从
master
对应tag节点拉取的。最后合并到develop
和master
分支。(此时如有release
分支也应合并)合并到master
上的时候也应该设置tag。
三. 针对各个分支的说明
1. master 分支
使用注意:
代码库必须有且只有一个
master
分支,所有发布版本都在这个分支上发布。对
master
分支使用gitlab的分支保护,仅管理者有权限。每次发布打tag,便于处理线上bug,拉取bug分支。
除了从
pre-release
或生产环境Bug修复分支进行merge,不接受任何其它修改。禁止将
master
分支merge到其他分支。
2. develop
分支
开发环境的稳定分支,公共开发环境基于该分支构建。
注意点:
develop
分支来源于master
分支,之后就跟master
无关了。develop
分支一定是大于等于master
分支的。严禁
master
分支合并到develop
分支的操作。develop
分支最好不好做版本开发,版本开发应该在对应的feature
分支上。
3. feature
分支
为了开发某个特定功能,从 develop
分支上面分出来的。开发完成后,要merge到 develop
分支。
注意点:
- 通常用
feature
-name命名。 - 通常是在
develop
分支拉取的,如果需要和线上版本保持一致,也可以从master
拉取。 -
功能分支属于临时分支,合并完就结束生命周期,执行删除操作。
feature
分支的使用说明:
-
当前仅有一条
feature
分支开发的情况从当前的
develop
分支拉someOne分支,在someOne分支上进行开发,要将该分支推送为线上分支(防止意外发生,比如电脑坏了...)。如果需要提测,将该分支合并到develop
分支上,并基于develop
拉release
分支。 -
当前有多条
feature
并行的情况如果要开发someOne版本,从当前的
develop
分支拉取someOne分支,someOne功能未开发结束,这个过程中来了anotherOne版本,应该从develop
对应的someOne分支节点前(不包含someOne代码的最新节点)拉anotherOne的分支。如果出现当前不适合合并到develop
的情况,可以在当前的feature
操作版本提测。
4. release
分支
预发布分支,又叫测试分支,是一个临时分支。通常用于合并到 master
之前拉一个预发布分支用于测试。
注意点:
通常用
release-*
命名预发布分支是从
develop
分支拉取的。预发布分支的bug,在该分支处理,处理完同步到
develop
上。预发布分支测试完成,合并到
develop
和master
分支上。
5. hotfix分支
修复线上bug一般拉一个叫 hotfix-*
分支。其他的开发bug分支叫 bugfix
分支。这两种分支都属于临时分支,合并完成,及时删除该分支。
因为线上bug和开发bug处理方式不同,最好还用分区一下分支的命名
bug产生的分支情况:
-
master
分支
bug产生于 master
分支,需要从 master
对应的tag节点拉取hotfix分支,做完修复之后,用这个hotfix
打包测试,发布上线。上线成功之后,将该条hotfix分支分别合并到 master
和 develop
上,并删除该hotfix分支。(如有需要还要合并到需要的 feature
和 release
分支)
思考为什么要从bug分支打包上线❓
-
develop
分支
bug产生于 develop
分支,在发现该bug的节点,拉取bugfix分支,修复完成,合并回 develop
分支。并做删除操作。(如有需要还要合并到 feature
和 release
分支)
-
feature
分支
在 feature
上发现的bug,要对该bug做区分是否属于该功能分支上的。如果属于该分支,修改即可。如果属于 develop
分支,要在 develop
上找到合适的commit,拉取bugfix分支,修改完成之后合并到 develop
上。(如有需要还要合并到需要的 feature
和 release
分支)
四. 流程规范
1. 正常开发流程
-
从
develop
分支切出一个新分支,根据需求区分功能还是bug分支。如果新功能开发就是
feature-*
分支,如果是dev的bug修复就是fixbug-*
分支。 开发者完成开发,提交分支到远程仓库。
开发者发起 merge 请求(严格的话采用 Merge Request),将新分支请求merge到
develop
分支,并提醒code reviewer进行review。code reviewer对代码review之后,若无问题,则接受merge请求,新分支merge到
develop
分支,同时可删除新建分支;若有问题,则不能进行merge,可close该请求,同时通知开发者在新分支上进行相应调整。调整完后提交代码重复review流程。转测时,直接从当前
develop
分支拉release
分支,构建测试环境完成转测。测试中,如果发现bug,就在
release
分支修改,修改完成merge到develop
分支。-
测试完成后,基于pre-
release
分支打包完成上线工作。上线完成之后,merge到master
分支和dev分支,并对master
分支打tag,tag一般采用线上app的版本号。
2. 生产环境bug修复
生产环境的Bug分两种情况:
非紧急Bug或优化:非关键业务流程问题,仅影响用户使用体验,或出现频率较小等,为非紧急Bug,可规划到后续版本, 作为功能需求进行修复。
紧急Bug:严重影响用户使用的为紧急Bug,需立即进行修复。如关键业务流程存在问题,影响用户正常的业务行为。
紧急Bug修复:
- 需要从
master
分支切出一个bug修复分支 - 完成修复之后,将该分支代码提交测试。如果问题继续在当前分支修改。
- 验证完成,需要同时merge到
master
分支与develop
分支。
3. dev环境bug修复
- 从对应的节点拉取
bugfix
分支 - 修复完成,如需测试接入,用该分支提测。
- 验证完成,将
bugfix
分支合并到develop
分支上。
- 当前如果存在
release
分支,也应该合并到该分支。
- 如果有暂时不能合并到
develop
分支的
feature
分支,也要判断是否需要合并。
五. 小技巧
1. Merge Request
功能分支合并请求,可以使用Gitlab的 Merge Request 功能。本质是一种对话机制,你可以在提交的时候,@
相关人员,引起他们的注意。
2. 分支保护
master
分支应该受到保护,不是每个人都可以修改这个分支,以及拥有审批 Merge Request 的权力。Gitlab默认提供了该功能。
3. Merge节点
Git有两种合并:一种是"直进式合并"(fast forward),不生成单独的合并节点;另一种是"非直进式合并"(none fast-forword),会生成单独节点。
前者不利于保持commit信息的清晰,也不利于以后的回滚,建议总是采用后者(即使用--no-ff
参数)。只要发生合并,就要有一个单独的合并节点。