Everyone has heard the advice to integrate early and integrate often. It isn’t rocket science. If you hadn’t heard that before, you have now and there’s simply no excuse. People may argue against this point claiming integrations are a pain, but that’s a chicken and egg scenario. Integrations certainly are a pain when not done often enough. The idea is to reduce the drift such that you are dealing with smaller, easily identifiable changes. (This piece of advice brought to you by The Pragmatic Programmer.)
I’ve been on all types of branching layouts and integration schedules. My first school project we did not utilize branching and it was actually amazingly easy. It was a treat. Except for that one time when someone threw a wrench into the build, it was broken, and there were a mass of files in a bad state. That sucked. That sucked a lot because I had a lot of dependencies I was waiting to get and was effectively out of the coding game for a day. (Side note: Thank goodness I had plenty of work to do outside of programming.) That’s why we have branching and that’s why a single branch simply would not scale past our small, six-person team. However, it was great when things were going smoothly because there were rarely merge conflicts to resolve.
Fast forward to another project where we had branches for each major feature. It was nice for a while. We’d take our integration from master and it was almost always just accepting the source because we did not change similar files. Those are the kinds of dreamy integrations I love. We integrated once every week or week and a half and never had many problems. That is, until the day came when there were a massive amount of changes to a shared file on both sides. Changes that had been building up for a few weeks. It was a very bad time to decide to cleanup that file because of a mismatch of brace styles and poor naming conventions (one letter variables belong nowhere) “while I was working there anyways.” I made some meaningful changes and so did the person who integrated to master, so the integration was much more complex than needed. If he had grabbed the file incrementally, and I had gotten his changes before fully going to town, we both would have been resolving much smaller amounts of conflicting changes. Lesson learned.
Let me give another, final example. I call it the ripple effect. I was on a project that integrated approximately once a month. At least, they tried to integrate once a month. More often than not someone would integrate to the mainline. The next person would go to integrate from master and have so many conflicts, they would spend a week fixing the bugs and bad merges. Then they’d integrate to master. Then Johnny Thirdguy would grab from master and be even more screwed, and he’d spend a week on top of that. You can see where I’m going with this. We now have a whirlpool during adult swim. The adults don’t want waves, they want to be able to swim smooth, continuous laps. Let us swim laps, damn it!
So how do you do your part?
Usually integrations are a two-way road. Your team working in a branch off of the mainline and a few other teams in their branches. Take integrations to your branch as often as possible. You could very well end up spending only five or ten minutes at a time rather than hours during the integration and then a week resolving the bugs. (Maybe you could integrate every night! As I mentioned before, you could automate that.) Side benefit: You get other teams’ bug fixes and it should reduce duplicated effort.
Another thing to keep in mind, is how much and how often you integrate out of your branch. Do you really need to wait until your feature is 100% done before unleashing a fifty file change upon the world? Perhaps you first changed the interface for some system and could integrate that change out. This would prevent you from having to fix any new calls to the interface that get created in that window and allows other people to take that smaller change before getting your massive refactor. You can also try throwing your feature outward incrementally if it simply isn’t expected to be final. Do you need all classes of enemies to work immediately? Will your co-workers be up-in-arms if only the weak, brainless AI enemy is in the main branch for a few days or a week?
Finally, perhaps you can create a better branching structure. If every single developer is isolated in their own branch for weeks, you’re just asking for some painful merges. Especially if a lot of them are working on the same files. Maybe you don’t need three branches when all people will be working on the jumping system. If you’re stuck on branches, perhaps there can be a sub-branch that the three of you integrate amongst yourselves before being able to push something working (or at least something that doesn’t break the build and create all kinds of bugs.)
I don’t know, those are just my thoughts on the subject. I feel you should integrate as often as possible. It behooves you. Leave a comment if you have any other cool advice, tips, tricks, or thoughts of your own! I’d love to hear it.
See you, Space Cowboy.