What are the pros and cons of using a trunk-based Vs feature-based workflow in Git? [closed]
Asked Answered
F

2

32

I pretty much like the idea of the feature-based workflow in Git: using feature branches to support parallel development.

In a feature-based workflow, I would develop my tasks in a feature branch (off master), and I would rebase often from master to avoid potential conflicts. If collaborative, I will push/pull the feature branch to the remote. When ready to integrate to master, I open a pull-request from my feature branch to master, so that the pull-requests is reviewed by peers & automatically assessed to know if the pull-request (the merge of my feature branch into master) passes the build and unit-tests. If the pull-request is "green" then my feature branch is automatically merged to master.

I find the aforementioned workflow fine. However, in some internet posts, they advocate for a "trunk-based development" (e.g. 1, 2).

As far as I am concerned, trunk-based development does not encourage developing into separate feature branches but all developers develop into master. This model, encourages that developers integrate daily (Martin Fowler's CI practice) to the master to avoid conflicts (in contrast, what I would do is to rebase my feature branch on master).

I was wondering which advantages this model would carry over the feature-based model. I have several doubts with the trunk-based model:

  1. How would code-review be done? In feature-based model is easy: into the feature branch. In the trunk-based model, since all the commits are published in master, how can I make them reviewed? In fact, if I resolve conflicts when merging into master, wouldn't this commits appear as to be reviewed (i wouldn't like that)?

  2. How would two developers collaborate on the same feature? In the feature-based model, both would work on the feature branch. In the trunk-based model, all developers would be collaborating in "all the features" (somehow). Right?

  3. I believe, the trunk based model was "created" to avoid the problem of long-lived feature branches are their potential conflict hell when merging it to the mainline. However, if feature branches are short-lived, and if they are often rebased from the mainline, what is the issue then?

  4. Overall, which benefits can carry the trunk-based compared to the feature-based workflow?

Thanks :-)

Felic answered 9/2, 2017 at 11:30 Comment(4)
The barro.github.io/2016/02/… blog article is almost complete non-sense. It just shows that the author did not understand Git Flow at all. Git Flow is fine and very flexible. Read my comment on that article that I just wrote to learn some of the mistakes the blog author has done in his article.Nathannathanael
I find all your comments to the post reasonable. I couldn't make the cactus model work in my head. I didn't/don't get it at all. additionally, why don't they merge release branches to master?... I agree with you - GitFlow seems flexible to me, but I guess most of the people arguing against it make some assumptions that are not entirely correct. Thanks for the post!Felic
Also, the spaghetti hell the other article is complaining about is of course not nice to look at, but simply do a rebase before doing the merge and you have a history that is almost linear but you still can see which commits make up a feature initially.Nathannathanael
totally agree :-)Felic
F
14

Your reference 1 already discuss some points about code-review. This answer is primarily based on my experience at work with the Gerrit tool and trunk-based workflow.

  1. How would code-review be done? In feature-based model is easy: into the feature branch. In the trunk-based model, since all the commits are published in master, how can I make them reviewed? In fact, if I resolve conflicts when merging into master, wouldn't this commits appear as to be reviewed (i wouldn't like that)?

The code-review in trunk-based workflow ideally should be done before commits integrate into master. Manually, developers would push their commits to some temporary feature branch and, when approved, rebase those commits into master and push them (optionally squashing them into a single commit).

Gerrit automates this process. When pushing a commit to Gerrit, it creates an (almost invisible) temporary set of branches to hold the commit under review. During review, any corrections made are amended to the commit under review and pushed again to Gerrit. Once approved, the commits are integrated into master atomically (user can chose how among options like rebase, cherry-pick and merge).

Gerrit is best used for code-review in trunk-based workflow, since it promotes review commit-by-commit and the pushed commits only appear in master after passing review (corrections are done as amends, so "wrong" commits never go to master).

  1. How would two developers collaborate on the same feature? In the feature-based model, both would work on the feature branch. In the trunk-based model, all developers would be collaborating in "all the features" (somehow). Right?

Right. Since all features are developed in the same branch, all developers commits on that same branch. Code review (and continuous integration) will give some confidence that this branch is always sufficiently stable (at least for development, if not for production).

The drawback is that commits of different complex features become interleaved in the log - adding numbers of some issue tracking system helps a lot. However, squashing commits after code-review, or using Gerrit (which forces the reivew commit-by-commit, not branch-by-branch), experience has shown that most features are just a single commit (equivalent to the merge commit in a feature-based workflow).

  1. I believe, the trunk based model was "created" to avoid the problem of long-lived feature branches are their potential conflict hell when merging it to the mainline. However, if feature branches are short-lived, and if they are often rebased from the mainline, what is the issue then?

