7.1. Creating a Project
A project is any group of files and directories that exist beneath one project root directory. Every project must include at least one directory, because CVS needs to be able to create a subdirectory to store metadata about the project.
Most often, a project represents one program, one set of related configuration files, or one web site. Sometimes, a project is a collection of related items. For instance, I store all my articles for http://www.oreillynet.com in one project, with each topic grouped under a subdirectory. Sometimes a project is a subsection of something larger.
If you want to create a project right now with default settings and minimal reading, read "Importing Projects" in Chapter 2. That section walks you through the process of importing a project.
7.1.1. Preparing a Project
To create a project in CVS, you need a copy of the files and directories you want to import, or an idea of which files and directories you want to make. If you are planning to import an existing project, be sure to make a backup of it before you proceed.
If you have an existing set of files and directories, check whether you have files that can be generated from other files, such as compiled code. Files that can be generated easily do not usually need to be stored in CVS and can be removed from the copy of the project. It is good practice to store the commands that generate these files in CVS as part of the project, usually as a build script or as part of the installation document.
If you have a set of files stored in another version control system and want to save their revision history, see "Importing from Other Version Control Systems" later in this chapter. If you don't need to retain their revision history, export the files from the other system using a command that gives you a clean copy of the project with no administrative files, and use that copy to import from.
If you don't have any existing files, you can import a single directory with the project name. If you are more comfortable with a structure to work from, create an initial directory structure for your project and import that.
If you cannot easily fit the task you are trying to accomplish into a single project, you can use the modules feature of CVS to give each development team a smaller section to work from, or you can create several projects and use a module to combine projects into a larger unit when needed. Modules are explained in "The modules File" and "Project Structure and Sandboxes," both later in this chapter.
Be aware that CVS restricts the filename CVS for its own purposes. You should also avoid using Attic, .cvsignore, and any filename in the format .#filename.revision.
Once you have at least one directory ready to add to the repository, you need to decide how to add it. There are two methods, which are explained in the following section "Importing a Project" and in "Alternatives to Importing," later in this chapter.
7.1.2. Importing a Project
The cvs import command is used for both creating a new project and updating the vendor branch. Vendor branches are explained in "Vendor Branches," later in this chapter.
To create a new project, make your initial directory structure and place in it the initial files for your project, or set out your existing code that is ready for importing, as described in the preceding section, "Preparing a Project." Run the cvs import command from within the root directory of that structure. CVS takes the files and directories from the initial directory structure and copies them into the repository. The syntax for cvs import is:
cvs [cvs-options] import [command-options]project_name vendor_tag release_tag
cvs import requires a log message and calls an editor if it is not invoked with the -m option. You'll then be able to type a message into the editor to record the purpose of the import. See Chapter 2 for more information about the log message.
Check out a sandbox to test whether the import command has worked. If the files are in the sandbox correctly, you can remove or store the original files or directories as you see fit; CVS no longer needs them. cvs import doesn't change the files it imported from, and it doesn't convert them into a sandbox.
Example 7-1 shows how to import a project and create an initial project sandbox. The vertical ellipsis indicates where CVS calls the editor so you can enter a log message. Note that I change directories before checking out the test sandbox.
Example 7-1. Importing with cvs import
cvs import saves the data from the files to both the project trunk and to the special branch known as the vendor branch. Unless specified otherwise with -b, the vendor branch is given the ID 1.1.1. The vendor tag parameter is used for the branch tag, and the release tag tags the branch at the current (just-imported) revision. These tags can consist of only alphanumeric characters, hyphens, and underscores.
If you need to import binary files or other files that are not plain text, see the information on binary files in Chapter 3 before adding them to the repository.
The cvs import command honors cvsignore and cvswrappers files and recognizes the standard -k, -I, and -W options (also used by cvs checkout and cvs update) explained in Chapters 3 and 10. The -d option causes CVS to record the time of import based on a file's last modification time, rather than the current time.
Like cvs update, cvs import reports on the status of files it adds to the repository. These are the output codes for cvs import:
7.1.3. Vendor Branches
A vendor branch is a special type of branch that CVS creates automatically when you import a project. If your project is based on code external to the project itself, such as in-house patches to a vendor's code base, the vendor branch provides a way to merge updates from the external source with your own code.
If you intend to use vendor branches, create your project with cvs import, using the vendor's code as the initial directory for the project. Make your changes on the main trunk and run the project normally; the vendor branch is used only when the vendor releases a new set of code.
When the vendor provides a new release, use the cvs import command to add the new code to the same CVS project with the same vendor tag and a new release tag. In effect, this is a special cvs commit to the vendor branch.
Example 7-2 shows a vendor-branch import to the wizzard project. Note the new release tag. The project name and vendor tag remain the same as in Example 7-1.
Example 7-2. Importing a vendor branch
If a file is changed on the vendor branch and the local file has not changed, CVS sets the trunk revision of the file to the new vendor-branch revision.
If both the vendor-branch copy and the local copy of a file have changes, CVS reports this as a conflict with the message "N conflicts created by this import," where N is the number of conflicts. CVS also provides a suggested variant of cvs checkout to help you resolve all the conflicts, using two -j command options to merge the vendor branch with the trunk.
CVS 1.11.5 tries to provide the exact cvs checkout command you can use to find the differences between the previous release and the current release of the vendor branch and merge those differences to the trunk. If your version doesn't do this, try the following command:
cvs checkout -j previous_release_tag -j current_release_tag projectname
You may also need to include the -d repository_path CVS option if you run this command from outside the sandbox, where CVS can't find the repository path in the sandbox administrative files.
"Merging Branches" of Chapter 4 explains how the -j option works and how to resolve any conflicts that arise from this type of merge. Tag the vendor branch once these conflicts have been resolved, and use that tag as the previous_release_tag when you next merge changes from a vendor branch.
If you have more than one external source for a project, you can use the -b command option to run cvs import on an arbitrary branch number. This creates an additional vendor branch with the specified branch number. Create a separate vendor branch for each separate code source for your project, to help you keep track of which changes came from which vendor.
When selecting a branch to use as a new vendor branch for a new code source, determine that there is no preexisting branch with the number you choose. When updating an existing vendor branch (other than the default branch), use the -b option with the numeric ID of the branch, to specify the target branch for the current import.
7.1.4. Alternatives to Importing
If your project does not contain files provided outside the project, it is unlikely you will need to use vendor branches. If this is the case, you can bypass cvs import. To do so, create a new project by adding a new subdirectory to the repository root directory, either by editing the repository directly or by checking out the repository root directory and then using cvs add in that sandbox.
If you do not need the vendor-branch capability of cvs import, the choice between cvs import and the combination of cvs checkout and cvs add is a matter of personal taste. However, I recommend that you use either of those methodsusing CVS commands to create a new projectrather than editing the repository directly.
184.108.40.206. Creating a project with cvs add
To create a project with CVS commands other than cvs import, you need to check out a sandbox that contains only the repository root directory, create the new project root directory, and add that directory with cvs add.
To check out the repository root directory, use a period (.) as the project name. Use the -d name command option to specify a directory name in which to check out the sandbox. To avoid including subdirectories, use the -l command option to cvs checkout.
Example 7-3 shows how to create a project and an initial project sandbox by checking out the repository root directory and using cvs add.
Example 7-3. Importing without cvs import
These are the steps for this method:
220.127.116.11. Creating a project by editing the repository
The second way to create a new project and bypass cvs import is to edit the repository directly. Editing the repository always involves the risk of making a minor typing error and affecting other projects (or your own), so I suggest you back up the repository before editing it.
To create a new project by editing the repository:
The rest of this process is optional and is needed only if you have existing files to add to the project:
7.1.5. Importing from Other Version Control Systems
You might want to import a project, including the project's history, from a different version control system into CVS.
If the other version control system can export files into RCS format, use the following steps to install the RCS files into CVS:
If the other version control system can't make RCS files, write a script to check out each revision of each file from the other system and commit it into CVS, or create an RCS file with the RCS ci command and use ci to add each revision of the original file to the RCS file. If you create RCS files, you can install them to CVS as described earlier.
The contrib directory in the CVS source contains scripts that convert SCCS and PVCS files to files that CVS can use. These scripts can be used as templates for scripts to convert files from other version control systems. Appendix B contains more information about the sccs2rcs and pvcs2rcs scripts.