Software Development teams deliver value by writing new code, or by changing existing code and functionality. The majority of the time it is about changing existing systems, not writing completely new ones. Software Configuration Management is one of the disciplines responsible for managing that change. Rapid, unmanaged, change can cause chaos and reduce productivity. One (easy) way to reduce that chaos is to reduce the frequency of change. We have most of us experienced situations where order has been been created out of chaos by slowing things down and controlling changes such that they are perhaps grouped together (in releases), reviewed and authorised before being allowed to happen, and similar practices. Rapid, well-managed change is a mechanism for delivering value more quickly. Rather than simply managing change, SCM can be a tool for enabling change that maximizes the value of the system being developed.
A traditional SCM approach to manage change is to isolate streams of work to reduce the immediate impact of changes in one stream on others. While this provides for short term gains, it defers the cost of integration til a later, perhaps more sensitive, time in the project. By realizing that branching is not the only tool teams can us to manage change, and by using simple codelines, and good engineering practices, your team can develop new features in an integrated manner, isolating streams of development, and not incurring the associated cost of branching and merging.
Applying the Principles of Lean development to Branching
The principles of Lean development, as applied to Branching are [LEANBRANCH]:
- Eliminate Waste - Eliminate avoidable merge-propagation, long-lived variant branches, and stale code and partially completed work
- Build Quality In - Maintain codeline integrity with an automated unit & integration tests and a Codeline Policy to establish a set of invariant conditions that all checkins/commits to the codeline must preserve.
- Amplify Learning - Facilitate frequent feedback via frequent/continuous integration and workspace update
- Defer Commitment - Branch as late as possible! Create a label to take a "snapshot" of where you MIGHT have to branch from, but don't actually create the branch until parallelism is needed.
- Deliver Fast - Complete and commit change-tasks and short-lived branches (such as task-branches, private-branches, and release-prep branches) as early as possible
- Respect People - Let developers reconcile merges and commit their own changes (as opposed to some "dedicated integrator/builder")
- Optimize the "Whole" - When/if branches are created, use the Mainline pattern to maintain a "leaner" and more manageable branching structure
In other words, branch when it makes sense, but realize that branching has a cost and remember that branching is not always the best tool for managing change.
If you favor eliminating waste, and the other principles of lean branching, working on a single codeline, when in the past you might have favored a branch, requires a commitment on the part of the development team to maintaining the simplicity necessary to make this process work.
Simple Codelines and No Broken Windows
For teams to make progress, you need to keep the codeline functional. In the words of the Pragmatic Programmers, "clean, functional systems deteriorate pretty quickly once windows start breaking" [ENTROPY]. If the codeline is always working, it's easy to migrate new functionaliy in using adapters, or to add modules for new functionality without integrating them tightly into the existing code. One way of viewing this is as simple codelines. The Rules for simple codelines are [SIMPLE]:
- Correctly build, run (and pass) all the tests
- Contain no duplicate work/work-products
- Transparently contain all the changes we needed to make (and none of the ones we didn't)
- Minimize the