什么是Gitflow

Gitflow是基于Git的强大分支能力所构建的一套软件开发工作流,最早由Vincent Driessen在2010年提出。最有名的大概是下面这张图。

在Gitflow的模型里,软件开发活动基于不同的分支:

  • The main branches

    *   master 该分支上的代码随时可以部署到生产环境
    
    • develop 作为每日构建的集成分支,到达稳定状态时可以发布并merge回master
  • Supporting branche
    *   Feature branches 每个新特性都在独立的feature branch上进行开发,并在开发结束后merge回develop
    
    • Release branches 为每次发布准备的release candidate,在这个分支上只进行bug fix,并在完成后merge回master和develop
    • Hotfix branches 用于快速修复,在修复完成后merge回master和develop

Gitflow通过不同分支间的交互规划了一套软件开发、集成、部署的工作流。听起来很棒,迫不及待想试试了?等等,让我们先看看Gitflow不是什么。

  • Gitflow不是Git社区的官方推荐工作流。是的,不要被名字骗到,这不是Linux内核开发的工作流也不是Git开发的工作流。这是最早由Web developer Vincent Driessen和他所在的组织采用并总结出的一套工作流程。
  • Gitflow也不是Github所推荐的工作流。Github对Gitflow里的某些部分有不同看法,他们利用简化的分支模型和Pull Request构建了适合自己的工作流Github Flow。
  • 现在我要告诉你,Gitflow在企业软件开发中甚至不是一个最佳实践。ThoughtWorks Technology Radar在2011年7月刊,2015年1月刊里多次表明了Gitflow背后的feature branch模型在生产实践中的危害,又在2015年11月刊里专门将Gitflow列为不被推荐的技术。

为什么Gitflow有问题

Gitflow对待分支的态度就像: Let's create branches just because... we can!

很多人吐槽,为什么开发一个新feature非得新开一个branch,而不是直接在develop上进行,难道就是为了……废弃掉未完成的feature时删除一个branch比较方便?

很多人诟病Gitflow太复杂。将这么一套复杂的流程应用到团队中,不仅需要每个人都能正确地理解和选择正确的分支进行工作,还对整个团队的纪律性提出了很高的要求。毕竟规则越复杂,应用起来就越难。很多团队可能不得不借助额外的帮助脚本去应用这一套复杂的规则。

然而最根本问题在于Gitflow背后的这一套feature branch模型。

VCS里的branch本质上是一种代码隔离的技术。使用feature branch通常的做法是:当developer开始一个新feature,基于develop branch的最新代码建立一个独立branch,然后在该branch上完成feature的开发。开发不同feature上的developers因为工作在彼此隔离的branch上,相互之间的工作不会有影响,直到feature开发完成,将feature branch上的代码merge回develop branch。

我们能看到feature branch最明显的两个好处是:

  1. 各个feature之间的代码是隔离的,可以独立地开发、构建、测试;
  2. 当feature的开发周期长于release周期时,可以避免未完成的feature进入生产环境。

后面我们会看到,第一点所带来的伤害要大于其好处,第二点也可以通过其他的技术来实现。

merge is merge

说到branch就不得不提起merge。merge代码总是痛苦和易错的。在软件开发的世界里,如果一件事很痛苦,那就频繁地去做它。比如集成很痛苦,那我们就nightly build或continuous integration,比如部署很痛苦,那我们就频繁发布或continuous deployment。 merge也是一样。所有的git教程和git工作流都会建议你频繁地从master pull代码,早做merge。

然而feature branch这个实践本身阻碍了频繁的merge: 因为不同feature branch只能从master或develop分支pull代码,而在较长周期的开发完成后才被merge回master。也就是说相对不同的feature branch,develop上的代码永远是过时的。如果feature开发的平均时间是一个月,feature A所基于的代码可能在一个月前已经被feature B所修改掉了,这一个月来一直是基于错误的代码进行开发,而直到feature branch B被merge回develop才能获得反馈,到最后merge的成本是非常高的。

现代的分布式版本控制系统在处理merge的能力上有很大的提升。大多数基于文本的冲突都能被git检测出来并自动处理,然而面对哪怕最基本的语义冲突上,git仍是束手无策。在同一个codebase里使用IDE进行rename是一件非常简单安全的事情。如果branch A对某函数进行了rename,于此同时另一个独立的branch仍然使用旧的函数名称进行大量调用,在两个branch进行合并时就会产生无法自动处理的冲突。

