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:
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)?
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?
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?
Thanks :-)
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.
- 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).
- 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).
- 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.
- Overall, which benefits can carry the trunk-based compared to the feature-based workflow?
The greatest benefits I have seen are:
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).