The author doesn’t really seem to go into details about what goes wrong with feature branches, though. And how to practically deal with merge conflicts, WIP checkins and such. Too bad, because it sounds kind of interesting.
It sounds, from one throw-away line in the middle, as if his problem is not feature branches, it’s long-lived branches. This is important because if there’s one thing we learned from Loki it’s that the longer a branch exists the more it will diverge. There’s a non-trivial cost to maintaining two different versions of a program and that cost comes from the divergence. If every developer has to keep handling conflicts with their branch then that’s time that they’re not spending improving the quality of code. Ideally you want people to be constantly pulling changes out of their branches that they can merge and have only things in their branches that are in a broken state (even unfinished features can be merged, gated behind a CI-only flag, tested to prevent regressions but not accidentally shipped in a release).
Weirdly he seems to ignore the existence of pre-merge CI. One of the most valuable features of git is the ability to trivially run CI on a tree that is in the state it would be after merging a branch, by simply merging the branch and not pushing to the canonical repo. In a well-designed CI system with fast incremental builds, you can make the CI system responsible for pushing to the main branch: first it runs a build and sanity checks, then the code is reviewed, then CI does a second run on the final version and pushes the changes to the main branch if everything passes. Now the main branch is never in a broken state (for some definition of broken).
From the linked PDF it seems he’s also arguing that instead of doing code review, people should be pair programming. I agree pair programming is a good idea, but I also think it’s not a substitute for an independent reviewer. While pair programming, you tend to be closely following eachother’s thought patterns, so I think it’s likely you’ll both have the possibility to fall into the same conceptual mistake/trap. Also, a merge request leaves a trace so you can later re-read the comments and feedback people made. With the “pair-programming and committing straight to trunk” approach you create silos of knowledge (OTOH, it’s pretty rare for more than one person to perform a code review).
On the other hand, with pair programming you don’t get the result where someone just rubber-stamps a commit because it’s too large to grok.
But then, in the PDF he mentions that people shouldn’t be making such large features in the first place. Nice in theory, but in practice, a seemingly trivial change might require sweeping changes because it infects other parts of the code to make certain information available there.
I dunno, the whole idea seems ill thought-out and a bit arrogant as in “I know better than everyone else’s lived experience”. At least, I have experienced working on a single trunk in svn before and I consider the code-reviewable patch set (merge request, if you will) a nice improvement over the past way of working. Especially in distributed teams, and now with the pandemic it shows how useful this is even if you’re not that distributed.
So this seems to boil down to “Trunk-based is better (if you’ve already fixed all the underlying issues that make feature branches problematic in the first place.)”
But then if you’ve already fixed those problems, why work against the common practice and tools at all?
Trunk based development works if
If you need to support different versions of your software, feature branches are very useful.
For 1, I would solve with feature flags, but 2 is a legitimate concern I think.
Different versions with feature branches sounds much like long lived branches, which I would avoid and again solve with feature flags.
[Comment from banned user removed]
Are you using feature/os flags?