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, and 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. Most of us have experienced situations where order has been been created out of chaos by slowing things down and controlling changes so that they are, perhaps, grouped together in releases, reviewed and authorized before being allowed to happen. 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 will maximize the value of the system being developed.
A traditional SCM approach for managing change is isolating streams of work to reduce the immediate impact on other streams when changes are made to another. While this provides short-term gains, it also defers the cost of integration until a later, perhaps more sensitive, point 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, thus 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:
- 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. Also, 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 maintain 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 functionality by 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:
- Correctly build, run (and pass) all the tests
- Contain no duplicate work/work-products
- Transparently contain all the changes we needed to make
- Minimize the number and length of sub-branches and unsynchronized work/changes (see Lean branching)