Git工作流程实践

前言

上篇文章说到,选择Git作为版本控制系统,就是选择一种新的团队协作方式。Git常用的工作流程有几种:Git Flow、GitHub Flow、GitLab Flow。这三种工作流程几乎都是以功能驱动开发。先是有需求,才开始进行开发,建立对应的功能分支,完成开发后,该分支就合并到主分支,然后被删除。阮老师有一篇文章讲述得很清楚,这里我只是讲自己实践下来,觉得比较好的一种模式:GitLab Flow New。

为什么使用GitLab Flow New工作流程?

这里,我先讲讲为什么没有采用Git Flow 与 GitHub Flow的工作流程。

Git Flow的问题在于你需要花费时间去维护一个开发分支。

大部分的人都需要从开发分支新建分支,如果人数超过3个以后,你会发现需要去解决日常工作中的异常多的代码冲突。因为可能很多人,在新建的分支上进行开发,但合并开发分支的更新,却是在完成功能开发,这时候开发分支已经累计了无数的代码更新,再去合并的话,可能冲突会很多。

GitHub Flow的问题在于,你需要发起一个Pull Request,简称PR。你的PR通过了评审和讨论后,就合并到master里。可实际上合并到master的代码,也不一定是线上最新的代码。实际工作里,可能还会有预发布这一环节。

如何优雅使用GitLab Flow New工作流程

实际上,我们是这样使用GitLab Flow的。

首先定义3个主要分支。master为生产环境的分支,与线上代码保持一致。预发布的分支为prelease。开发测试分支从master里新建分支进行功能开发。

分支 作用 备注
Master 主分支,与生产环境的代码保持一致
Prelease 预发布分支,与预发布环境的代码保持一致
fea/xxx 开发分支从master创建分支

当你的功能开发完成并通过测试后,会新建一个MR(Merge Request与Pull Request类似,这是GitLab 里的叫法),请求合并到prelease分支。

发起MR后,就可以通知相关人员进行代码的Review,代码审核和讨论,没有问题后,会尝试合并到prelease。

这时自动构建工具会自动发布一个版本到预发布环境中。与此同时,根据这次改动将全部的代码打包一个全量/增量的zip压缩包,并请求发布系统获取标识唯一的版本号码,比如20190607_130102_9159

相关的开发和测试人员可以进行预发布环境的测试,当通过测试验证后,在发布系统对上述的版本号码进行发布,这样就更新到全量的线上机器了。

这里用一张图,说明该工作流程的步骤。
Git工作流程实践

常用技巧

Merge Request

我们采用GitLab的Merge Request机制进行代码Review,每一个新功能必须通过MR才能合并到prelease以及master。与GitLab Flow的上游优先,持续发布的原则类似,开发分支的代码只有在开发/测试环境通过了测试,才会允许发起MR合并到prelease。唯一例外的是,线上紧急问题的修复,是可以跳过这个流程的。

采用MR后,会利用no fast worword合并,并生成一个对应commit id,这样实现了代码线性的提交,也方便后面代码回滚。确认代码合并时,通常会选择合并后自动删除源分支的选项。

合并prelease的更新

开发人员提交MR后,可能会遇到prelease已更新,也就是落后提交的问题(x commits behind),这时,采用rebase的方式将prelease分支的代码与自己分支进行合并,并重新提交。

举例,当前你发起了一个MR,分支为fea/new,在merge_requests界面发现落后prelease几个提交,那么正确的方式是:

# 切换到prelease分支
git checkout prelease
# 拉取对应的更新
git pull --rebase origin prelease
# 切换到开发分支
git checkout fea/new
# 合并prelease的更新
git rebase prelease
# 推送到远端分支
git push -f origin fea/new

合并提交

为了方便他人阅读你的代码,也会要求开发人员将多次简短的提交,合并一个完整注释的提交,方便代码review。

举例,你会发现有这样的提交记录:

* 调试功能a x7 commitid7 author1 2019-06-15 17:00:07
* 调试功能a x6 commitid6 author1 2019-06-15 17:00:06
* 调试功能a x5 commitid5 author1 2019-06-15 17:00:07
* 调试功能a x4 commitid4 author1 2019-06-15 17:00:06
* 调试功能a x3 commitid3 author1 2019-06-15 17:00:07
* 调试功能a x2 commitid2 author1 2019-06-15 17:00:06
* 添加功能a    commitid1 author1 2019-06-15 17:00:07

你应该把这些提交合并到一起:

git checkout fea/new
git reset commitid1
git add .
git commit -m "+ 添加功能a,完成测试,参考下面的注释模板"
git push -f origin fea/new

Protected Branch

我们是会把prelease以及master进行保护,只有管理员、拥有代码审核权限的人员才会允许进行代码的推送。开发人员只允许推送自己的开发,测试分支。这样会避免prelease以及master主干分支的代码被不小心”污染”,也就是没有通过测试的代码提交到主干分支中。

注释模板

一个较好的开发习惯是提交详细的注释。详细的注释有几个好处:

  1. 提交更多的提交信息
  2. 方便快速浏览查找。
  3. 可以直接生成改动日志。

我常用的几个小技巧:

  1. 提交信息前添加固定字符代表增删改查,比如* 代表更新 + 代表添加 – 代表文件删除。
  2. 代码注释每行限制72个字符,方便过长被自动截断。
  3. 最后空出一个行,让上面的行作为标题,再下一行提供相关的链接和关键字。

一个简单的模板如下:

* 更新 写作 Git工作流程实践

整理自己在日常工作中实践下来,有效的的Git工作流程。

还有他人提供的常用提交模板,你也可以参考https://gist.github.com/jmaxhu/8e7fb69a7dcec1b9b953、

合并最新的代码

将自己的开发分支合并master更新的代码。这是一个很重要的操作。每天上班第一件事,就是拉取最新master分支的代码,采用rebase方式,合并自己开发分支的代码,保证自己的代码提交是线性的。这样在后续代码合并会显著的减少很多不必要的冲突合并时间。

总结

在这篇文章里,我分享自己在Git工作流程的一些尝试。定义工作流程不是目的,我认为最终目的是提升整体团队的工作效率以及避免经常遇到的”代码覆盖”问题,进而引起的”环境问题”。解决在日常工作可能会遇到的问题,才是我们最终目的。

每个团队的使用习惯,业务模式,可能都不相同。一种工作流程可能也无法满足所有人的需求,大家可以根据自己的习惯或者最适合当前团队的方法去尝试,去定义适合自身团队的工作流程。

Git工作流程实践

发表评论

电子邮件地址不会被公开。 必填项已用*标注