Branchless development
tedunangst.com
tedunangst.com
The pertinent question is how often you merge. On one end of the scale you merge on every keystroke. Every time Joe types a character it gets put into Anna's files. Clearly this doesn't work. On the other end of the scale every developer works on their own copy, and all the work gets merged just before a release. Clearly this doesn't work either. There is a scale from maximal disruption minimal effort merging to minimal disruption maximal effort merging. You want to find a point on that scale that minimizes the total amount of work.
Feature toggles remove this problem by keeping everyone in trunk/master. You can then have CI builds with whatever set of toggles you want.
Throw hardware at it.
Switches are temporary, with time their number will settle.
There was an advantage: if a bug popped up you possibly had a workaround immediately for the customer. Downside is you had no idea if that workaround would expose more bugs.
Toggling also only makes sense for the cases where you don't change the structure of your data. So be careful, and make sure you have a plan if you decide to do it.
If you're a fan of this workflow then I can recommend using Visual Source Safe. It even has exclusive locks which completely eliminate merge conflicts.
I've been building software professionally for almost 20 years, I've seen (and experimented) with almost every VCS/SCM strategy imaginable.
My conclusions:
This only really works for tiny teams - 2-3 people who work very well together. It needs high bandwidth communication.
For teams of 3-10 short lived feature branches are effective with a little bit of planning to minimize merge conflicts.
For larger teams you really have to split the system into self-contained modules or microservices, each module having clear owner. These modules are then shared as source, library or service depending on the actual needs.
I've never had good experiences with longly lived branches. They can work whilst adding experimental modules which require only a couple of tiny API changes to the main system; but then splitting the module into a separate project/repository and making the API changes (behind an #IFDEF) makes more sense.
it also matter average team skill. if you have to make do with what you find/can afford, then feature branches are good at isolating devs from each other non working commits.
I introduced Subversion. No more corrupt files (shiver), it just kept on running. And you could actually work on any file. If you divide your work properly, you can work in the same file without working in the same code. And if the small chance of changing the same line occurs, the merge wasn't that complex to fix.
We never looked back, and therefore I am completely disgusted that someone actually suggests using such an unstable, non-efficient tool.
Visual Source Safe is an absolute pig, unless you're already using it and can't switch then I strongly advise getting as far away as possible.
Team Foundation Server - the replacement - has historically been just as poor. It does however have the advantage of including some extremely powerful software lifecycle management features.
Recent developments - such as the Git-based Team Foundation Online - are really rather good, especially if you need more advanced features and like giving Microsoft money ;)
Git totally kills it, of course, but as traditional old-school VCS goes, it's not bad at all.
I assume those locks can be overwritten by an admin, right? I'm exactly the sort of forgetful jerk who'll lock an important config file before going on a two-week vacation.
Regarding VSS and exclusive locks. No. Trunk based development with no exclusive locks is fine. Pessimistic locking was unwarranted pessimism when applied to source control.
Also, note that Google is trunk based...with a single trunk across the whole company. I think Facebook is too?
Over the years I've lost so much time to small errors resolving merges - particularly the type which involved cross-file refactoring (where two people have moved methods and then refactored them).
The beauty of using branches - especially with Git - is that you as developer gain a lot of power over how you apply merges. The "pre" state is also under version control, so you can always go back. Plus if you're using Git then you're implicitly doing branch-based development (git clone creates a local branch).
My current team of 6 developers switched from TFS trunk-based to Git with short-lived feature branches and they've not looked back. We've greatly reduced merge issues and downtime caused by bad check-ins. Both still happen, only less than before.
Fundamentally merge conflicts are unavoidable.
The claim by the trunk based development crowd is that smaller, but more frequent merge conflicts produce fewer mistakes. Trunk based development leads to smaller merges because you do them more frequently. That's about it.
We recently switched to short-lived feature branches (short-lived as in a couple of days maximum), and I haven't had to resolve merge conflicts in months. Our feature branches previously used to last around two weeks and merging things in was collectively not looked forward to. Now I don't even have to give it a second thought.
tl;dr not having merge conflicts is an entirely possible happy reality.
Yep!
http://paulhammant.com/2013/04/05/what-is-trunk-based-develo...
Merging complex changesets across branches is impossible to do 100% correct every time. Not unless you're a 10 feat tall code crunching robot.
To me, the ability to have logical separation of the features being built and do meaningful code reviews far outweighs any proposed speed benefits of not branching, benefits that I assume show up only in larger groups as they certainly don't show up in small groups. Which bring me to my last point, the "slow is fast" section, which doesn't provide any evidence that slow is fast. Other than users not having to decide which branch to run (which takes all of two seconds, BTW), development is much faster with feature branches and the other negatives do not show up in my experience. What I'm trying to say is that "fast is fast." Slow is not fast and the author doesn't make his point there either.
tl;dr: All in all, he points to no actual pros to branch-less development.
Give it a few years and everybody will use feature switching, except the old man enterprise dev :)
There are a million things that feature switching let's you do. Enable and disable instantly, enable for .00001% of the users, integration test different combinations, etc.
https://secure.phabricator.com/book/phabflavor/article/recom...
I would say feature branches were mainstream usage of CVS too, but SVN made it more popular because merging is more effortless.
Github probably popularized it, because they put a web interface on it (which is great), but that can be said for a lot of things.
I've seen those things and what you end up with is a dev team in tears because some chump has fluffed the source tree, the integration build is still running so no one else knows and checks out the trunk followed by boom and 2 days of paralysis while everyone works all their changes back into it for a checkpoint build.
All mature products tend to evolve into this state unfortunately.
Ergo, that works on small things but doesn't scale. Minimally, using feature branches and integrating them in turn is the only situation that works on those sorts of products.
I'm not entirely convinced either, but the argument isn't without success stories.
To name just a few:
* Palantir by A. Sarma et al. [1]
* Crystal by Y. Brun [2]
* CloudStudio (project I worked on); Video demo: https://youtu.be/R3Fz0Tcdz0Y
To the best of my knowledge, however, none of these projects have found any widespread adaption. A lot of it also has to do - I think - with culture and personal preference.
[1] https://scholar.google.de/citations?user=shMjCasAAAAJ
[2] http://homes.cs.washington.edu/~mernst/pubs/vc-conflicts-fse...
Hint: it's more than 2, more than 3, and more than 50.
http://paulhammant.com/2014/01/08/googles-vs-facebooks-trunk...
Having an autobuild system to build every checkin is a big plus.
I worked on a chip once where we decided to make everything a branch, at one horrible point we didn't have a mainline, we didn't know what we were building, we had to put people on full time merging trying to figure out what to test.
In order for this workflow to be reasonable for any development team of a size greater than about 3, each commit would need to move all the code in to a working state. While a reasonable pattern in theory (Don't TRY commit breaking changes!), it is frequently useful to track code in an intermediate state. Sometimes (read frequently), this code may not be representative of the final state of the technology or may not even work as it should. Not maintaining individual branches means that these changes are exposed to the entire team and can be very very messy.
All in all, what a silly approach to revision control. Take advantage of the latest patterns and a system that provides the loosest coupling and highest distribution. If we do as the author advocates, we might as well all just switch back to CVS...
> merge conflicts are preferable to changes that overwrite other changes
Nobody is saying that. The difference is really merging as you go vs doing one big merge at the end. I personally fall on the side that it's far easier to merge as you go.
Master is typically periodically pulled into the feature branch to ensure you're working against the most current version of the codebase.
EDIT: Yes, this can create an ugly revision history, but that's what rebasing is for, right?
It sounds crazy now that I write it down, but it really keeps our commits clean.
Pros or cons of each aside, advocates of feature branch based development should recognize that they are merging less often than they would if they were doing trunk based development.
Checking in code to the VCS that makes the tree NOT build will get you screamed at (at least within the OpenBSD project). This requires proper planning for big changes, and to break them down into small, easy to review, patches.
OpenBSD uses CVS as main repo because it fits their development style. Bevore you knock down CVS look at AnonCVS and cvsync. http://www.openbsd.org/papers/asiabsdcon2009-release_enginee...
An open source project with highly motivated and capable developers and a benevolent dictator in charge functions differently from other projects and organisations. A process needs to be attuned to the people, and the relations between those involved, involved.
Diverge and merge at the end is quite utopist on complex projects.
Of course, this would be even more useful if it only alarms the users whenever they have created a merge conflict.
I've seen branch-and-review used in anger. It can easily go bad: it drastically multiplies the inventory of work-in-progress. Everyone becomes blocked on someone else, moves on to another task, then loses context on the previous task or tasks. Stories with soft dependencies wind up sprinkled across several branches, making user testing a bit of a merge-and-pray event.
It sounds great. Reviews! But efficient!
And it turns out to be a tangle of interlocked gears.
I imagine somebody has made it work. I have not seen such a case.
My personal preference is a single development branch^, test-driven, pair programming, with rebase and integration test before pushing.
[^] If it's a private project, this is master. On github, the master branch can't be used as a true master, because it is a de facto release branch.
Formal meetings with scribes and reviewers and procedures and checklists are not the same as "here, check out this patch and merge it if you like it".
I haven't kept up with research and I don't know if anyone has shown that TDD + pair programming is a reasonable substitute for full-blown code reviews in terms of bug yield.
Now that I think of it, what I saw was an inversion of the classic CVS commit-bit model. CVS-based opensource projects typically have a praetorian guard who review everything before it gets committed.
What I've generally seen is the reverse: soliciting opinions from other teams with little context or familiarity with the original codebase. So they take days or weeks to respond and when they do, it's quite cursory.
I bought into feature branches and all that stuff right after uni and tried to apply it at my first job without all the success I was expecting. Then when I moved to my current job in which we do TDD, Pair programming and single branch development I was a bit reluctant. After almost 2 years I haven't come up with a single scenario in which this approach has given us any troubles and in hindsight I think is what I should have proposed at my first job.
That said, I'm anchoring a project where my predecessors chose a feature-branch model. I have a motto that "sometimes it's better to be consistent than correct". Done properly, it's not too hard, but in practice that's because we don't have a large team and we still rebase on and merge back to master frequently.
When in Rome do as the Romans.
I think consistency is a best practice with precedence over all the other ones. Having a team agreeing on something and being happy with it is sometimes far more important than that something being the best of the possible choices.
The perfect is the enemy of the good.
It's unethical for me to put my own standard of perfection ahead of delivering business value and soundly engineered software.
My peers have opinions, formed validly, from their experiences. I have my own. Sometimes they differ. Sometimes I just need to suck that up and get on with the job.