Disappointingly, we continue to see development teams embrace the practice of feature branching to isolate work and defer integration. Feature branches commonly cause significant pain and unpredictability during late merges, but more importantly prevent the continual design improvement necessary to maintain high quality software. We recommend continuous integration and branch by abstraction as an alternative to feature branching.
Gitflow is a strict branching pattern for releases using Git. Although not an inherently bad pattern, we often see it misused. If the feature and develop branches are short lived and merged often, you are really using the power of Git, which makes these activities easy. However, a problem we often see is that these become long lived branches, which results in the dreaded merge conflicts many people began using Git to escape. A merge is a merge. Regardless of the source control tool or pattern you use. If you wait more than a day or two to merge, you could hit a big merge conflict. This becomes a real issue if you have a larger team. If you have more than a few people waiting to merge, you can have a serious a bottleneck. Introducing patterns like Gitflow require the discipline to merge often to be successful. So by all means use the pattern, but only if you have the discipline to prevent long lived branches
We firmly believe that long-lived version-control branches harm valuable engineering practices such as continuous integration, and this belief underlies our dislike for Gitflow. We love the flexibility of Git underneath but abhor tools that encourage bad engineering practices. Very short-lived branches hurt less, but most teams we see using Gitflow feel empowered to abuse its branch-heavy workflow, which encourages late integration (therefore discouraging true continuous integration).
这些内容的核心在于GitFlow重视管理，强调多分支开发，会造成集成滞后，合并困难，影响持续集成。在2016年发布的文章中，TW给出了几个其他的建议，包括推荐GitHub Flow和Trunk-Based Developmeng
二、GitHub Flow。这个是GitHub的Scott Chacon于2011年提出的，针对的就是GitFlow。但是其中主要问题并不是针对GitFlow，而是针对有人开发的GitFlow Script，这些Script用于相对强制性地执行GitFlow规则，但是仅支持命令行，因此被很多人吐槽。Scott给出了GitHub的模型，即GitHub Flow。GitHub Flow希望针对的场景是每天发布几次产品代码的场景（个人认为这是DevOps场景，而不是产品交付型场景），希望采用敏捷的场景每天多次解决小问题。
- Anything in the master branch is deployable
- To work on something new, create a descriptively named branch off of master (ie: new-oauth2-scopes)
- Commit to that branch locally and regularly push your work to the same named branch on the server
- When you need feedback or help, or you think the branch is ready for merging, open a pull request
- After someone else has reviewed and signed off on the feature, you can merge it into master
- Once it is merged and pushed to ‘master’, you can and should deploy immediately
GitHub is 35 employees now, maybe 15-20 of whom work on the same project (github.com) at the same time. I think that most development teams – groups that work on the same logical code at the same time which could produce conflicts – are around this size or smaller.
三、Trunk Based development。这是Paul Hammant 2013年提出的模型，这个模型不用多解释，基本就是SVN的模型，在TBD模型中，所有开发都在主干，但是拉出新的分支交付。这个场景下，假设所有的特性开发都可以快速完成，这样就不会影响CI。
- You’ve broken your application into multiple components.
- Each component into a directory inside the trunk (possibly hierarchical).
- Each directory its own source self-contained and its own build (possibly hierarchical).
- You have a good set of unit tests and consider them important enough to illustrate snippets of example usage.
- Continuous Integration drives things, even for hundreds of components, that drops items into a Maven-like repository. CruiseControl has a nice <httpfile/> directive that with the <include-projects/> directive that allows you to set up the killer CI installation that is branch-ready meaning you can run without a dedicated CI administrator.
- Your management are good at release planning.
- Developers are in the habit of never breaking the build 🙂
但是针对大型变更的时候（如替换某中间件），上述流程被打乱了，因此提出了BBA（Branch By Abstraction）
- Introduce an abstraction over the core bits of the big thing you’re going to change and commit
- Update all the bits of code that were formerly using the thing directly to use it via the new abstraction and commit
- Make a second implementation of the abstraction, with unit tests that specifically test its core functionality and commit
- Update all the code from (2) to use the new implementation (still via the abstraction)* and commit
- Deprecate the first implementation (or skip to 6 if you don’t want a respectful grace period).
- Delete the first implementation (its proven there is no need for you to go back).
- Remove the abstraction (if it is inelegant).