如果连rename这么简单的重构都可能面临大量冲突,团队就会倾向于少做重构甚至不做重构。最后代码的质量只能是每况愈差逐渐腐烂。

持续集成

如果feature branch要在feature开发完成才被merge回develop分支,那我们如何做持续集成呢?毕竟持续集成不是自己在本地把所有测试跑一遍,持续集成是把来自不同developer不同team的代码集成在一起,确保能构建成功通过所有的测试。按照持续集成的纪律,本地代码必须每日进行集成,我想大概有这几种方案:

  1. 每个feature在一天内完成,然后集成回develop分支。这恐怕是不太可能的。况且如何每个feature如果能在一天内完成,我们为啥还专门开一个分支?
  2. 每个分支有自己独立的持续集成环境,在分支内进行持续集成。然而为每个环境准备单独的持续集成环境是需要额外的硬件资源和虚拟化能力的,假设这点没有问题,不同分支间如果不进行集成,仍然不算真正意义上的持续集成,到最后的big bang conflict总是无法避免。
  3. 每个分支有自己独立的持续集成环境,在分支内进行持续集成,同时每日将不同分支merge回develop分支进行集成。听起来很完美,不同分支间的代码也可以持续集成了。可发生了冲突、CI挂掉谁来修呢,也就是说我们还是得关心其他developer和其他团队的开发情况。不是说好了用feature branch就可以不管他们自己玩吗,那我们要feature branch还有什么用呢?

所以你会发现,在坚持持续集成实践的情况下,feature branch是一件非常矛盾的事情。持续集成在鼓励更加频繁的代码集成和交互,让冲突越早解决越好。feature branch的代码隔离策略却在尽可能推迟代码的集成。延迟集成所带来的恶果在软件开发的历史上已经出现过很多次了,每个团队自己写自己的代码是挺high,到最后不同团队进行联调集成的时候就傻眼了,经常出现写两个月代码,花一个月时间集成的情况,质量还无法保证。

如果不用Gitflow...

如果不用Gitflow,我们应该使用什么样的开发工作流?如果你还没听过Trunk Based Development,那你应该用起来了。

是的,所有的开发工作都在同一个master分支上进行,同时利用Continuous Integration确保master上的代码随时都是production ready的。从master上拉出release分支进行release的追踪。

可是feature branch可以确保没完成的feature不会进入到production呀。没关系,Feature Toggle技术也可以帮你做到这一点。如果系统有一项很大的修改,比如替换掉目前的ORM,如何采用这种策略呢?你可以试试Branch by Abstraction。我们这些策略来避免feature branch是因为本质上来说,feature branch是穷人版的模块化架构。当你的系统无法在部署时或运行时切换feature时,就只能依赖版本控制系统和手工merge了。

Branch is not evil

虽然long lived branch是一种不好的实践,但branch作为一种轻量级的代码隔离技术还是非常有价值的。比如在分布式版本控制系统里,我们不用再依赖某个中心服务器,可以进行独立的开发和commit。比如在一些探索性任务上,我们可以开启branch进行大胆的尝试。

技术用的对不对,还是要看上下文。

[参考文献]

  1. Long-lived-branches-with-gitflow in radar: https://www.thoughtworks.com/radar/techniques/long-lived-branches-with-gitflow
  2. Gitflow in radar: https://www.thoughtworks.com/radar/techniques/gitflow
  3. Feature Branching in radar: https://www.thoughtworks.com/radar/techniques/feature-branching
  4. Fowler on feature branch: http://martinfowler.com/bliki/FeatureBranch.html
  5. Fowler on continuous integration: http://www.martinfowler.com/articles/continuousIntegration.html
  6. Paul Hammant on TBD: http://paulhammant.com/2015/12/13/trunk-based-development-when-to-branch-for-release/
  7. Google's Scaled Trunk Based Development: http://paulhammant.com/2013/05/06/googles-scaled-trunk-based-development/
  8. Trunk Based Development at Facebook: http://paulhammant.com/2013/03/04/facebook-tbd/
  9. Fowler on feature toggle: http://martinfowler.com/bliki/FeatureToggle.html
  10. Jez Humble on branch by abstraction:http://continuousdelivery.com/2011/05/make-large-scale-changes-incrementally-with-branch-by-abstraction/
  11. Fowler on branch by abstraction: http://martinfowler.com/bliki/BranchByAbstraction.html

