前言
已经使用git flow的开发人员,可以对git开发的头脑更佳清晰。对未使用git流,或者使用git不久的新人,可以极简单的理解分支流以及这么做的原因。
常见(好用)的分支体系
- master 线上版本
- master-B 预发布版本
- dev 测试版本
- f1,f2,f3功能分支
整个开发流呈现:
当发起一个新功能,从master中拉取出一个分支f4,在f4中完成功能,合并进dev测试,无恙后合并进master-B,让测试/玩家在预发布版本中体验,最后再进入master。
Git流大概是:
# 切换到master
git checkout master
## 新建功能4分支
git branch f4
## 切换到f4
git checkout f4
# f4开发和完成,检查master是否有更新,有则merge到f4中,f4推送到远程仓库
## git add .
## git commit -m "完成f4功能"
## git checkout master
## git pull origin master
## git checkout f4
## git merge master
## git push origin f4
# 合并f4进dev,并发布测试
## 在远程仓库中,pull request(f4 ---> dev),完成dev更新f4功能
## 在远程仓库中,pull request(f4 ---> master-B),完成master-b更新f4
##............................................(f4 ---> master), 完成master更新f4
这里不对原理过度解析,而是针对以下问题来解释为什么这样做?
1. 为什么不直接在dev上完成开发?
git流的原则是,只操作属于你的分支,换句话说,不论是master,master-B还是dev,你拥有的都是只读的权限,只有f4是你可以动的。为什么不直接在dev上完成开发:
- 因为可能同时开发n个功能,你和其他人同时开发dev,容易造成冲突。
- 因为dev上可能有一些未发布/未测试完的功能,假设你在dev上完成了f4,那么,你无法做到,从dev合并到master-B时,仅合并f4功能,而不合并未完成的f5功能。
2. 为什么完成f4后,要重新切换回master pull一下?
当你从master新建f4分支后,在你完成f4开发过程中,可能master有f5,f6功能合并并发布了。如果你在提交f4时,不重新merge一下master,在线上的pull request上,很大概率会出现合并冲突。
3. 为什么不是严格地dev --> master, 而是f4 --> master?
除非每个功能都串联开发,不然就会和问题1的第二个原因一样,无法在合并时,从dev中仅合并f4进master。
4. master-B预发布分支的必要性。
不是必要的,视情况而定。
下面,发一个各个分支的日常状态,或许你可以从中体会一些.
分支状态
假定数字示功能点,比如:
master: 1, 2 ,3
描述master分支,已完成功能1,功能2,功能3.
状态分析
master: 1, 2, 3, 16
master-B: 1, 2, 3, 4, 5 ,6, 15, 16
dev: 1, 2, 3 ,4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 16
f1: 1, 2, 3 , 12
f2: 1, 2, 3, 13, 16
f3: 1, 2, 3, 14
f4: 1, 2, 3,15
f5: 1, 2, 3 16
描述:
- f1 刚刚从master(1,2,3) 诞生,正在开发12功能,并且未完成,开发过程中,master有功能16合并,但是f1分支还未merge master。
- f2从master(1,2,3)诞生,开发13功能,未完成,对master的16功能已经进行了merge。
- f3从master(1,2,3)诞生,开发完成了f14,并且正在dev里进行测试,未(预)发布,因为f3在提交时,未merge master,就算f3在dev里测试成功了,在pr进master时,也有可能因为功能16而造成冲突。
- f4 完成了15功能,发布进了dev测试,并且进入了预发布master-B,pr进master时可能因为16发生冲突。
- f5 完成了16功能,并且先于f1,f2,f3,f4进行了迭代发布。f5不仅可以代表开发最快的功能,也能代表一些紧急的bug fix。
处理冲突
-
哪个功能出现冲突,哪个功能分支的所有者处理冲突。f4 —> dev 出现冲突,f4功能者处理,而不是dev管理员处理。
-
子功能者保持在master,master-B,dev只读的情况下进行合并冲突。本地pull master/dev/master-B,merge进f1,再让f1重新走上述开发流。
-
如果说,有一些功能,只能以git push -f 的方式合并,那一定是某一个开发者,以错误的方式操作了分支,比如直接基于dev开发了。
-
如果f1在重新走流程时,又有功能发布进了master怎么办?
不怎么办,不管是对master的bug fix还是新功能f2的开发,很大概率对f1的合并都不会造成冲突(仅需要对小概率的合并冲突处理)。 -
如果冲突很频繁,应该从以下层面考虑和优化:
项目架构,目录层级,代码层面上架构比较烂,导致不同功能开发经常出现共享文件、目录的修改,开发人员应该适当地优化项目目录的架构,而不是从分支入手。