在团队中使用GitLab中的Merge Request工作模式
时间:2022-06-26
本文章向大家介绍在团队中使用GitLab中的Merge Request工作模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
在工作中使用Git
已有5年多的时间了,Git
分布式的工作机制以及强大的分支功能使得在团队中推广使用没有受到什么阻碍。一直以来都是采用的分支管理模式,我把项目的开发分为三个阶段:开发、测试和上线。
分支管理模式
开发阶段
- 除了
master
分支创建一个供所有开发人员开发的dev
分支; - 开发人员在
dev
分支上进行工作,随时随地commit
,每天push
一次到服务器; -
push
代码前需要进行pull
操作,因为有可能在之前有别的成员先进行了push
操作,如果有冲突还需要进行冲突解决; - 每天上班后所有成员对
dev
进行pull
操作,获取所有成员push
的代码,有冲突需要解决; - 团队Leader每天将
dev
合并一次到master
。
测试阶段
- 测试进入后就需要添加
test
分支; - 在开发人员将代码
push
到dev
分支后,可以在dev
基础上创建test
分支,测试人员以test
分支搭建测试环境,开始测试; - 开发人员在接受到
bug
后,直接在测试分支上修改,然后让测试人员进行验证; - 每天团队Leader将测试分支上修改的
bug
合并到dev
分支上,这样所有团队成员当天修复的bug
都会在第二天被团队其他人pull
下来; - 团队Leader每天将
dev
合并一次到master
。
上线阶段
- 系统上线后试运行阶段会存在两种改动:
bug
和优化需求,bug
通常当天解决晚上部署,优化需求通常周末部署; -
bug
当天能修复的就直接在test
分支上修复,然后进行测试,验证通过后合并到master
; -
bug
当天不能修复的就针对该bug
创建一个分支,修复完后合并到test
分支进行测试,验证通过后合并到master
; - 每个优化需求都以
master
分支为基础创建一个feature
分支,完成后合并到dev
分支,开发人员可以先交叉测试,然后将dev
合并到test
进行测试,验证通过后合并到master
; -
master
始终是一个干净的,可发布的分支。
Merge Request模式
一直以来,都觉得Merge Request
模式遥不可及,只有做开源软件才会采用这种模式,没想到这么快就已经在团队中开始推行使用了,先看一张图来了解下Merge Request
的开发流程:
Merge Request流程
- 需求或是
Bug
都是用Issue
来表示; - 虽然
Issue
不支持多层级,但结合里程碑、标签等还是可以很好的对任务和Bug
进行管理; - 管理员和团队成员都可以进行
Issue
的创建; - 任务的接收者对
Issue
创建Merge Request
; - 完成任务后推送代码到
Merge Request
对应的分支; - 管理员对代码进行
Merge
。
相比较传统的分支管理模式,Merge Request
可以给我们带来下面几个好处:
- 重要分支设置为受保护,杜绝了有些问题代码被提交了,但项目经理不知道的情况;
- 每个任务都有一个对应的分支,互相隔离,所有的代码改动有据可查;
- 开发人员不用在分支间切换和合并,更专注于开发。
下面以一个示例来介绍Merge Request
的工作流程
1、设置重要分支受保护
设置受保护分支
在上图中的位置可以将所有的重要分支设置为受保护,重要的分支通常是master
、release
、test
等。
2、创建Issue
创建Issue
任务创建后,开发人员就可以对该任务创建Merge Request
了,如下图:
创建Merge Request
- 创建
Merge Request
时会创建针对这个任务对一个分支; - 分支名称的格式为:任务编号-[任务标题中出现的英文和数字],当然分支名称也可以自行修改;
- 分支的Source为该项目设置的主分支,主分支可以在
设置/General/General project settings/Default Branch
进行设置。
3、使用你熟悉的工具拉取Merge Request
对应的分支到本地进行代码修改,修改完成后,Push
代码到服务器,代码推送后,管理员在Merge Request
页面可以看到Merge
按钮,如下图:
Merge
点击右边的Resole WIP status
后,Merge
按钮就可以使用
如果勾选Remove source brance
,当Merge
后,服务器端会删除创建的分支。Merge
完成,会关闭关联的任务,但并不是每一次推送都可以非常顺利,有时会有冲突,当本地代码和服务器代码不一致时,会出现解决冲突的按钮,解决冲突后才能进行Merge
解决冲突
代码Merge
后,开发人员就可以按照同样的流程做下一个任务了。
思考
- 如果系统上线后有紧急
Bug
需要处理,这个流程应该怎样去调整? - 每个任务都在单独分支并行开发,这是如果A和B都以来C开发的一个模块,应该怎么解决?
- 理论上
Issue
管理员和开发人员都可以进行创建,什么样的Issue
可以有开发人员来创建?
总结
- 任何一种模式或工作方式的改变,总会打破一些人的舒适区,我们应该学会走出舒适区,拥抱变化;
- 尝试新的东西肯定会遇到各种问题,先执行,然后再持续优化改进,逐步达到最优状态;
- 从团队试用的情况来看,暂时没有出现水土不服的情况。
- 关于React Native 安卓首屏白屏优化
- 浅谈spring security 403机制一、无权限访问二、匿名访问三、有权限访问原因机制指定AccessDeniedHandler指定error-page情景原因结论
- Python之numpy数组学习(二)
- Intent 属性详解(上)
- 复仇行动:Notepad++官网被圣战组织黑了
- 四大组件的纽带——Intent
- 利用HTC One漏洞破解手机PIN密码
- Android NDk环境配置
- 谷歌再曝Windows8.1漏洞,微软怒了
- Python机器学习的生态系统
- TP-link TL-WR840N系列路由器存在CSRF漏洞,可修改任意配置(含POC测试过程)
- JavaScript严格模式
- 微软修复8个安全漏洞,包括谷歌披露的0day漏洞
- PullToRefreshScrollView 嵌套RecyclerView实现特卖列表倒计时抢购
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 安装RabbitMQ无法访问localhost:15672的管理界面解决
- koa中http服务与websocket服务共享端口
- 第23天:NLP实战(七)——中文新闻主题分类
- Swoole v4.5.3 版本发布
- .NET5.0 单文件发布打包操作深度剖析
- 使用ng-container标签在SAP Spartacus里插入UI
- 自定义SAP Spartacus Cart界面
- 还是只使用console.log()进行调试?好吧,其实还有更多。
- SNMP++: Transport is not supported
- Codeforces Round #666 (Div. 2) A-D
- 深度剖析前端JavaScript中的原型(JS的对象原型)
- dotnet OpenXML 颜色变换
- n维空间的多面体的有向测度和重心
- 只会Vue怎么开发小程序?Vue和微信小程序的到底有哪些区别?
- VBA CreateObject函数如何找到所需要的依赖文件