8 ms·
I prefer trunk-based development
- flohofwoe 3y agoI'm fine with both, I've seen both trunk-based (with SVN) and branch-based (with Git) models work. Due to git's 'multiple histories' it's quickly becoming a mess when many people are on the same branch, that's why I prefer to use a branch-model in git where only one person is on a short-lived branch, and a team uses PRs/MRs into a common target branch to create a clean, shared, linear history. This target branch doesn't have to be the main branch, but can itself be a (bigger) feature branch which then is eventually merged into the main branch (key is to not diverge too much from the main branch though, so that merging back doesn't become a hassle).
- barrkel 3y agoSubversion sucked for a lot of reasons. It had no good integration with code review (though there are some tools that can do it now). It didn't have a good way of doing a three-way merge, necessary for rebasing a change or porting it across branches (e.g. release branches for shrinkwrap patch updates, which was the style at the time), without additional tooling. I wouldn't model how trunk-based development works based on experience with SVN.
- flohofwoe 3y agoTortoiseSVN+WinDiff took a lot of pain out of SVN merging, but in general with the trunk-based approach you'd usually only create 'dead-end' branches off the trunk which would not be merged back (for instance one maintenance branch per feature release to enable further patch-releases without holding up work on the next feature release already happening on trunk), in this case, only bugfixes would be cherry-picked in either direction (e.g. the most important rule for SVN was: avoid complex merge scenarios in the first place).
- jeffbee 3y agoThese discussions, including the comments on the OP, are always poisoned by people who can’t imagine any other VCS than git.
- detaro 3y agoI don't see that in the comments. (and whould argue it's an orthogonal point anyways, many VCS, including git, can easily accommodate different development styles)
- theshrike79 3y agoThe problem is that picking a VCS is rarely something you get to do. There are specific version control systems that do some things better than git, but have huge downsides for other things. If your company is focused on a specific thing (graphics or 3D modelling), there are options. But usually "everyone" knows git well enough not to need hand-holding and that's what companies go with.
- horsawlarway 3y agoI can imagine different systems just fine. Hell - I used several before git (svn, sourcesafe, and something with an M at the start of the name that I think I've repressed so hard I can no longer recall). My desire to continue using git has nothing to do with my inability to imagine a different system. It comes directly from having actually used those other systems. I've done trunk development, I've dealt with file locks (and having to hunt down the fucking admin to unlock the file that one coworker locked before taking off on vacation). I've seen the pain there. If anything, the vast majority of negative experiences with version control in my career came out of the first 5 years of it, before git took off everywhere. After that, the worst experiences are from the folks who absolutely refused to even try to learn git, and just bury their head in the sand of whatever tool they were using. I don't really even like git, but unlike those other monstrosities... I can tolerate it. Is it "the best VCS"? Eh - probably not. It's fairly old, the concepts have trickled out to other systems, the cli tooling is obtuse, etc. But it's solid, widely used, and has none of the serious pain points those other tools caused.
- jcarrano 3y ago
- alkonaut 3y ago> when we say CI, what CI really meant was actually integrate your code regularly. Code living on separate branches is, by definition, not integrated. When I work on a long lived (say, a week or two) branch, I just rebase it on main every morning or some times several times per day. It always contains 100% of everyone elses code. But their code contains 0% of my commits yet. Because that's the point of the branch. That none of it is visible to anyone else, until I deem it ready to. The point is that when I merge it, it looks like an atomic change on main, which takes it from one working state (100% passing tests and so on) to another working state. And the only way to ensure that is to make the validation take place IN my branch. If I'm eager to "publish" my work, I can do that. I can make multiple branches with just one or two commits each on monday and tuesday with new functionality behind some feature flag. And then the final friday commit is basically just flipping the feature flag. But it doesn't change the fact that I do want to make sure main stays healthy so I still want to gate the commits. I don't think there is a pattern of development that works everywhere, and whether one thinks that feature branches is an overhead I think will vary. People who are used to a project taking 3 months and having multiple builds per day, perhaps having their tests run in seconds via a commit hook, will think that the overhead of a PR is massive. But if validation builds/tests take multiple hours anyway then the overhead of making branches isn't really going to have an impact on productivity.
- BiteCode_dev 3y agoYou can do that with squash-merge.
- mattpallissard 3y agoBut with squash you lose all of the individual commits.
- BiteCode_dev 3y agoThat's a pros, not a con. Once something is merged, intermediary steps to get that new thing are no longer interesting. In fact, most rebase workflows squash anyway. In the rare case you have 3 steps in that PR of 23 commits you want to keep, squash it in 3 pieces and merge them.
- peschu 3y agoWikipedia link does not work I see a lot of claims in your article without any examples etc. to prove these claims. It's hard for me to distinguish what is factual and what is "only" evangelism ... Additionally it's probably a lack of knowledge on my side, since I only worked with git. So examples would be very helpful to make this topic more accessable.
- onion2k 3y agothe longer we leave it to commit our changes, the higher the chances our commit will clash with someone else's changes The further you let your branch deviate from the trunk the worse it gets, sure, but you can alleviate that problem pretty much entirely by regularly merging develop into your feature branch. When it's time to merge your feature into develop there aren't many conflicts because you've already got all the changes in your branch. Trunk based dev is still better in my opinion, mostly because it forces people to check their work properly, to write robust tests, or else they risk breaking the build. If you work on a team with people who aren't particularly careful then it's not worth the hassle though.
- barrkel 3y agoThis, of course, isn't the only kind of conflict you can have. The delta on a feature branch will almost invariably be larger than the delta on a commit to trunk, and if everybody is merging feature branches, even if they are continuously rebased or merged with the trunk, they spend less time being tested in the final merged state and the risk of unexpected feature interactions (not textual conflicts in code) is higher. Trunk based development is better because it forces smaller commits. Everything else flows from that. Smaller commits are easier to test, and have less risk of breaking stuff. Smaller commits are easier to roll back if they break stuff (fewer "unmerge" conflicts, i.e conflicts when you merge the inverse of the patch). Smaller commits force you to develop a better approach to schema and data migrations. Smaller commits force you to add support for feature flags, because a whole feature can't be implemented in a single easily reviewable commit, and now you have tech you can leverage for canaries and so on.
- tsimionescu 3y agoThe reality of software development is that any project beyond a handful of devs requires branching. This branching can be achieved in at least two ultimately equivalent ways: - literal branches in your VCS of choice (or forks, clones, etc) - literal runtime branches, via IF on feature flags When a feature is ready to merge to prime time, the branches have to be merged, and unexpected interaction with other features can now be found. This is exactly as likely to happen when doing a git merge as when setting a feature flag to true. Different features working in isolation but interacting badly is a fundamental aspect of software and not some incidental self-caused problem that can be prevented by a better development methodology. To take a somewhat silly example - if one team is working on a feature to make error messages more readable and another team is working on a feature to make error messages opaque IDs looked up in a manual, these two features will obviously clash when they go live regardless of whether they were each behind a feature flag or on separate git branches. Hopefully few organizations would schedule such an obvious conflict of features, but more subtle versions happen all the time.
- Aaargh20318 3y agoThe biggest advantage I see of branch based development is that you land a single fix/feature with one merge commit. This makes it relatively easy to revert a change if necessary as it's more or less an atomic change.
- barrkel 3y agoThat's actually an advantage of trunk-based development. Instead of needing to roll back a whole feature, you just roll back the commit which broke stuff. This derisks big feature branches. It also forces the use or development of more incremental approaches to schema migration, feature flags and so on, which also reduce risk, and enable things like canary releases, A/B testing and so on.
- tremon 3y agoyou just roll back the commit which broke stuff You are conflating branch-based development with commit squashing. It is perfectly possible to revert a single commit even if it was developed on a separate branch and then merged.
- Aaargh20318 3y ago> . Instead of needing to roll back a whole feature, you just roll back the commit which broke stuff. What if it's the whole feature that broke stuff? What if we decide just before release that based on our release tests this particular feature isn't ready for production yet? Do you expect me to hunt through the entire commit log and identify and revert every single commit related to the feature?
- barrkel 3y agoNo, flip the feature flag. You have a feature flag because there's multiple commits for the feature and it can't be enabled until it's complete. And since you're continuously deploying, even if you did have to look for a commit, it wouldn't be more than a day or two old. Of course you wouldn't enable the feature all at once if at all possible. You'd do a canary first, sending a proportion of traffic. And your production system alerting would notice an elevated error rate on the canary and drain traffic to it, so you're not up in the middle of the night searching for a flag to flip or commit to roll back, at least not very often.
- cynicalsecurity 3y ago[flagged]
- post-it 3y agoI think it can work for some teams and some products.
- robertlagrant 3y agoI think this sort of statement sounds good and confident in meetings, but, with no supporting evidence, isn't very persuasive.
- kdmccormick 3y agoI think the article paints a false dichotomy. DVCSs and trunk-oriented development are fully compatible. I work on an open-source project using git that has both a main branch that's continuously-deployed, and stable branches for twice-yearly community releases. We treat the main as a trunk: everyone makes small PRs to it and they're generally deployed day-of, if not within a couple of hours. If anyone's PR is too big, they're generally asked to split it up for incremental review+merge into main. PRs are generally rebased onto to main and tested via CI regularly, including right before merge. So, we enjoy all the "trunk-based" development benefits that the article describes. I get the impression that this workflow is common in the industry, especially for GitHub users. That said, the branching features of git are still essential for us for creating, testing, and patching those stable community release branches. That's not to mention the offline development quality-of-life features that DVCSs give us. I couldn't imagine not using a DVCS!
- chippiewill 3y ago> everyone makes small PRs to it I don't think that's the trunk based development that they're advocating for. I believe the version they're advocating for is where all developers commit and push changes directly to the main branch.
- goodoldneon 3y agoHow would code review work if everyone is committing and pushing? The article must mean tiny, short-lived branches
- kdmccormick 3y ago"Pair programming", maybe? Anyway, agreed. Particularly, I wonder how any significant refactoring is approached.
- jdlshore 3y agoRefactoring is easier with short-lived (minutes to a few hours) branches, because refactoring causes branches to diverge over time. Significant refactoring, done correctly, is a series of small refactorings, and they can be integrated every 30-60 min to minimize impact of changes.
- a1o 3y agoI surely don't miss locked files and having to have projects with gazillion files that reflect team structure instead of what is the best logical way to solve problem X.
- eterm 3y agoIn a DVCS like git, an important realisation is that commits are branches. Both a "regular" commit and a commit to a branch are just nodes on a DAG.
- stcroixx 3y agoIt’s statements like this among other that fuel git hate. Maybe this is true, I don’t know, but if it is, that’s terrible. To most working programmers these are not the same thing.
- eterm 3y agoCould you expand what you find hateful about that?
- dboreham 3y agoSome people hate tools that lack conceptual integrity.
- veddan 3y agoIn git a branch is a name that points to a commit. When you commit to a branch, you create a new commit and then update the branch to point to the new commit.
- tremon 3y agoIndeed. Which also invalidates the OP's claim that started this thread. No, commits are not branches: they lack a (repointable) name.
- eterm 3y agoThey don't, because they have a name (that also happens to be a hash). They lack a convenient name. You can go to any commit and "turn it into" a branch if you so wish by "promoting" it to a branch. My point is that there's no such thing as "avoiding branches" in git. Or least, you can't avoid the "downsides" of branches as some perceive it. Those issues are still present with commits, just without the convenience of good naming. That is to say, and I should have made it more clear in my initial comment, that trying to avoid branches is pointless and indeed counterproductive. You still logically have branches, without the convenience.
- barrkel 3y agoPeople ought not express an opinion on this unless they've tried both professionally. Git doesn't have great support for trunk-based development. Gerrit tries to paper over the gaps, but the git client isn't great. git-branchless or another plugin is needed for better support.
- civilized 3y agoSome people use long-lived branches in essentially the same way as short-lived branches function in TBD. Multiple sibling comments talk about merging in commits from main into their long-lived dev or QA branch multiple times a day, but this seems not really that different from just briefly branching from main when you need to do some work.
- DeathArrow 3y ago>I prefer trunk-based development I am devoted to fridge based development. Whenever I have something harder to solve, I open the fridge and eat something. That seems to help my thought process.
- jitl 3y agoThis article fails for me because it doesn’t clearly define the two sides: what constitutes “trunk” vs “branch”? The two sides in this argument are always fighting their own straw man of the other side. I’ve heard teams using Phabricator for “trunk based development” say they are reviewing commits not branches. If you’re doing any code review or CI before code lands on trunk, I’ve got a hard time seeing the difference between that and a “branch”. Even in a CVS like SVN, your local code changes are still a “branch” that diverged from trunk until you commit it up to the server. And if you go 1-2 weeks without committing to trunk that’s just the same to others as going 1-2 weeks making hourly local git commits to a local branch… And if I make a local git branch, commit 100 times to it over 6 hours, and then squash those local commits and push a single change to trunk, is that any different from trunk development? At $JOB we use GitHub, try to make small Pull Requests that are usually merged within 24 hours of PR open, and those PRs tend to receive commits for between 6 hours and 4 days before we try to merge them into `main`. But you’re free to make as many commits as you want to your branch. We squash it down to a single commit rebased on main. Main is the only branch that lives indefinitely. Is that “branch” or “trunk” development? I think it’s “trunk” but maybe the author would differ.
- DeathArrow 3y ago>In trunk-based development, the entire team works on a single branch. This model allows for quicker integrations and fewer merge conflicts. I rather resolve merge conflicts than fix bugs.
- jrochkind1 3y agoThis really means every commit goes to the main branch... and if on a dvcs like git, gets immediately pushed too? One thing that occurs to me is that probably requires more intention and discipline into how your commits are divided up, what makes a commit? I guess you have to run tests and ensure green before committing, for one thing? But also I'd guess in general probably waiting to commit until it's a larger unit/feature than otherwise? But I'm guessing. I'm curious what people who use this method have to say about how they decide when to make a commit and what it should contain. And how that effects their experience. If I'm understanding correctly what is being described.
- amno 3y agoI don't think anything of this has with trunks or branches to do. I think all said arguments are equally valid for both types of CV systems. It really is a developers discipline that decides here. All this with CI, frequent merging etc are just as easy and possible with Git as well, especially since we got worktrees.
- andyish 3y agoIt takes a mature and disciplined team to use TBD and these teams are few and far between. Every developer you add to your team (or department) increases the risk that someone is going to miss a test, or an edge case and ultimately break the build and blocks everyone. For me short lived branches that get merged into main dependant on passing tests and maybe a PR is by far the easiest, most reliable, and most common approach. For many of the reasons listed, I do use TBD for my side projects. Push it to main, tested, built and deployed. Easy. :)
- yarekt 3y agoYes, this doesn't get talked about enough, however, I understand how discussion can get polarising: Some downsides of feature branches can be mitigated. Make CI do a merge before running tests, failing the test if there are conflicts. If you split your teams well, you may not need to ship work in big long running branches. Some of it also comes down to discipline. Objectively the continuous integration model wins in my opinion, but the feature branch thing we've ended up with seems to work well in many general cases. I think as with many programming related phenomena it seems to largely depends on human factors.
- jacknews 3y agoThe problem with CD is not so much that you might break production (though that's definitely an issue, even if you have comprehensive tests). The problem is that you're constantly disrupting users with new features, changes to existing ones, and usually resetting or invalidating any open sessions. I think CD is most useful to integrate into a 'staging' branch that is effectively the 'trunk' branch as far as developers are concerned. And that branch is them deployed to production on a schedule, say weekly, etc. Development should stil happen on feature branches though IMHO, just keep them small.
- robertlagrant 3y agoNot if you use feature toggles as well?
- jacknews 3y agoIt seems like a tall order if not impossible to put every potentially breaking change or fix behind a feature toggle, and even if were possible to map the effects of every change, why bother deploying code that has no effect? It's fair enough if you're going to switch on complete features for a subset of users, but if it's just to hide incomplete parts of a feature? The practice seem like all risk for no gain.
- williamdclt 3y agoIt's a pretty common use of toggles, really! It has many upsides: decoupling deployment of code from feature release (useful for many reasons eg giving PMs control over the feature release), gradual feature rollouts, fast feature rollbacks, breaking up big features over multiple small PRs (eg each implementing a different part of the logic/UI), deploying "risky" code knowing you can enable/disable it instantly... We use this extensively at work, and wouldn't go back. You call it "just hiding incomplete parts of a feature", but for us that was a huge improvement in workflow. The real downside is that these flags tend to outlive their purpose; they don't get cleaned up as soon as they should.
- 3y ago
- aaaronic 3y agoI just read this as an argument for tiny incremental changes and very short-lived branches. This can work well for a team that is very highly engaged and where Code Reviews get immediate attention. When I've worked for startups, I've seen this kind of usage out of git and it can be quite effective (no branches alive for more than a couple days + frequent rebasing in of upstream changes from main/master). Long-lived, all-encompassing feature branches are definitely an anti-pattern and they bit-rot unbelievably quickly, especially as team size grows. Some shops I've worked in still prefer them, though, because they demand zero dead code paths or half-baked features making it into the mainline (which are definitely their own risk of technical debt).
- _hao 3y agoHere's a nice article from the VSTS team at Microsoft on trunk-based development - https://devblogs.microsoft.com/devops/release-flow-how-we-do-branching-on-the-vsts-team/ https://devblogs.microsoft.com/devops/release-flow-how-we-do... This is basically what I do on all of my projects and have put this into place in a couple of companies that I have worked at. Haven't encountered any serious issues and it has offloaded some big problems related to the gitflow madness that preceded it.
- jcarrano 3y agoI don't think the author understand how one is supposed to use branches and DVCS. It also compares an "ideal" situation of "trunk-development" with the worst usage of branches. Those unfortunate enough to have worked with CVS/SVN on a single trunk know that the ideal just does not happen and that by 2023 we know what not to do with branches (and it is perfectly realistic to avoid such mistakes). > In the branching model, large and infrequent merges can introduce bugs that are hard to identify and resolve due to the sheer size of the changes. You are not supposed to have branches that diverge too much, and if you do, what's stopping you in a centralized VCS from doing the same? I.e. having a large local changes that you did not upload back to the server. It actually makes the problem worse. > In contrast, the branching model encourages developers to create separate branches for every feature, bug fix, or enhancement. It seems the author suggesting not only a reversion the centralized VCS days but also to do it with just a trunk branch, where either each commit is made to the trunk right away (so it must be right on the first try) or you pile uncommitted changes locally. Using a DVCS and committing to the local version of the `master` branch already counts as having a branched model, except more limited. > In a trunk-based model, continuous integration becomes more straightforward because your code is committed frequently to trunk, and that's the branch your CI environment is running the build and tests on. You can run CI and test in any branch you want, and you can rebase prior to running the tests. It is not a big deal.
- Justsignedup 3y agoI have worked in pre-git environments extensively, and I can say that I hated every minute of it. Branches are great. Pushing branches is great. People rebasing is a good thing. Committing as much as you need to is great, and lets me diff when I mess up. If I couldn't commit till I was "done" because we're all working off main, like I had to do in the past, oh man were there gonna be merge conflicts. I've had projects where we spent a week on merge conflicts alone. I have never, in 14 years of using DVCS had anything even remotely close to that.
- feoren 3y agoThe actual best process: talk to each other. Every other set of rules about how/when to branch/merge/PR/rebase feels like an attempt to get around having to just actually talk to each other and know what's going on. By all means, have those guidelines. But first and foremost: talk to each other.
- User23 3y agoThis just reads to me as “I prefer working with small teams with great communication.” Sure that’s lovely; but it doesn’t scale. Depending on your scenario you might not need to scale past a handful of devs. In that case pretty much any process can be made to work well, including a completely linear commit graph.
- pavon 3y ago> Trunk-based development encourages frequent commits, which leads to smaller and more manageable changes. I strongly disagree with this assertion. In my years of doing development with SVN/CVS the consistent pattern I would see is that developers didn't want to publish their work to trunk until they were certain it was good, and since with SVN you can't make local commits without publishing to trunk people delayed making commits until a feature was complete. In other words, all the work that would be done on a branch with git was instead done on the developer's local machine without any revision control (and often without backups). Good developers would frequently `svn update` as they worked to get smaller conflicts, but code was merged to trunk at the same frequency as it is today with git[1]. In git, the equivalent would be make a branch, then commit --amend each change, fetch and rebase frequently, and then merge the single "squashed" commit. [1] If anything code was merged less frequently because agile encourages smaller stories today but that is completely orthogonal to trunk vs branch based development.