The concept of branching. The Subversion documentation has a decent layman’s description of branching:
Suppose it’s your job to maintain a handbook for a particular division of your company. One day a different division asks you for the same handbook– but with a few parts modified specifically for them, as they do things slightly differently.
What do you do in this situation? You do the obvious thing: you make a second copy of your document, and begin maintaining the two copies separately. As each department asks you to make small changes, you incorporate them into one copy or the other. But you often find yourself wanting to make the same change to both copies. For example, if you discover a typo in the first copy, it’s very likely that the same typo exists in the second copy. The two documents are almost the same, after all; they only differ in small, specific ways.
This is the basic concept of a branch– a line of development that exists independently of another line, yet still shares a common history. A branch always begins life as a copy of something, and moves on from there, generating its own history.
I find that almost every client I visit is barely using branching at all. Branching is widely misunderstood, and rarely implemented.
Here are a few common patterns of branching:
Branch per Release
Every release is a new branch; common changes are merged between the releases. Branches are killed off only when the releases are no longer supported.
Branch per Promotion
Every tier is a permanent branch. As changes are completed and tested, they pass the quality gate and are “promoted” as merges into successive tiers.
Branch per Task
Every development task is a new, independent branch. Tasks are merged into the permanent main branch as they are completed.
Branch per Component
Each architectural component of the system is a new, independent branch. Components are merged into the main branch as they are completed.
You may notice a few emerging themes in these branch patterns:
- All branches have a clearly defined lifecycle. They either live forever, or they are eventually killed off.
- All branches are created with the intention of eventually merging, somewhere. A branch without a merge is pointless.
- As we add branches, our development model gets complicated.
So what are our options?
- Maximum Productivity
Everyone works in the same common area. There are no branches, just a long, unbroken straight line of development. There’s nothing to understand, so checkins are brainlessly simple– but each checkin can break the entire project and bring all progress to a screeching halt.
- Minimum Risk
Every single person on the project works in their own private branch. This minimizes risk; everyone works independently, and nobody can disrupt anyone else’s work. But it also adds incredible process overhead. Collaboration becomes almost comically difficult– every person’s work has to be painstakingly merged with everyone else’s work to see even the smallest part of the complete system.
The answer usually lies somewhere between these two extremes.