这是我参与「第五届青训营 」笔记创作活动的第7天
一、本堂课重点内容
- Git 研发流程
- 依托代码管理平台 Gitlab/Github/Gerrit 介绍我们如何进行代码的开发级团队合作
二、详细知识点介绍
1. Git 研发流程
常见问题
- 在 Gerrit 平台上使用 Merge 的方式合入代码
- 不了解保护分支,Code Review, CI等概念,研发流程不规范
- 代码历史混乱,代码合并方式不清晰
1.1 不同的工作流
| 类型 | 代表平台 | 特点 | 合入方式 |
|---|---|---|---|
| 集中式工作流 | Gerrit / SVN | 只依托于主干分支进行开发,不存在其他分支 | Fast-forward |
| 分支管理工作流 | Github / Gitlab | 可以定义不同特性的开发分支,上线分支,在开发分支完成后再通过 MR/PR 合入主干分支 | 自定义,Fast-Forward or Three-Way Merge 都可以 |
1.2 集中式工作流
- 什么是集中式工作流?
- 只依托于 master 分支进行研发活动
- 工作方式
- 获取远端 master 代码
- 直接在 master 分支完成修改
- 提交前拉取最新的 master 代码和本地代码进行合并(使用 rebase),如果有冲突需要解决冲突
- 提交本地代码到 master
1.2.1 集中式工作流-Gerrit
Gerrit 是由 Google 开发的一款代码托管平台,主要的特点就是能够很好的进行代码评审。
在aosp(android open source project)中使用的很广,Gerrit 的开发流程就是一种集中式工作流。
- 基本原理
- 依托于 Change ID 概念,每个提交生成一个单独的代码评审。
- 提交上去的代码不会存储在真正的 refs/heads/ 下的分支中,而是存在一个 refs/for/ 的引用下。
- 通过 refs/meta/config 下的文件存储代码的配置,包括权限。评审等配置,每个 Change 都必须要完成 Review 后才能合入。
- 优点
- 提供强制的代码评审机制,保证代码的质量
- 提供丰富的权限功能,可以针对分支做细粒度的权限管控
- 保证 master 的历史整洁性
- Aosp 多仓的场景支持更好
- 缺点
- 开发人员较多的情况下,更容易出现冲突
- 对于多分支的支持较差,想要区分多个版本的线上代码时,更容易出现问题
- 一般只有管理员才能创建仓库,比较难以在项目之间形成代码复用,比如类似的 fork 操作就不支持。
1.3 分支管理工作流
| 分支管理工作流 | 特点 |
|---|---|
| Git Flow | 分支类型丰富,规范严格 |
| Github Flow | 只有主干分支和开发分支,规则简单 |
| Gitlab Flow | 在主干分支和开发分支之上构建环境分支,版本分支,满足不同发布 or 环境的需要 |
1.3.1 Git Flow
Git Flow是比较早期出现的分支管理策略
- 包含五种类型的分支
- Master:主干分支
- Develop:开发分支
- Feature:特性分支
- Release:发布分支
- Hotfix:热修复分支
- 优点
- 如果能按照定义的标准严格执行,代码会很清晰,并且很难出现混乱
- 缺点
- 流程过于复杂,上线的节奏会比较慢。
- 由于太复杂,研发容易不按照标准执行,从而导致代码出现混乱。
1.3.2 Github Flow
Github 的工作流,只有一个主干分支,基于 Pull Request 往主干分支中提交代码。
- 选择团队合作的方式
- owner 创建好仓库后,其他用户通过 Fork 的方式来创建自己的仓库,并在 fork 的仓库上进行开发
- owner 创建好仓库后,统一给团队内成员分配权限,直接在同一个仓库内进行开发
- 创建一个 Pull Request
- 创建一个 main 分支
- 创建一个 feature 分支
- 创建一个 feature 到 main 的 Pull Request
可以在 Pull Request 页面执行 CI/CA/CR等操作,都检查通过后,执行合入。
可以通过进行一些保护分支设置,来限制合入的策略,以及限制直接的 push 操作。
1.3.3 Gitlab Flow
Gitlab 推荐的工作流是在 Git Flow 和 Github Flow 上做出优化,既保持了单一主分支的简便,又可以适应不同开发环境。
原则:upstream first 上游优先
只有在上游分支采纳的代码才可以进入到下游分支,一般上游分支就是 master.
1.4 代码合并
Fast-Forward
不会产生一个 merge 节点,合并后保持一个线性历史,如果 target 分支有了更新,则需通过 rebase 操作更新 source branch 后才可以合入。
Three-Way Merge
三方合并,会产生一个新的 merge 节点
1.5 如何选择合适的工作流
- 选择原则
- 没有最好的,只有最合适的
- 针对小型团队合作,推荐使用 Github 工作流即可
- 尽量保证少量多次,最好不要一次性提交上千行代码
- 提交 Pull Request 后最少需要保证有 CR 后再合入
- 主干分支尽量保持整洁,使用 fast-forward 合入方式,合入前进行 rebase
大型团队合作,根据自己的需要指定不同的工作流,不需要局限在某种流程中。
1.6 解决问题
- 在 Gerrit 平台上使用 Merge 的方式合入代码
- Gerrit 是集中式工作流,不推荐使用 Merge 方式合入代码,应该是在主干分支开发后,直接 Push
- 不了解保护分支,Code Review,CI 等概念,研发流程不规范
- 保护分支:防止用户直接向主干分支提交代码,必须通过 PR 来进行合入。
- Code Review,CI:都是在合入前的检查策略,Code Review 是人工进行检查,CI 则是通过一些定制化的脚本来进行一些校验。
- 代码历史混乱,代码合并方式不清晰。
- 不理解 Fast Forward 和 Three Way Merge 的区别,本地代码更新频繁的使用 Three Way 的方式,导致生成过多的 Merge 节点,使提交历史变得复杂不清晰。
三、课程总结
- Git是一个分布式版本控制工具,由linus开发,衍生出github gitlab gerrit等平台
- Git配置,Git代码提交,Git代码同步基本命令,以及git管理代码的原理,帮助我们更好的知道如何正确使用Git命令
- 讲述不同的研发流程,有以gerit 为代表的集中式工作流,和Gitlab/Github为代表的分支管理工作流,讲述了一些代码提交规范,保护分支,codereview等就念,帮助我们规范研发流程
四、课后作业
- 熟悉一个开源项目,学习开源代码,整理成学习笔记,提交到 Github 上。
- 尝试向开源项目提一个 Pull Request。