7.6. Strategies and Practices
CVS is a tool that can help you manage a project, but you need to decide how to use CVS with your project to make it work effectively for you and your team. The following sections present some ideas to help you integrate CVS into your working practices.
7.6.1. Tag and Branch Strategies
Decide whether and how you will use tags and branches, and then decide on the format to use for tag and branch names. Branching philosophies, styles, and policies are explained in the "Branching Strategies" section of Chapter 4.
I strongly recommend keeping almost-complete work separate from experimental work. In programming projects, I recommend keeping bug fixes separated from the main body of development by putting either bug corrections or development on a branch.
If you use branches, designate an owner for each branch. The owner should be responsible for seeing that the branch is used for its specified purpose, for maintaining a record of the changes made to that branch, and for managing merges to or from that branch.
I strongly recommend tagging at strategic points in development, at the root of each branch, and at each merge point. See "Tagging Strategies" in Chapter 4 for more suggestions on tagging.
7.6.2. Automation Strategies
Automation can be helpful in ensuring that a project moves smoothly to completion. Generally, automation translates into consistency. When using CVS on a project, you may find the following automation strategies to be helpful:
7.6.3. Project Structure and Sandboxes
Good project structure remains good structure, regardless of the use of version control. You know how to structure your project, whether it's a small web site or a complicated client-server application: you're the expert on your particular project and how to lay it out.
As long as your project can be developed and tested under a single top-level directory (and without symbolic links), you need not modify it at all for use under CVS. If it can't, consider developing it under a top-level directory, and using a build system such as make to distribute the files for testing. If your project is particularly large, consider breaking it into subprojects or using modules so that each developer needs to check out only her part of the project.
In small projects, each sandbox can contain the entire source tree. In larger projects, use symbolic links or other tools to allow the developers to share a central set of standard files. In such projects, each developer's sandbox should contain only the files that developer needs to work on, and the build script in each developer's sandbox should include commands to create the necessary symbolic links to the central files. This practice allows developers to compile and test their own code without having to compile files they haven't changed.
Consider having a central build sandbox that is automatically updated and built on a regular schedule. This sandbox can be used to test the integration of the whole project. If developers fail to commit all their necessary files, the central build usually fails, because the update is unable to retrieve the uncommitted files. This makes it obvious when someone has forgotten to commit a crucial file.
Each task should have its own sandbox; each developer, tester, and editor should work from his own sandbox, and anyone who is working on multiple branches should work from a different sandbox for each branch. If there is a central build, it should be in its own sandbox. If there is a file server, it should be a separate sandbox.
Use cvs release to remove sandboxes. This helps prevent modified or new files from being forgotten. If the history file is in use, this command records the removal of a sandbox.
7.6.4. Client and Server Version Mismatch
The CVS 1.12 line of development provides many new and useful tools to repository administrators and project managers. It's extremely tempting to run 1.12 and use the new featuresbelieve me, I know! Unfortunately, many of us don't control the software our users use. Here's a partial list of problems you can encounter if you're running a 1.12 server, but your users are running a recent 1.11 client.
The following features are available only in 1.12 series clients (and later):
7.6.5. Practices for Development
Decide whether to use the simultaneous development model or one of the watching files or reserving files models of exclusive development. These models are explained in Chapter 5, which also explains how to use each model in CVS.
Consider using watches, notification emails sent via scripting files, or other tools to keep developers informed of what is happening during a project's development.
Develop strategies for updating and committing sandboxes. Sandboxes and the repository need to be kept synchronized to minimize conflicts and to ensure that a project is fully backed up. Deciding how frequently your users update and commit is a matter of judging the risk of breaking the build with incomplete work versus the benefits of storing data, even when it won't compile. The risk of breaking the build can be minimized with the careful use of branches.
The most common work pattern for development projects is update-edit-test-commit. In this pattern, your developers update a sandbox first thing in the morning, work on their files, test their files, and commit at the end of the day. Some groups commit at lunchtime and update again after lunch, working on a shorter cycle.
The greatest risk with frequent commits occurs in environments where one person can break something for everyone, such as a programming environment. If a person's code doesn't compile and this broken code is propagated to the entire team, no one can compile until that code is either removed or fixed. For this reason, many programming teams have a rule against committing before your code compiles.
The rule about not committing until your code compiles works well in some situations, but if a person is doing long-term experimental code, the code might not be in the repository for days. If the sandboxes aren't backed up, that's several days of work at risk. In such cases, I recommend letting the person work on an experimental branch and commit to the branch.
Some teams prefer to restrict updates rather than restrict commits. These teams update stable code into their sandbox and work from that stable code base until they have completed a feature. Then they update from a new stable code base. The risk in this case is that the changes one person has made to the code will conflict with changes from a team member in a way that CVS cannot merge, and someone will have to merge those changes by hand. The benefit is that team members are working against a known code base. This system can be duplicated by using a branch to build the feature on, then merging the branch and the new feature to the trunk. Using the branch also provides a way to commit the partially completed feature without affecting other people's sandboxes, which helps protect against mistakes.