Simply put, Maintained Divergence is where you have two branches that have a common origin, and while merges may happen in either direction, there are differences that remain over time.
Here, Y was branches from X. Work is merged over time in either direction (could be enhancements, could be bug fixes). Not shown is work that’s deliberately not merged. For a whole commit that is deliberately not mergeable, you could use the source-control tool’s mechanism to not merge it, but mark it as merged. For Subversion that is ‘—record-only’, Git ‘strategy-ours’, and Perforce ‘accept yours’. We’ll call that record-only going forward as Svn is the defacto-standard source-control tool. Once you’ve done record-only in both directions and no other commits have happened, then the next general merge (without record-only), will say there’s nothing to merge, even though you know the two branches are different. That difference is the maintained divergence aspect, that does not rely on cherry-picks.
Having one branch for both (say trunk based development), and have a build that can adapt build both (X and Y) from the same source. The adaptability could be represented in #IFDEF style source directives (C, C++), or could me more pluggable around abstractions if the languages in question support that. There’s a degree of sophistication to this, that many would argue is not worth the effort. The Agile community is nearly always going to say this is better.
Apple’s iOS and Mac
One of the reasons Apple were able to conclusively beat at least Microsoft’s hand-held operating systems in 2007 was that ARM chips had become beefy enough to run their desktop operating system. More or less that is. I hypothesize they made an experimental branch from OS X (Mac) to prove the point, keeping lots of commonality, dropping plenty (all apps for example), and diverging quickly to what is recognizable today. For the items that are desired in both code-lines, there may be divergence too. Either way, record-only merges would set you up, to subsequently be able to merge bug fixes either direction.
Both iOS and OS X have their own release schedules of course. That’s one of the characterizing aspects of this. Indeed, it could be that Apple will kill OS X after growing iOS to be all that you need (in their opinion). Perhaps they’d do this after allowing Mac end-users to install an iOS environment (sync’d) for a few releases:
Note – I don’t actually know how Apple use Perforce ‘inside’, or their branching strategy. Sadly, there is a bit of a news blackout from devs that join the Cupertino company.
Bigger Games Studios
A title may be concurrently developed for XBox 360 and Playstation3 by a single studio. There’s a huge amount of C++ source, but also a ton of differences between the two platforms. Having a branch for each allows for teams to run against their own release schedule, but benefit from merges where there is commonality.
Data instead of ‘source’
Let’s take a contrived example: US Hotel data, and we’ll change from branches of the same source-control repo, to forks on GitHub (amounts to the same thing):
The first “upstream” branch/fork, is just reduced hotel data. It presumably grows as part of some community effort, in the style of Freebase.
Then there’s the fork (a team concerned with determining whether the hotels have wifi, and whether that’s free): https://github.com/paul-hammant-fork/us_hotels_with_wifi and their view of the same file.
There’s two differences:
- a correction to the number of stars a hotel has
- the addition of the fact that wifi is free for Hilton-Honors members with status.
In fact, #1 came after #2 in terms of commits. In this case you’re want to consume the stars correction back to the upstream master, but leave the wifi details divergent as it does not constitute the “reduced” aims of the upstream master. GitHub has “pull requests” where the wifi team could donate changes back to the reduced-hotel-data team, but it does not allow for cherry picking of individual requests, in order to maintain divergence.
Here’s the diffs all together -
I previous blogged about semantic merge amongst other things.
The Plastic SCM team is working on such a thing, not just for their source-control tool, but to have command-line inteop with others. I’ve not used it yet, but look forward to trying it out. It’s relevant to this space I think.