The problem lies when some long-lived feature branch is integrated into the master. Then every other long-lived feature branch will have to integrate all changes from that finished feature all at once. That's even worse if both the finished and the rebasing feature branches have done some refactoring.

  1. Overall, which benefits can carry the trunk-based compared to the feature-based workflow?

The greatest benefits I have seen are:

  • More linear history, which is easier to understand and to make cherry-picks and reverts.
  • Smaller conflict resolutions, mainly in case of major refactorings.

However, I'd like to recommend again using Gerrit (or some similar tool) to automate code-review process in trunk-based workflow instead of using a tool designed for reviewing pull-requests (feature-based workflow).

Flanders answered 9/2, 2017 at 12:27 Comment(11)
Thanks for sharing your experience. 1. Regarding, code-review, I have not yet worked Gerrit, but will have to look at it. 2. I still think, feature-based development is a nicer approach. I see no issues in using feature branches (if not long-lived) and you can still guarantee mainline stability if you pre-test the integrations. 3. Linear history can be achieved also (to some extent) with feature branches, if you rebase before merging, and/or if you merge with a fast forward.Felic
what about CI enforcement? would all developers integrate daily? BAsed on your experience, how many commits a day would each developer perform to master?Felic
@letimome, Gerrit provides an event stream to integrate with CI systems. We use Jenkins (with Gerrit Trigger plugin) to verify all code changes sent to review, so we execute automated tests with integrated code even before the code is actually integrated. Some teams also execute a publishing step automatically when code is integrated. About the commit rate, I don't see neither workflow limiting it in any way (we don't commit often, however). The difference is that with Gerrit, we make 1-5 commits before code-review approval that never appear on the master's log.Interlaminate
About the commit rate: as I see it, the more "gates" you put to the integration (code-review, build, tests), the less likely you have a "pure CI practice" (CI, as the practice to commit often to mainline, multiple times a day). At the end, it is a trade-off of: commit rate Vs mainline stability.Felic
What happens if a major feature is split into multiple commits and then a release needs to happen (for business reasons or because an immediate fix is required) how do you deal with a feature being partially implemented such that you can’t release the app in that state?Myoglobin
@Jonathan., for immediate fixes, I'd recommend creating a release branch from the tag and cherry-picking the fixes (there is nothing wrong with release-branches on trunk-based workflow). But if you want select features will go into the next release and which won't, then you want a feature-based workflow (where you pick the features you want) instead of a trunk-based workflow (where you have maximum integration at all times). Of course, a hybrid approach is also possible: create feature-branches for those features the team is not certain when they should be released.Interlaminate
@Myoglobin Part of CI / TBD is never breaking the build. So if you have to split a feature across multiple commits, you write the code in such a way that the system won't be broken at an intermediate stage. That might be by adding a config option for the feature, switched off by default, or it might just waiting until the feature is usable before adding a link to it from another screen of the application.Despain
@Despain that seem like it would just cause the code to be filled with a bunch of if statements on config options for all the different features?Myoglobin
@Myoglobin Yes that is a risk and something you want to avoid. It shouldn't be too much of an issue if you don't have many tasks in progress at once and you remove the config option from the code once a task is done. And the last option I mentioned (wire the feature up to the UI after building it) is usually better than adding a config option.Despain
Author suggests using Gerrit, and this is only tool I know to support trunk-based code-review on some server-in-the-middle to master.Introjection
cont. In fact it imitates feature-merges that exists in feature-branch world. I do not like Gerrit (only my opinion) as it adds lot of complexity to overall process and adds its own concepts (like patchsets, etc) and bases its review on those concepts. One thing I don't like more - Gerrit implicitly pushes developer to make bigger commits using amend. Before Gerrit we moslty had one-line commit per 10 code lines, and now same one-line commit per 200-300 modified lines. And uncomfortable scenarios when you need to share your work with colleagues. It can be done, but in not very convenient way.Introjection
I
4

Like you, the developers here at Debitoor had some doubts with trunk based development. To overcome these problems, they came up with an innovative solution they call Koritsu.

Kōritsu is the Japanese word for efficiency, and the approach is designed to ensure developers never interrupt or block each other. Koritsu is fairly similar to short lived feature branches, except it lets the feature branches live for up to a week and automatically deploy every merge to trunk.

Debitoor has been using Koritsu for several years for our website and mobile development. For us, its been been running smoothly without any issues. One thing is for sure: we are not going back to Trunk Based Development

Our CTO Allan has written an article about the problems with Trunk Based Development and how Koristu is designed to fix them. The article also includes a video of a talk he gave on his innovative solution to Trunk Based Development, which explains everything in more detail.

Inventor answered 30/6, 2017 at 8:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.