Paul Hammant's Blog: The Cost of Unmerge
One of the reasons you’re going to choose a Trunk-Based Development (TBD) model, is because you’re doing concurrent development of consecutive releases. Maybe that’s not even your choice as a development team, but the people funding the development work already have a series of big releases planned, and even eighteen months out, they have a clear idea of the order of releases and are planning the marketing campaigns around them, and it’s pretty clear that you can’t delay the start of the each project because of the amount of work needed.
What if the unthinkable happens? Specifically the order of releases is changed or a releases is cancelled, after usability testing shows it as popular be popular with end-users as dirt frosting on a donut.
I think we all know the solution I’ll propose, but lets drill into the problem is we were using non-trunk branching models.
Cascading branches.
Remember: Your development teams are all working concurrently.
In this model the release 1.0 project team has it easiest. They just work towards their completion. Periodically though the release 1.1 project team take merges (everything, not just cherry-picks). Mostly likely a dev-pair will work for between half a day to a couple of days to run through all the merge conflict resolutions. This is especially true if the changes were happening to the same parts of a web page, or the same classes. It’s also true if the team has been authorized to do refactorings as they go. If the ‘hit’ is taken weekly it’ll be longer, whereas daily merges from ‘upstream’ might be easier. Then again if the 1.0 team is 30 people, and the 1.1 is 20 people, then there is a likelihood that somebody in the 1.1 team is permanently arbitrating over merge activities. At least, that’s true for high-throughput teams.
Release 1.1 being cancelled, or being re-sequenced after what would have been release 1.2, is pretty much a nuclear option. Specifically is it pertains to part finished projects and merges you wish you’d not made. If either of those happens you’re going to have some down-time for development while many dozens of people are involved in work to neutralize (temporarily or permanently) work that’s been merged to 1.2 (and/or 1.3), then start merging that ‘neutralization’ again. This is the “unmerge” that is costly of the article title. The internal customer paying for the dev work, wonders why from their point of view, dev work essentially stops for a week or a month, yet salaries are still being paid.
It need not be a whole release that is scrapped or resequenced, it could be just some aspects of it.
Classic ClearCase Branching
ClearCase has a classic branching style, which counts a main-line branch as a pristine representation of previous released work, but actual development work-streams happen on a branch that is named for a particular release. As well as developer commits, actual releases happen from that release branch. Because both are happening on the same branch, a code freeze incrementally kicks in to protect the release from mistakes. After the release, everything is merged back to the mainline. Of course defects happen, so the release branch stays alive longer than is intended, and more merges happen after successive releases from there.
Meanwhile, perhaps slightly in advance of the incremental code-freeze, a new release branch is cut, and preparatory work happens there towards that later release. After the release from the former branch, and the merge down to mainline, there will be a consequential merge out from mainline to the new release branch, bringing them up to date. These merges are “all” rather than cherry picks, and are not cheap.
The problem is when you’re canceling or delaying some components of the release. You’re going to have to devote some resources to commenting out code, or wrapping it around conditionals tied to a feature-toggle, when you’d not previously intended that. The latter is better of course. Following that there’s a larger testing schedule and to ensure you got them all. Again, that essentially costly unmerge.
The correct solution
The right thing to do is Trunk-Based Development together with Branch by Abstraction, and Feature Toggles.
When you have multiple teams working in one code-line, and they’re toggling everything because their code is going out long before marketing are ready to trumpet the arrival of the associated features, then there’s no cost of unmerge. The only cost is setting up another Jenkins (substitute your choice of CI server) pipeline for a permutation of toggles that you’ve not previously tested. Maybe there’s some small work after that to iron out the kinks.
This actually happened to a client of mine. We’d advocated for a shift to trunk based development for many months, and won it because of the huge pain or merging changes from a upstream branch (high throughput team), and Subversion was actually breaking in a particular scenario, and we were struggling to find support for it. Start a merge, abandon after two days, start over and abandon again after two days gets you to revaluate your branching strategy quite seriously.
Source-Control tool trends.
These numbers, from Indeed.com, are gameable by those with vested interest, but let’s assume nobody would go to that huge effort:
Subversion, Git and TFS overtook ClearCase in ‘09 to ‘12. ClearCase slowly trends downwards. Thank goodness for that I say. I’ll be pleased when IBM/Rational eventually pull the plug on it. Rational now have “Rational Team Concert” (RTC), which I have not shown. It is at the same level of interest as StarTeam (the black line at the bottom). StarTeam should also go the way of the dodo in my opinion. Mercurial is as good as Git really, but has been wrong-footed by the rise of Git and Github. Even Microsoft realized that Git is unstoppable when it endorsed it in their TFS ecosystem. Perforce chugs along as the darling of Google, Apple, and multi-platform games companies. TFS and Subversion spent a lot of time matching the feature-set and mode of operation of Perforce of course. Subversion has peaked, obviously, but still remains the gorilla in the room. I think Mercurial and Subversion should merge, as Selenium and WebDriver did, and Struts2 and WebWork2 and Rails3 & Merb did.
Mar 21, 2013: This article was syndicated by DZone