构建高质量软件:持续集成与持续交付系统实践
上QQ阅读APP看书,第一时间看更新

3.6 Git工作流程

图3-14所示的是Git工作流程(Git Work Flow)的示意图,目前业界主流的一种最佳实践,笔者在日常工作中也经常使用这样的模型管理项目的代码。

图3-14中包含了五种类型的分支和Tag,它们的用途和相互之间的关系说明如下。

  • master分支:首次创建Git仓库时,都会有一个master分支(GitHub中称之为main分支),主要用于存储和管理相对全量的、稳定的变更提交。初始时的提交动作都发生在master分支上,比如,图3-14中的C1提交。master分支的另外一个用途是为其他分支提供创建的基础(因为它的变化比较小,而且接收的都是经过了测试证明且相对比较稳定的变更),也就是说其他分支将会基于master分支进行创建,比如,develop分支。根据图3-14所示的模型,master分支只接受来自其他分支的merge提交,而不是直接在master分支上进行更改并提交。
092-01

图3-14 Git工作流程图示

  • develop分支:该分支是基于master分支创建的,同样不能在该分支上直接更改和提交,它只接受来自其他分支的merge提交。相对于master分支而言,develop分支的变化比较频繁,并且在开发阶段,它的最近一次提交(HEAD指针)比master分支的最近一次提交要更新一些。针对软件新功能的迭代和开发,都会基于develop分支来创建,比如图3-14中的feature1和feature2分支。
  • feature分支:当开发人员接收到某个开发任务时(按照敏捷方法论,该任务应具有功能职责单一、工作包清晰、易于跟踪进度、时间成本可度量、进度可控等特点),首先应更新(pull操作)本地的develop分支,获得develop分支最新的提交,然后基于develop分支创建feature分支,常见的命名方式为feature/taskid,比如,feature/jira123。在开发人员完成开发、单元测试和代码检查后,即可发起合并至develop分支的请求,代码在经过了其他人员的审核之后才会合并至develop分支(在若干次迭代之后,需要删除一些较老的feature分支,以避免Git仓库中feature分支过多)。
  • release分支:如果当前迭代的所有开发工作全部完成,并且通过了验收测试,那么接下来就需要基于develop分支创建release分支,以用于软件包的发布。图3-14中,C6提交是软件包发布之前最近的一次提交,同时,基于develop分支的所有变更都会合并(merge)回master分支,以确保master分支始终维护和管理着稳定的全量变更。当然,这只能算是一个小小的里程碑,我们通常还会针对C6提交创建一个不可变的tag-v0.1。
  • hotfix:即使做了大量的测试,也无法百分之百保证发布(release)后的软件包不存在缺陷。如果在发布之后才发现软件包出现了问题,那么开发人员就需要对问题进行紧急修复,因此要基于tag-v0.1创建新的分支hotfix,对问题的修复动作将发生在hotfix分支上,比如,图3-14中的C7提交。当问题在开发环境中经历了重现、修复和测试之后,就可以发布hotfix版本的软件包了,如图3-14中所示的tag-v0.1.1,最后将hotfix分支中的变更合并至develop分支。
# 假设当前的sprint中要开发两个小的功能,其对应的任务(task)id分别为123和124。
# 开发人员 A针对task 123,创建了features/jira123分支,并且完成了开发任务。
# 开发人员 B针对task 124,创建了features/jira124分支,并且完成了开发任务。
# 下面通过git log命令查看提交记录。
> git log --graph --abbrev-commit --decorate --oneline --date=relative --all
* 32c84db (features/jira123) add the file 6.txt
* f455e50 add the file 5.txt
* 5025f9c add the file 3.txt
| * c3e5fd6 (features/jira124) add the file 4.txt
| * 75e82cf add the file 2.txt
|/
* 192f143 (HEAD -> develop, master) initial commit

#开发人员A和B都对代码进行了测试和检查,以确保没有问题,现在需要将变更代码合并至develop分支。
> git merge features/jira123
> git merge features/jira124
> git log --graph --abbrev-commit --decorate --oneline --date=relative --all
*   f0b2bd7 (HEAD -> develop) Merge branch 'features/jira124' into develop
|\
| * c3e5fd6 (features/jira124) add the file 4.txt
| * 75e82cf add the file 2.txt
* | 32c84db (features/jira123) add the file 6.txt
* | f455e50 add the file 5.txt
* | 5025f9c add the file 3.txt
|/
* 192f143 (master) initial commit
#对develop分支的提交进行功能测试,并在确保无误后合并至master分支。
> git checkout master
> git merge develop
> git log --graph --abbrev-commit --decorate --oneline --date=relative --all
*   f0b2bd7 (HEAD -> master, develop) Merge branch 'features/jira124' into develop
|\
| * c3e5fd6 (features/jira124) add the file 4.txt
| * 75e82cf add the file 2.txt
* | 32c84db (features/jira123) add the file 6.txt
* | f455e50 add the file 5.txt
* | 5025f9c add the file 3.txt
|/
* 192f143 initial commit
# 完成小小的里程碑,基于master分支最新的提交,创建一个tag。
> git tag -a v0.1 HEAD -m "stable version v0.1"
> git log --graph --abbrev-commit --decorate --oneline --date=relative --all
*   f0b2bd7 (HEAD -> master, tag: v0.1, develop) Merge branch 'features/jira124' into develop
|\
| * c3e5fd6 (features/jira124) add the file 4.txt
| * 75e82cf add the file 2.txt
* | 32c84db (features/jira123) add the file 6.txt
* | f455e50 add the file 5.txt
* | 5025f9c add the file 3.txt
|/
* 192f143 initial commit
# release分支和hotfix分支的创建大同小异,大家可以自行尝试。