This site will look much better in a browser that supports web standards, but is accessible to any browser or Internet device.
This is another post in my intermittent series of Best Practices Gone Bad (BPGB)
Today, we are going to take another side-step into version control. Most development groups use version control of some form. Whether you prefer Subversion, Git, Mercurial, Bazaar, Clear Case, or any of the many others, version control is an important technique for keeping your changes under control. This is especially true if you are maintaining multiple releases concurrently or have more than a couple developers on your team.
Back in BPGB: Feature Branch Fail, we covered what happens when branches live for too long. When you need to merge multiple long-running branches, you increase the probability of conflicts.
In order to prevent these kinds of conflicts from messing up the main branch, many people discover the idea of an integration branch. You branch from the main line, merge multiple feature or bug fix branches into this integration branch, and fix any conflicts there. When the integration branch is clean and survives the tests, you merge the branch back to main.
This approach seems pretty reasonable and usually solves the first set of problems that people have with branch conflicts. Although the conflicts still exist, the integration branch gives us the time to resolve conflicts without leaving the main branch broken. If the conflicts take time to merge, we don't have main in a broken state. If the conflicts are too overwhelming, we have an easy way to back out. Maybe merging branches in a different order will make the conflict resolution easier. In any case, we have a few more options. Life is good.
Then, someone has the idea that recreating the integration branch each time we want to do this is a waste. The obvious approach is to leave the integration branch around and just keep it in sync with main. Although this seems reasonable, we have just turned the integration branch into the equivalent of a long-lived feature branch. as we found in the previously mentioned post, this tends to result in worse conflicts and pain.
If the integration branch is not kept in sync with main, there is a real possibility of problems when integration is merged to main. I've also seen situations where someone decides that the integration branch is obviously more up-to-date and overwrites (force push) the main branch, potentially posing changes that had already been merged. This becomes the same kind of issue that we were trying to solve with the integration branch in the first place.
Key to making the integration branch strategy work is that this branch starts out identical to your main branch before you begin merging. If there is any difference at all, you court the possibility of doing a bunch of work to get the integration branch functional, only to have the same problems again when you merge to the main line.
Most version control tools provide methods for maintaining and merging multiple lines of development. Despite the fact that the tools have become increasingly good at recognizing and resolving simple conflicts, human intervention may still be required. Care is needed to make sure that you reduce the effort needed to make changes rather than just move the effort.
One real anti-pattern for version control is long-lived branches. There are a few cases where it makes sense. But, they are a lot rarer than people believe. Don't ever make a long-term integration branch solely to save the time of setting up and tearing down this branch as needed. The pain will quickly outweigh the minor benefit.
Posted by GWade at August 25, 2015 07:46 AM. Email comments