为什么要使用GitFlow工作流
主要因为我们的生产过程是比较复杂的,软件生产中会有各式各样的问题,并要面对不同的环境。我们要在不停地开发新代码的同时,维护线上的代码。于是,就有了下面这些需求。
-
希望有一个分支是非常干净的,上面是可以发布的代码,上面的改动永远都是可以发布到生产环境中的。这个分支上不能有中间开发过程中不可以上生产线的代码提交。
-
希望当代码达到可以上线的状态时,也就是在 alpha/beta release 时,在测试和交付的过程中,依然可以开发下一个版本的代码。
-
最后,对于已经发布的代码,也会有一些 Bug-fix 的改动,不会将正在开发的代码提交到生产线上去。
GitFlow工作流说明
![](https://img.haomeiwen.com/i9320976/5061fba5149b1235.png)
整个代码库中一共有五种分支。
-
master 分支。也就是主干分支,用作发布环境,上面的每一次提交都是可以发布的。
-
feature 分支。也就是功能分支,用于开发功能,其对应的是开发环境。
-
develop 分支。是开发分支,一旦功能开发完成,就向 develop 分支合并,合并完成后,删除功能分支。这个分支对应的是集成测试环境。
-
release 分支。当 develop 分支测试达到可以发布状态时,开出一个 release 分支来,然后做发布前的准备工作。这个分支对应的是预发环境。之所以需要这个 release 分支,是我们的开发可以继续向前,不会因为要发布而被 block 住而不能提交。
一旦 release 分支上的代码达到可以上线的状态,那么需要把 release 分支向 master 分支和 develop 分支同时合并,以保证代码的一致性。然后再把 Release 分支删除掉。
- hotfix 分支。是用于处理生产线上代码的 bug-fix,每个线上代码的 bug-fix 都需要开一个 hotfix 分支,完成后,向 develop 分支和 master 分支上合并。合并完成后,删除 hotfix 分支。
这就是整个 GitFlow 协同工作流的工作过程。我们可以看到:
-
我们需要长期维护 master 和 develop 两个分支。
-
这其中的方式还是有一定复杂度的,尤其是 release 和 hotfix 分支需要同时向两个分支作合并。所以,如果没有一个好的工具来支撑的话,这会因为我们可能会忘了做一些操作而导致代码不一致。这里推荐
sourcetree
,完美契合GitFlow工作流。
几个问题
- 为什么要使用feature分支,直接在develop分支上开发不是很方便吗?
(1) 每个feature是一个独立的需求或者功能,要通过严格自测后才能合并到develop,否则大家都在develop上开发,测试则要一遍遍的回归。
(2) 一个大功能的开发可能是跨版本的,直接在develop上开发会造成当前版本无法上线。
(3) 开发过程中开发功能互相不影响,一个功能需要多个人一起开发,则那几个人可以在那个功能分支共同开发,不会影响团队其它人的开发工作。
- 什么时候创建release分支?开出release后产品有新增了一个需求需要当前版本上怎么办?开出release后一个开发说我的feature还没开发完没有合并到develop怎么办?
(1) 当大家按计划完成功能开发并向develop分支合并完成后,项目负责人确认向各成员确认无误后创建release分支,在release分支上只应该做bug修复。
(2) 可以在release上新开一个feature,完成功能后合并到release和develop,并删除该feature。这种情况下该feature的代码未在develop完成测试,会增加release的不稳定性,加重测试的工作,但技术应当为产品服务,需求确实要z在这个版本完成也没有办法。
(3) 应当避免这种情况的发生,工作流需要大家遵守规则,如果确实发生了,只能在完成该feature后,合并到release和develop,并删除该feature。这种情况同样会增加release的不稳定性。
- 分支太多,feature、hotfix、release分支合并完成后忘记删除导致分支杂乱。
养成良好的习惯,其次使用对应的工具帮助管理工作流,会节省时间,提高效率,减少失误。但是工具是建立在理解GitFlow的基础上,如果不清楚操作对应执行了什么,用工具也会造成错误。这里再次推荐sourcetree
。
- 发布新版本的时候是否应当打上tag?
应该要,release向master合并前应该打一个tag,比如v3.7.0,hotfix向master合并前应当打一个tag,比如3.7.1,这样线上可以清晰的版本走势,在回滚时也不会迷失在繁多的commit中。
- feature、hotfix分支是否需要推送到远端?
如果该功能是独立完成,则不用,多人一起完成一个功能,则要推送远端。hotfix同理。如果有推送到远端,则删除分支时应同时删除远端对应分支。
- GitFlow是否太重,操作太繁琐?
GitFlow的每一个分支都解决了对应的问题,但是工作流是为了持续开发,更好的协同合作而存在的,在实际开发中,可以根据实际情况做对应的调整。比如迭代的速度足够快,没有跨版本需求,测试的规范无需那么严格就可以直接在develop分支开发,砍掉feature分支。比如每个版本的功能很有计划,不会在当前版本未上线时开发下一个版本,那么release分支也就无需存在了。比如在修改线上bug时离上线时间还有很久,此时也没有其它人在改bug或者需要上线,那么hotfix其实也就没有必要创建。
我在想,是否有一种工作流,可以面对我们现实工作中的各种情况。但是,这个世界太复杂,应该不存在一种一招鲜吃遍天的银弹方案。流程是为了解决普遍的问题,提高整体的工作效率和可靠性,但是在局部就会有降低效率的情况出现。应当根据实际情况选择和调整我们的协同工作的方式。
基本实践
假设当前线上版本为v3.7.3,此时要开发3.8.0的需求,开发A(小明)接到了两个功能(假设是购物车优化和余额提现)的需求。此时小明的开发流程应当是:
- 如果当前工作副本的分支不是develop,那么应当切换到develop分支,并且pull代码。
git checkout develop // 如果当前就在develop无需这一步
git pull origin develop
- 小明决定先做购物车优化,于是他基于develop分支创建feature/shopping-cart-improve,并切换到feature/shopping-cart-improve开始开发。
git checkout -b feature/shopping-cart-improve // 创建feature/shopping-cart-improv分支,然后切换到feature/shopping-cart-improv分支,带上-b相当于两条命令:git branch feature/shopping-cart-improve 和 git checkout feature/shopping-cart-improve
- 小明在开发时突然收到线上出了一个bug(下单失败),需要他去修复,于是他先commit当前代码(不commit不能切换分支哦),然后切换到master分支,执行pull,基于master创建并切换到hotfix/order-fail,修复bug,commit并合并到master,在master分支打上一个tag,push代码和tag到远端,然后发布master分支的代码上线。把hotfix/order-fail分支合并到develop,最后删除hotfix/order-fail分支。
git add .
git commit -m "shopping-cart-improve is developing"
git checkout master
git pull origin master
git checkout -b hotfix/order-fail
git add . // 修复bug后
git commit -m "fix issue # create order fail"
git checkout master
git pull origin master
git merge hotfix/order-fail
git tag // 查看当前分支下的标签,假如是v3.7.3
git tag -a v3.7.4 -m "fix issue # create order fail"
git push origin master
git push origin --tags
git checkout develop
git pull origin develop
git merge hotfix/order-fail
git branch -d hotfix/order-fail
- 小明修复完bug后回来继续开发购物车优化的需求。
git checkout feature/shopping-cart-improve
git merge develop
- 小明继续开发,小东(另一个开发)告知他他写了一个公共类,小明可以在这个功能的开发中使用,并且小东已经提交到develop分支。小明则切换到develop分支更新代码,并合并到feature/shopping-cart-improve(实际上这个动作应该常做,比如在你下班前或者刚上班时,因为其它开发成员完成功能开发或者修复bug,则develop分支的代码就有变动,应该及时合并到你的feature分支)
git add .
git commit -m "shopping-cart-improve is developing"
git checkout develop
git pull origin develop
git checkout feature/shopping-cart-improve
git merge develop
- 小明完成购物车优化需求开发,并自测无误后,提交代码并合并到develop分支,并删除feature/shopping-cart-improve分支
git add .
git commit -m "complete shopping-cart-improve"
git checkout develop
git pull origin develop
git merge feature/shopping-cart-improve
git branch -d feature/shopping-cart-improve
- 小明开始余额提现需求提现的开发,并完成。
git checkout -b feature/balance-withdraw
git add . // 完成开发后
git commit -m "complete balance-withdraw"
git checkout develop
git pull origin develop
git merge feature/balance-withdraw
git branch -d feature/balance-withdraw
- 团队所有成员的开发工作都完成了,项目负责人小江确认无误后新建release分支
git checkout develop
git pull origin develop
git checkout -b release/v3.8.0
git push origin release/v3.8.0
- 测试ing,开发人员在release/v3.8.0上修改bug,完成后小江准备上线
git pull origin release/v3.8.0
git checkout master
git pull origin master
git merge release/v3.8.0
git tag -a v3.8.0 -m "complete 3.8.0"
git push origin master
git push origin --tags
git checkout develop
git pull origin develop
git merge release/v3.8.0
git branch -d release/v3.8.0
git push origin --delete release/v3.8.0
网友评论