Handling Long Lived Tasks
Some development tasks take a long time to implement, and intermediate steps are potentially disruptive to an ACTIVE DEVELOPMENT LINE (5). This pattern describes how to reconcile long term tasks with an active development line.
How can your team make multiple, long term overlapping changes to a codeline without compromising its consistency and integrity?
You usually want to use the version control system as a mechanism to keep the entire team up to data on what everyone is doing. Under normal circumstances, you will check in changes frequently. Some development tasks should not be integrated into
the mainline to share with the rest of the team until they are complete. For example, you may be making a major change to an interface and you need to be sure that it works before you publish it to the team.
When you are doing parallel development without controlling the interaction between everyone’s concurrent changes you can end up with wasted effort and rework. Most of the time you want to use the version control system as your commu-nications mechanism, since you want to share your work with everyone as soon as you think that it is ready, since frequent integration is a good way to improve global stability. You also want to put your changes into version control as soon as is reason-able to ensure that you have traceability and recoverability. Also, on a practical note, often development systems do not have the same backup and recovery infrastructure around them as the drives that contain the version control software.
Some changes would destabilize the active codeline if check them in. For example, a major refactoring can’t easily be done in stages, yet you don’t want to wait a week before checking in the complete set of changes. Also, since your version control sys-tem is a good mechanism for communicating changes to other developers who are working on the same task, you need a place to check your code into. The alternatives, which include sharing files, and other mechanisms that bypass the version control system, can easily cause you to get out of synchronization with each other, even if your communication is good, which is often not the case because we get distracted.
Figure 19-1 illustrates this concept.
Another example of a situation where a small group of developers is working on a task without that can cause conflict is if you are approaching a product release, but a small part of your development team is working on a new feature for a subsequent release. You want this subset of your team to share code changes using some sort of version control system, but the changes cannot go into the active development line, since they are not for this release. If only a small part of the team is working on these changes, the overhead of creating a release line might be too great, since everyone is doing work on the release line, and the mainline should remain in sync with it. With Figure 19-1 .Some Tasks are for the future
/main
some tools the only reliable way to synchronize both lines, is to check code into both places. Figure 19-2 illustrates this.
A small team of developers working on a future task can have a more lax codeline policy with respect to keeping there work synchronized with the active mainline because they can communicate among themselves more efficiently than the larger team can.
You need a way to allow a team of developers to work on a task that is paralled to the mainline for a short period of time, while keeping all of the benefits of the version control tools.
Parallel Lines
We were changing the persistence mechanism for our application. This had far reaching implications. We were changing the mechanism because there were problems with the existing one, so there were bug fixes going on as well. The fact that there was some isolation at the module level between the persistence code and the other parts of the system made this a bit easier.
By creating a branch with the files that we were updating, we could allow a group of people to enhance the persistence mechanism while other work was going on.
Figure 19-2 .Creating a Release Line too Early is Troublesome
1.0 /earlyRelease
/main
Use Branches for Isolation
Fork off a separate branch for each activity that has significant changes for a code-line.
A branch is a mechanism for reducing risk. You can use a task branch as “a mecha-nism for physically isolating riskier development ventures from the code base”
(Vance 1998).Once the activity is complete and all of its file changes have been tested, checkin files on the activity branch. When the task in complete, merge with the main-line. Michael Bays describes the scenario for a task branch (though not calling it by that name) (Bays 1999):
It is common for a single developer to create a branch from the trunk in order to execute a change that will require a non trivial amount of time and not be impeded by changes others are making in the same files. As work in this developer branch continues, the source trunk will continue to iterate through revisions with the work of others. Eventually, the developer will want to take the files that she has changed and merge them back into the latest file versions on the trunk.
You need to be sure that all of the code that has changed on the mainline since the time you started your branch, still works with yours. Either merge the activity branch into the appropriate codeline (as a single transaction). Otherwise notify the appropri-ate codeline owner that the change is complete and ready to be merged and provide the codeline-owner with any other necessary information for finding, merging, and testing the change-task.
If your VCS supports ‘lazy branching’ where your branch inherits all the code from the mainline unless it change on the branch, you can use a task branch when you have to isolate a small amount of ‘future work’ from the mainline Figure 19-3 shows this structure.
Task branches are especially useful when you have multiple people sharing work that needs to be integrated together. For this reason, you can also use a task branch for integration prior to releasing a change to the active development line. You can integrate a number of changes into the task branch, and then merge the task branch back into the active development line when the changes pass your tests.
It is important to integrate changes from the active development line into the task branch frequently. You want the final integration of the task branch with the active codeline to go as smoothly as possible.