Font: Mechanical pencil for body, Erwin for heading
Sources: Tim Ottinger, George Dinwiddie (via mail list), Jeff Langr
Branch-per-feature is a common SCM strategy in which a branch is created on a central server for each feature that is under development. As a feature is completed, the branch is integrated back into the main development code line.
In some organizations, releases are composed by merging selected, completed features together. This seems quite rational, and can be made to work with enough effort applied in bursts. Every merge creates a unique, new configuration in the system that must be tested for side effects. If the merge has unintended consequences, then one or more features must be modified or the release re-composed without it. As a result, releases become major events in the life of the company with huge testing parties and great schedule risk. These times are frequently called "hell week" or "hell month" depending on the release periodicity.
In addition, the more two lines of code diverge, the harder it is to reconcile their changes. When work is integrated several times a day, it tends to be a fairly trivial effort. When it is integrated only a few times per month, it is rather harder. A few times a year, and it is surprisingly difficult. Likewise, if many branches are held for a long time, each branch will not only diverge from the main codeline but from other branches as well. This effect can make it rather difficult to estimate the effort of integrating branches, which contributes to the nervousness around hell week.
Agile teams integrate continually with great ease and success. Why, then, do some organizations hail branch-per-feature? Teams that use branch-per-feature as regular practice are often compelled to do so because they don't know which tasks/stories will actually be completed by the end of the sprint. It seems easier to hedge bets with version control systems than to tackle the organizational/political problems that frustrate planning and execution of sprints.
- Too much WIP (work-in-process) means that too many tasks are undertaken at once. Branch-per-feature helps the team deal with the fact that work is not being finished predictably or reliably within the iterations. Many tasks are reported complete on the last days of the iteration, yet some of those are rejected. Branch-per-feature allows management to decompose and recompose the release at the tail-end as they find out what is actually completed.
In an agile team, as many as half of the features are done by the midpoint of the iteration and are being tested frequently. Very few changes are actually at risk of being left incomplete. In the best teams, missing an iteration boundary is a rare event, so branched features are unnecessary.
- Features are too large if they cannot be completed in a small part of a single iteration. Otherwise the uncertainty prompts the team to fork the code base. The forked code base is more difficult to integrate as it diverges from the original code line. Fear of difficult integrations actually encourages the team to hold isolated branches longer.
Agile teams instead look to ensure features are small enough to completed within a few days. Small features completed in a day or two rarely require complex merging. Any overlap of effort can be easily coordinated with other team members during stand-ups or ad hoc conversations across the team table, further minimizing the chance that a merge will be necessary.
- Structure is poor if changes routinely span many files in many libraries or assemblies (something Martin Fowler refers to as "shotgun surgery"). When a feature's implementation is scattered all over the code base, it is harder to accurately make changes and harder to predict when work will be truly done. This uncertainty drives the team to isolate rather than integrate.
Agile teams are highly cognizant of the value of simple, SOLID design. They understand that systems exhibiting true cohesion and minimal duplication dramatically lower the need for shotgun surgery.
- If there is no way to turn off incomplete features then the team will fear customers stumbling into incomplete sections of code and causing damage to data or additional customer support burden. This force drives developers to develop code in isolation from the main codeline, which of course increases the cost of integration.
Agile teams view changes to the system holistically, breaking down each new feature as a series of incremental changes to the mainline. They understand that while this requires some level of overhead, it means that merge hell is minimized, and that it demands a better system design. For larger changes, they look to solutions such as branch by abstraction as helping provide both benefits.