Git-flow最佳实践方法
1. 原则
master 为保护分支,存储正式版本的发布历史,是最稳定的版本,禁止在此分支中进行代码修改和版本提交,所有的提交应该都是基于tag的。
develop 为功能集成分支,所有的功能开发都应该从此分支中checkout,某些时候develop分支的内容应大于master主分支。
2. 操作步骤
2.1 初始阶段
项目刚开始时,核心开发人员在本地搭建好基础架构,保证基本运行。此时应初始化git仓库,并进行远程仓库的关联,master分支自动创建,后基于master分支创建好develop分支。
2.1.1 主要的步骤
- 在远程仓库创建好相关的issue类型
- 使用额外的工具强制进行规范化约束
- 创建好基本的两个分支master和develop
为提交信息做规范化约束,进入工程根目录执行以下命令
$ npm init
# 所有的"git commit"全部使用"git cz"的方式进行提交
$ npm install -g commitizen
# 使此工程的提交格式以angular的范式进行约束
$ commitizen init cz-conventional-changelog --save --save-exact
# 安装生成CHANGELOG的cli工具,开发人员可以选择不安装,配置管理人员需要进行安装
$ npm install -g conventional-changelog-cli
本地工程结构创建,初始化本地git并关联远程仓库
$ echo "# HelloWorld" >> README.md
$ git init
$ git add -all
$ git commit -m "初始版本提交"
$ git remote add origin [email protected]:wangjunneil/HelloWorld.git
$ git push -u origin master
执行完上述命令后,默认会在远程仓库中创建主干 master 分支。
基于主干分支创建开发分支develop
$ git branch develop
$ git push -u origin develop
$ git branch # 查看本地分支
$ git branch -a # 查看本地和远程分支
$ git branch -r # 查看远程分支
develop 分支包含了项目的全部历史,此时远程仓库应该有 master 和 develop 两个最主要的分支。
2.2 开发阶段
开发人员从git中clone出项目源码,创建好develop分支的跟踪分支,准备进行功能开发。
$ git clone [email protected]:wangjunneil/HelloWorld.git
$ git checkout -b develop origin/develop
2.2.1 新功能开发
所有新功能的开发都需要在develop分支中checkout一个功能分支feature,功能的分支的命名规范见 附录A 分支命名规范。
$ git checkout -b feature_20170811_personal develop
2.2.2 本地编码提交
开发人员每次提交都应该保证功能单元的完成,功能的开发一直处于本地git环境中,不push远程仓库。特殊情况是此功能分支由两人开发或者处于交接状态,应该将功能分支push到远程仓库中。
$ git status
$ git add XXX-FILES
$ git cz # 安装了commitizen
# 可选,查看提交记录
$ git log --pretty=format:"%ad || %h || %s || Author:%an " --date=short | sort -r
$ git log v1.0.0..v2.0.1 --pretty=format:"%ad || %h || %s || Author:%an " --date=short | sort -r
# 可选,将功能分支发布到版本库中
$ git push -u origin feature_20170811_personal
虽然使用了”commitizen”工具进行了约束,但还是建议参看 附录B 提交描述格式
2.2.3 合并开发分支
当开发人员在本地git中完成了功能的开发并已经自己测试过,此时需要合并到总的开发分支上
$ git pull origin develop # 首先保证本地develop分支为最新版本
$ git checkout develop # 切换到develop分支上
$ git merge --no-ff feature_20170811_personal # 合并功能分支
$ git push origin develop # 提交develop分支的远程版本
# 可选,删除远程分支
$ git push origin --delete feature_20170811_personal
开发人员完成了功能开发后,继续循环从 2.2.1 新功能开发 开始做新功能。
2.2.4 发布release分支
当develop分支汇集了足够的新功能和bug修复代码之后,项目组决定可以发布release版本进行测试了(所以release也叫做测试分支),此时从develop分支上发布release分支,用于持续集成和服务器上测试,测试包括集成测试和手动用户接受测试。对于测试中发现的问题,直接在release上修改,完成后再次部署测试。这个分支应该只做bug修复、文档生成和其他面向发布任务。
$ git checkout -b release-0.1.0 develop
2.2.5 合并到主分支上
当release代码通过测试后,开始进行分支合并,合并前需要做好代码评审,而非事后
$ git checkout master
$ git merge --no-ff release-0.1.0
$ git push origin master
$ git checkout develop
$ git merge --no-ff release-0.1.0
$ git push origin develop
# 可选
$ git branch -d release-0.1.0
$ git push origin --delete release-0.1.0
2.2.6 打标签正式发布
$ git tag -a v0.1.0 -m "initial public release" master
$ git push origin v0.1.0
打完标签后,远程仓库中已经包含此标签的基本信息,但作为发布版本,需要清楚的描述出此版本修复了哪些问题以及增加了哪些新的功能。
此时需要生成此版本的CHANGELOG信息,将信息编辑进release note中。要生成规范的CHANGELOG信息,需要 按照标准的提交格式进行提交
# 生成CHANGELOG明细并进行修改
$ conventional-changelog -p angular -i CHANGELOG.md -w -r 0
关于标签命名规范请参看 附录C 标签命名规范
2.3 上线阶段
在线上运行的master标签版本,难免会出现bug,接受客户的ticket进行修复,直接在master分支上checkout出hotfix的维护分支,维护分支或说是热修复分支用于生成快速给产品发布版本打补丁,这是唯一从master中fork出来的分支。
2.3.1 创建hotfix分支
$ git checkout -b hotfix-0.1.1 master
2.3.2 合并到主分支中
完成hotfix的bug修复后,合并到master分支及develop分支(master分支存在此问题,则develop分支肯定也有)
$ git checkout master
$ git merge --no-ff hotfix-0.1.1
$ git push origin master
$ git checkout develop
$ git merge --no-ff hotfix-0.1.1
$ git push origin develop
$ git branch -d hotfix-0.1.1
2.3.3 主分支打标签发布
git tag -a v0.1.1 master
git push --tags
附录A 分支命名规范
格式规定
分支类型_创建时间_分支功能,例如:feature_20180311_personal
格式含义
分支类型 | 创建时间 | 分支功能 |
---|---|---|
新的功能(feature) 问题修复(hotfix) 功能重构(refactor) | 年月日,8位有效数字 | 简要描述此分支的作用,不超过10字 |
附录B 提交描述规范
提交禁止使用git commit -m "xxx"
的方式,因为这种方式不能准确描述出本地提交的目的、结果。
使用git commit
方式可以以文本的方式来描述本次提交的具体信息,这对于后续追溯和问题的发现有很大的帮助。
commit message格式
提交信息包含三个部分,Header、Body和Footer,如下:
<type>(<scope>): <subject>
<body>
<footer>
其中Header是必须的,在变更范围不是很大的情况下,Body和Footer可以省略。
Header
Header部分只有一行,包括三个字段:type(必需)、scope(可选)和subject(必需)。
(1) type
type用于说明 commit 的类别,允许使用下面7个标识。
feat | 新功能(feature) |
fix | 修补的问题(bug) |
docs | 文档变更(documentation) |
style | 格式变更(不影响代码运行的变动) |
refactor | 重构(既不是新增功能,也不是修改bug) |
test | 增加测试 |
chore | 构建过程或辅助工具的变更 |
若type为feat和fix,则该 commit 将肯定出现在 Change log 之中。
(2) scope
scope用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。建议项目初期定义好相关枚举
(3) subject
subject是 commit 目的的简短描述,不超过50个字符。
Body
Body 部分是对本次 commit 的详细描述,可以分成多行,也可以分文件描述变更明细。
Footer
Footer 部分只用于两种情况。
(1) 不兼容的变动
如果当前代码与上一个版本不兼容,则 Footer 部分以BREAKING CHANGE开头,后面是对变动的描述、以及变动理由和迁移方法。
如下的例子:
BREAKING CHANGE: isolate scope bindings definition has changed.
To migrate the code follow the example below:
Before:
scope: {
myAttr: 'attribute',
}
After:
scope: {
myAttr: '@',
}
The removed `inject` wasn't generaly useful for directives so there should be no code using it.
(2) 关闭issue
如果当前 commit 针对某个issue,那么可以在 Footer 部分关闭这个 issue 。
closes #214
也可以一次关闭多个issue
Closes #123, #245, #992
附录C 标签命名规范
标签版本号包含三位数字,前缀使用”v”,如v1.2.31-alpha
Tag命名规范
位数 | 描述 |
---|---|
第一位 | 主版本号,功能模块有较大变动,如多个模块或者整体架构有变化 |
第二位 | 功能有一定的增加变化,如增加了权限控制、自定义视图等 |
第三位 | 问题bug修改的版本,每修改一个bug增加1 |
第四位 | 希腊字母版本号,取值alpha、beta、rc、release |
希腊字母版本号
alpha | 也叫α版,此版本主要是以实现软件功能为主,通常只在软件开发者内部交流,一般而言,该版本软件的Bug较多,需要继续修改。 |
beta | 此版本相对于α版已经有了很大的改进,消除了严重的错误,但还是存在着一些缺陷,需要经过多次测试来进一步消除,此版本主要的修改对像是软件的UI。 |
rc | 此版本已经相当成熟了,基本上不存在导致错误的BUG,与即将发行的正式版相差无几,测试人员基本通过的版本。 |
release | 此版本意味着“最终版本”、“上线版本”,在前面版本的一系列测试版之后,终归会有一个正式版本,是最终交付用户使用的一个版本。 |
附录D Git-flow工具
可以使用工具实现git-flow流程
安装方式
操作系统 | 安装方式 |
---|---|
OSX | brew install git-flow |
Linux | apt-get install git-flow |
Windows | wget -q -O - –no-check-certificate https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh | bash |
IDEA | Git Flow Integration |
使用步骤
# 初始化
$ 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
版权所有,本作品采用知识共享署名-非商业性使用 3.0 未本地化版本许可协议进行许可。转载请注明出处:https://www.wangjun.dev//2018/03/git-flow/