Gitflow有害论相关推荐

  1. git的操作说明超详细

    2019独角兽企业重金招聘Python工程师标准>>> 说明: 个人在学习Git工作流的过程中,从原有的 SVN 模式很难完全理解Git的协作模式,直到有一天我看到了下面的文章,好多 ...

  2. 四种常见的Git工作流

    在这篇文章中,我们将会讨论最受Git用户欢迎的几种分支工作流程,您可以选择最适合自己的方式. Git Flow Git工作流是最广为人知的工作流.由Vincent Driessen 在2010年所发明 ...

  3. gitflow分支管理模型

    gitflow的分支类型: master分支(1个) develop分支(1个) feature分支.同时存在多个. release分支.同一时间只有1个,生命周期很短,只是为了发布. hotfix分 ...

  4. Git基本命令和GitFlow工作流

    本篇博客讲解了git的一些基本的团队协作命令,和GitFlow工作流指南 git 团队协作的一些命令 1.开分支 git branch 新分支名 例如,在master分支下,新开一个开发分支: git ...

  5. 基于Gitflow分支模型自动化Java项目工作流

    Gitflow是一种协作分支模型,利用了Git分支的强大功能.速度和简单性.但有关如何在部署管道中使用Gitflow的文档不是很完善.在构建.测试.部署快照版本和部署发布版本时,我们应该使用哪些众所周 ...

  6. Google X垃圾分类机器人横空出世,再也不怕分不清干垃圾湿垃圾有害垃圾了

    郭一璞 发自 凹非寺 量子位 报道 | 公众号 QbitAI 从上海,到北京,每个城市都在搞垃圾分类. 干垃圾.湿垃圾.有害垃圾,猪不能吃.猪能吃.猪吃了会死--你是不是还在为这些垃圾分别是什么而苦恼 ...

  7. 前端小纠结--集成gitflow和standard-version使用

    请看上一篇前端小纠结--约定式提交和自动生成changelog git flow工作流对比 Git工作流指南 git flow 介绍 git flow源自这篇文章a-successful-git-br ...

  8. git-flow 工作流程简介

    从svn迁移到git了 , 补充一下git的知识和Git Flow在团队中的应用 Git主要优点有 分布式存储 , 本地仓库包含了远程仓库的所有内容 . 安全性高 , 远程仓库文件丢失了也不怕 优秀的 ...

  9. Git 版本控制之 GitFlow

    来源:  http://t.cn/EbZKx96 最近在着手制定开发规范,想要把项目正规高效的跑起来.计划引入 Git 版本控制,Git-Flow 便成为了首选.因为之前并没有过多接触,所以先花些时间 ...

最新文章

  1. 操作系统识别工具 xprobe2 p0f 简介
  2. Vue watch如何同时监听多个属性?
  3. windows服务autofac注入quartz任务
  4. oracle移动硬盘盒,oracle-linux下挂载移动硬盘 NTFS类型
  5. 纯干货分享 | 考PMP留下来的一些重要资料(收藏下载)
  6. 软件项目启动ppt_一直在启动不可行的软件项目
  7. 双绞线的规范和制作经验谈
  8. Show一下拿的奖杯
  9. win7安全模式计算机管理在哪里,win7安全模式怎么进
  10. Android 开发摆脱数据线 - Android studio 无线调试App
  11. 微信小程序不能直接加载本地静态图像作为背景的解决办法
  12. Python 数据分析微专业课程--项目06 城市餐饮店铺选址分析
  13. 忠告,男人、女人各100条
  14. Word论文公式的两个格式问题
  15. NXP i.MX8M Plus赋能边缘机器学习,启扬IAC-IMX8MP-Kit开发板
  16. 我的团队——风信子网络工作室简介
  17. 各种 maven 依赖
  18. 从Eigen向量化谈内存对齐
  19. 放假了,讲个真实的转岗故事
  20. SV小项目—异步fifo的简单验证环境搭建(全)

热门文章

  1. 前端 forward和redirect区别
  2. 程序和进程的区别是什么?
  3. log4j--分路径存储日志
  4. c语言上三角矩阵的检查
  5. 三星Galaxy note I9220 N7000 刷机ROOT工具及ROM下载
  6. 联想发布Lecoo掘金宝智能路由器S1,与Newifi新路由挖同一个黄金矿区
  7. 华为手机还有这么好用的翻译功能!说话就能语音翻译,高效又便捷
  8. web of science无法导出全记录与被引用的参考文献
  9. Unity3D C# 中foreach的GC产出(2023年带数据)
  10. Espeak最详细安装过程!