「本文已参与低调务实优秀中国好青年前端社群的写作活动」。
前言
面对频繁的需求变更和产品的不断迭代,需要对项目代码进行版本管理。
Git是一个开源的分布式版本控制系统,可以有效、高速的处理从小到大的项目版本管理。
一个团队如何使用Git进行版本管理,如何使用Git进行多人的代码coding?如何解决产品开发过程中的版本控制问题?
以下是团队版本管理的基本流程
一、GitServer
使用公司统一开发的统一代码管理平台
二、版本号定义规范
* 版本号命名规则:`主版本号`.`次版本号`.`修订号`,如`2.1.13`
* 版本号仅标记于master分支,用于标识某个可发布/回滚的版本代码
* 对master标记tag意味着该tag能发布到生产环境
* 对master分支代码的每一次更新(合并)必须标记版本号
* 仅项目管理员有权限对master进行合并和标记版本号
三、分支约定
GitFlow有主分支和辅助分支两大类,其中主分支用于组织与软件开发、部署相关的活动;辅助分支组织是为了解决特定的问题而进行的各种开发活动。
主分支
主分支是所有开发活动的核心分支。所有的开发活动产生的输出物最终都会反映到主分支的代码中。主分支分为Master
分支和Develop
分支
master分支
- master分支存放的是随时可供生产环境中部署的稳定版本代码
- master分支保存官方发布版本历史,release tag标识不同的发布版本
- 一个项目只能有一个master分支
- 仅在发布新的可供部署的代码时才更新master分支上的代码
- 每次更新master,都需对master添加指定格式的tag,用于发布或回滚
- master分支是保护分支,不可直接push到远程仓库master分支
- master分支代码只能被release分支或hotfix分支合并
develop分支
- develop分支是保存当前最新开发成果的分支
- 一个项目只能有一个develop分支
- develop分支衍生出各个feature分支
- develop分支是保护分支,不可直接push到远程仓库develop分支
- develop分支不能与master分支直接交互
辅助分支
辅助分支是用于组织解决特定问题的各种软件开发活动的分支。辅助分支主要用于组织软件新功能的并行开发、简化新功能开发代码的跟踪、辅助完成版本发布工作以及对生产代码的缺陷进行紧急修复工作。这些分支与主分支不同,通常只会在有限的时间范围内存在。
辅助分支包括:
- 用于开发新功能时所使用的feature分支
- 用于辅助版本发布的release分支
- 用于修正生产代码中的缺陷的hotfix分支
feature分支
-
命名规则:
feature/*
-
develop分支的功能分支
-
feature分支使用develop分支作为父类分支
-
以功能为单位从develop拉一个feature分支
-
每个feature分支颗粒要尽量小,以利于快速迭代和避免冲突
-
当其中一个feature分支完成后,它会合并回develop分支
-
当一个功能因为各种原因不开发了或者放弃了,这个分支直接废弃,不影响develop分支
-
feature分支代码可以保存在开发者自己的代码库中而不强制提交到朱代码库里
-
feature分支只与develop分支交互,不能与master分支直接交互
如几个同事同时开发,需要分割成几个小功能,每个人都需要从develop中拉出一个feature分支,但是每个feature颗粒要尽量小,因为它需要我们能尽早merge回develop分支,否则冲突解决起来就没完没了。同时,当一个功能因为各种原因不开发或者放弃了,这个分支直接废弃,不影响develop分支
release分支
- 命名规则:
release/*
,' * '以本次发布的版本号为标识 - release分支主要用来为发布新版的测试、修复做准备
- 当需要为发布新版做准备时,从develop衍生出一个release分支
- release分支可以从develop分支上指定Commit派生出
- release分支测试通过后,合并到master分支并且给master标记一个版本号
- release分支一旦建立就将独立,不可再从其他分支pull代码
- 必须合并回develop分支和master分支
release分支是为发布新的产品版本而设计的。在这个分支上的代码允许做小的缺陷修正,准备发布版本所需的各项说明信息(版本号、发布时间、编译时间等)。通过在release分支上进行这些工作可以让develop分支空闲出来以接受新的feature分支上的代码提交,进入新的软件开发迭代周期。
当develop分支上的代码已经包含了所有即将发布的版本中所计划包含的软件功能,并且已通过所有测试时,我们就可以考虑准备创建release分支了。而所有在当前即将发布的版本之外的业务需求一定要确保不能混到release分支之内(避免由此引入一些不可控的系统缺陷)。
成功的派生了release分支,并将赋予版本号之后,develop分支就可以为“下一个版本”服务了。所谓的“下一个版本”是在当前即将发布的版本之后发布的版本。
hotfix分支
- 命名规则:
hotfix/*
- hotfix分支用来快速已发布产品修复或者微调功能
- 只能从master分支指定tag版本衍生出来
- 一旦完成修复bug,必须合并到master分支和develop分支
- master被合并后,应该被标记一个新的版本号
- hotfix分支一旦建立就将独立,不可再从其他分支pull代码
当生产环境的软件遇到异常情况或者发生了严重到必须立即修复的软件缺陷的时候,就需要从master分支上指定的TAG版本派生hotfix分支来组织代码的紧急修复工作
这样做的好处使不会打断正在进行的develop分支的开发工作,能够让团队中负责新功能开发的人与负责代码紧急修复的人并行开展工作
四、commit 提交规范
commit message 是开发的日常操作, 写好 log 不仅有助于他人 review, 还可以有效的输出 CHANGELOG, 对项目的管理实际至关重要, 但是实际工作中却常常被大家忽略。对于Commit 规范,遵循目前比较流行的Angular.js团队规范:
每个Commit信息包含一个header
、一个body
和一个footer
。header
有一个特殊的格式包含一个type
,一个scope
和一个subject
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
header
type:
- feat:新功能(feature)
- fix:修补bug
- docs:文档修改
- refactor:代码重构
- style:代码格式修改,注意不是样式修改
- test:测试用例修改
- perf:用于优化性能
- chore:其他修改,比如构建流程,依赖管理
scope
用于说明Commit影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同
如果你的修改影响了不止一个scope,你可以用*代替
subject
subject
是commit目的的简短描述,不超过50个字符,建议符合50/72 formatting
body
commit 具体修改内容,可以分为多行,建议符合50/72 formatting
footer
一些备注,通常是 BREAKING CHANGE 或修复的 bug 的链接
举个例子
例如一个新功能,添加登录模块Git Commit中的信息可以这样写:
feat[login] add login module
Commitizen:替代你的git commit
最后决定要用过工具生成和约束
commitizen/cz-cli,我们需要借助它提供的git cz命令替代我们的git commit命令,帮助我们生成符合规范的commit message
安装以下依赖
npm install -D commitizen cz-conventional-changelog
package.json配置:
"script": {
...,
"commit": "git-cz",
},
"config": {
"commitizen": {
"path": "node_modules/cz-conventional-changelog"
}
}
在对应的项目中执行git cz or npm run commit
更多方法可以参考这个文章
五、正常上线流程
1)管理员创建固定的分支master和develop,根据产品功能确定当前的版本号,然后从develop分支创建feature分支
2)每个研发人员拉取feature分支,并创建个人本地分支
3)研发人员进行编码,自测完成后合并本地分支到feature分支,在确定为会为下一个版本发布时,合并到develop分支
4)从develop分支衍生出一个release分支,并部署到测试环境
5)release分支经测试、发布、审核、进入灰度后,直到确定不再回滚正式发布后,合并到master和develop分支,并在master分支上打版本标签,并部署到生产环境
6)测试人员验证生成环境通过后,上线完成,如果生产环境验证不通过,马上回滚到master上一次版本代码
六、如何处理线上的紧急bug?
1)研发人员从master分支创建一个hotfix分支
2)检出hotfix分支,测试通过后合并到master分支和develop分支,并在master打版本标签,并部署到生产环境
3)测试人员验证生成环境通过后,上线完成,如果生产环境验证不通过,马上回滚到master上一次版本代码
七、Git flow代码示例
(1) 创建develop分支
git branch develop
git push -u origin develop
(2) 开始新feature开发
git checkout -b some-feature develop
# Optionally, push branch to origin:
git push -u origin some-feature
# 做一些改动
git status
git add some-file
git commit
(3) 完成Feature
git pull origin develop
git checkout develop
git merge --no-ff some-feature
git push origin develop
git branch -d some-feature
# If you pushed branch to origin:
git push origin --delete some-feature
(4) 开始Release
git checkout -b release-0.1.0 develop
# Optional: Bump version number, commit
# Prepare release, commit
(5)完成Release
git checkout master
git merge --no-ff release-0.1.0
git push
git checkout develop
git merge --no-ff release-0.1.0
git push
git branch -d release-0.1.0
# If you pushed branch to origin:
git push origin --delete release-0.1.0
git tag -a v0.1.0 master
git push --tags
(6)开始Hotfix
git checkout -b hotfix-0.1.1 master
(7)完成Hotfix
git checkout master
git merge --no-ff hotfix-0.1.1
git push
git checkout develop
git merge --no-ff hotfix-0.1.1
git push
git branch -d hotfix-0.1.1
git tag -a v0.1.1 master
git push --tags
八、Git flow 工具
记不住以上命令可以借助工具
Git flow script使用
- 初始化: git flow init
- 开始新Feature: git flow feature start MYFEATURE
- Publish一个Feature(也就是push到远程): git flow feature publish MYFEATURE
- 获取Publish的Feature: git flow feature pull origin MYFEATURE
- 完成一个Feature: git flow feature finish MYFEATURE
- 开始一个Release: git flow release start RELEASE [BASE]
- Publish一个Release: git flow release publish RELEASE
- 发布Release: git flow release finish RELEASE 别忘了git push --tags
- 开始一个Hotfix: git flow hotfix start VERSION [BASENAME]
- 发布一个Hotfix: git flow hotfix finish VERSION
GitFlow GUI
- sourceTree
- Git flow for visual studio