I’ve definitely seen my fair share of source code chaos. Take a 3 man development team working on their SaaS app. Things should be pretty simple, but someone took a peek at the branching guide on Codeplex and now they have 10 different branches, don’t know when to forward integrate or reverse integrated, and when they finally do are plagued with merge issues.
The thing is, most of the branching guides out there are written with the assumption that you’re working on a huge team with complex issues. They assume you have an application that sits on the shelf or gets installed on someone’s laptop. For client side applications, you always have to be able to support multiple versions at any given time, but most of us are living in the world of the web. We have the benefit of knowing that only one version of our application will ever be “live”. And with that comes the ability to simplify how we structure source control.
How Many Branches Do I Need?
The short answer… As few as possible.
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
Every time you branch, you’re adding overhead. Another line of code to maintain, to merge. Every time you create a branch you should see a tangible benefit. The concern that two people might touch the same file at some point is not reason enough to introduce complexity.
My general recommendation is up to 3 branches:
The Main Line – This is what gets deployed
A Quality Branch (optional) – Typically known as the Dev line
Production Support Branch (optional) – Needed when production breaks so often that we know we’re going to need an emergency fix in the middle of our sprint.
Do NOT Branch by Version
I see this all the time. Every time a team releases a new version of their build to production they spin off a new branch. When I audit these scenarios I’ll see something that looks a lot like this:
My first question is always, “When’s the last time anyone used Version 1.0?” If the answer is anything other than within the last week, I know we have a code organization problem. If you want to snapshot your code during a deployment, add a label. You don’t need a branch.
The Main Line
Everybody has a Main line, even if they didn’t call it that. This is where code that is going to be deployed resides. For many teams, this may be all you need. Your developers work in the Main line, they deploy from the Main line. What’s more simple than that?
If you only have a Main line, don’t be embarrassed or ashamed. It doesn’t mean you’ve done anything wrong. The Main line is efficient. It means you’re verifying your code works before you check it in. It means that your code is good enough that you don’t need to worry about having to support an emergency deployment. You know you can branch by label if an emergency happens, otherwise you’ll just solve the problem during your next release.
If you’re just starting on a project and you have a small team of close developers. This is where you should begin. Don’t add layers until you need to.
The Dev Line
One day you may decide that Main is just too precious. We need to protect Main from those other nasty developers. So you’ll decide to add a Dev line. This is what I call branching for quality.
When you branch for quality, you make all the changes in your Dev line. You want developers to check in early and often to avoid merge issues, but you also want to provide an additional quality gate before it makes it into the Main line. A few examples of such quality gates:
Gated Check In or Continuous Integration Builds
This model is especially useful for contractors and vendor based development teams. By locking down your Main line and having the contractors work in the Dev line, it provides you an opportunity to review any code and ensure it passes your quality gates before making it into the Main line. Merging is extremely simple, as you’re only doing a one way merge from Dev into Main. No conflicts necessary.
The Release Line
If you often find yourself working on emergency break fixes outside of your normal release schedule, instead of creating a branch for each release, create a single Release branch. This code should always be what exists in production today. By having a single Release branch, merging stays simple and there’s never any confusion as to what code is live.
Day to day, your developers would still work in either your Dev or Main line. When you release to prod, you’ll do a merge from Main into Release, and hopefully it won’t need to be used. But if that day comes when you need to fix something and fast, the Release line will be there for you. Make the fix in the release line, test it, deploy it, and save the day. After you pulse returns to normal, merge the fix into Main and if necessary from Main into Dev.
Working in your Release line should not be common. If you’re in there more than a day or two, you’re probably not fixing a bug, you’re adding a new feature. I’ve seen projects where the client agreed to one thing in the sprint. You start working on the sprint, you’re two weeks in and now the client wants a new feature and he wants it now. The problem, you still have 2+ weeks left. So should you just create the feature in your Release line? NO! If your client can’t go two weeks without deciding he needs something else, then you don’t need more branches, you need shorter sprints.
Check In Early, Check In Often
The best way to avoid merge conflicts is to have developers check in their code as often as possible. Not only will this avoid merge issues down the road, but it keeps your code safe, which is a large reason you’re using source control in the first place. The longer a developer goes without checking in code, the more work and more money that’s wasted if something were to happen to their system. I’ve seen a developer leave a company who hadn’t checked in their code in a week, basically throwing away a week’s worth of work.
I recommend checking in at the end of each task and at the end of each day. You should never lose more than a days worth of work. If the code you’re working on at the end of the day would destroy the build, use shelving. Shelving is basically a private check in. The code is stored on the server, but it is unique to you. No worries about breaking the build, no worries about losing your work. Win-Win!
These basic strategies will work for the majority of web applications out there. They may seem simple, and that’s because they are. Your code may be complicated, but not your source control.
There are a few cases when these strategies just won’t work for and you may need to break the mold:
Branch by Feature – If you team is really large, you may need to break your application up into modules and work on feature teams. However, your application must be designed in a way that supports this. Features should be able to be worked on independently without affecting other portions of the code.
Branch by Release – Now I know I said don’t branch by release, and I stand by it, but if you have a app that lives on the client that may need support for multiple version (desktop, mobile, etc.) then sorry, you probably need a branch for each release that you need to support.
Branching Shared Components – If you have a suite of application that use shared components, you may want to create a solution for that component and then branch the class library out to the dependent applications. You could, of course, just share out the compiled assembly, but I’m sure you have your reasons…
Do you have another branching strategy that works or a crazy source control problem this just won’t fix? Let us know.