Source control branches is always a good topic to argue about. if you read any of my previous topic (or just know me a little) you are aware that personably I think those to be a complete waste of time and effort. My personal experience (which is validated against places I consult in) is that most usages of branches are covering some inherent process problems that best be solved instead of hidden. but that’s not what I want to talk about.
what I do want to discuss is one of the main argument people raise for justifying their need to use source branches. and usually it goes like this:
yes we would love to work on one main trunk, we see the great value in that. However, not all programmer knows how to work their code without breaking the rest of the system. therefore we use branches to prevent the system from breaking during development of new features. and we integrate their work based on needs and stability.
Frankly I can relate to this. I can understand what is missing here. We need some good strategies for working on code without hurting system stability. so here are some options for you.
Invisible Coding
The first and most trivial technique is using build it (in the programming language) mechanism for disabling code. Yes something like the infamous #ifdef directive for C/C++ that exists in most (all) modren software languages. The main idea here is that all new additions to the code are marked as disabled until they are ready be activated and integrated into the main system.
For most this would seem as an ugly patching/hacking and most programmers has a a natural dislike of such an option. and probably with a good reason. After all if the code is not active what is the big difference than just using a separate branch? well not much, the only real benefit in this is that at least one side of the integration is always done. when you are working on a new feature and still work on the main trunk, even if your new code is disabled, it is always updated with other changes being done to the system. And since in most cases enabling/disabling the new parts is quote easy. With just a little care you can do parts of the second side of the integration in an ongoing fashion making the final integration easier, safer and faster.
Decoupling of New Code
The second strategy takes the “invisible code” approach one step further. the main idea here is to write the new code into the main system, but this code will be decoupled from the main code in such a way that it will be easy to prevent actual usage of the new code until it is ready. Its like building a new part beside the main system and only connecting it when it is good and ready. technically speaking it’s a little harder to achieve and sometime require a little bit of juggling and some getting used to thinking this way. On the upside this make sure that all new code is integrated into the system in such a way that only the final steps of the integration (making sure everything works) is left for the end. the back and forth tedious merging is done along the way. Also, from my experience most developers find this approach natural and tend to work like this anyway when adding new stuff. However, the down side, is that in many cases the harder part is to actually to the connecting of the new parts into the existing system. sometime you find that you missed some staff that invalidate part/most/all you work done in isolation. I usually advice people trying to go this way to start by first solving the connecting part. that is start by making the system integrate into a “dummy” new part making all the calls do nothing. and when that’s ready go over and fill in the missing parts.
Work Small
This is kind of a process work around. it has nothing to do with how to write code. The main idea is to always work on small features. so small that in fact they can be started and finished in a couple of days making the use of a branch just a big overhead with no actual need. If you can start and finish in a matter of days, you can just work on your local copy focusing the actual code changes in a very short, delivering everything at the end. Actually this is just like branching but since it is for such a short period of time integration will not be an issue and most likely merging will not be required.
actually this strategy has all sorts of benefit outside the technical domain so it is a recommended idea no matter what else you do, and if/when needed it can also be combined with other strategies
Test Automation
Well this is probably the one thing that will make your code work at all time. if you have a good suite of automated tests that does a decent job at covering your system, the rest just falls into place. You just work on the main trunk and make sure that everything continue to function by running the tests after each change and before delivering. If you broke anything the tests will let you know, and you can just find another way of doing this. Of course having such a suite is something that sadly most people are short on. and those that do have are usually already solved this problem a long time ago. but lets face it you do need test automation no matter how you work.
The Mikado Method (The Missing Link)
That’s one is new for me, while I have encountered this over a
year ago, only recently I managed to actually dive deep and read the book (an excellent one BTW, which can be downloaded
here (for now)).
and for me that was the missing piece in the puzzle, the main idea of the Mikado method is turning the problem upside down. you start by stating you goal, you find out what are the prerequisites for achieving you goal, you apply them to your system, see what breaks, find what’s need to be done to complete the prerequisites, writ it down in a graph and then
revert your system back. then we repeat the process for each derived prerequisite and continue to so until we find actual things that can be done without breaking the system. This is a very short and probably not so good description of the Mikado process. but the book does a great job at that so just go ahead and read the first two chapters to get you going.
The great thing about this method is that it uses the power of a source control system, in way that allow a programmer to chart his way until he maps all/most of the things to do in order to reach the Goal, and only then actual work on the code is started. This allow one to start working in small steps from the end to the start while keeping the system intact all the way. at the end this is just taking the “Work Small” strategy and applying it to the “technical” side, resulting in breaking down the work into small technical steps that can be safely taken. and the best part is that this is an actual technical technique that can be practiced and mastered.
This are the strategy I have used and will use and for me those things work. I’m sure most of the things stated here works well in combined together and the trick is to use the right tool for the task. would love to hear about more techniques for handling the same situation.