If you're a Web developer, even minor errors -- a simple typo in your code, for example -- can create major problems. But you can easily track down and reverse such mistakes by setting up version-control software. This powerful tool records all changes to a document and lets you quickly step back to an earlier version -- even if you've changed and saved the file many times since then. Just think of it as your personal time machine.
The most popular version-control software is CVS (Concurrent Versions System). Although this open-source program was developed to help programmers manage source-code files, CVS is useful for managing any type of document. In fact, a Web site is a perfect example of the sort of multifile project that can benefit from version control.
CVS originated on Unix, and like most Unix software, it runs perfectly on OS X. There's just one downside: until recently, the only way to access CVS was through OS X's Terminal application -- not an enticing prospect for most Mac users. But now Bare Bones Software has simplified the process by building support for CVS into the latest version of its text editor, BBEdit 7.0 ($179; www.barebones.com). With BBEdit 7.0, you can open old versions of files, save new versions, and collaborate on team projects, all from the comfort of a polished Mac interface.
The CVS Advantage
There are many ways to track and archive document revisions. However, CVS offers some distinct advantages. Imagine that you're in charge of your company's Web site, and you discover that the search form on the home page no longer works. You remember making changes to the home page two days ago. To see what went wrong, you'd like to compare the current home page with the version from three days ago.
You could prepare for this sort of problem by taking snapshots of your Web site at regular intervals, placing a current version of every file into a dated StuffIt archive and saving the archives in a safe place. Although this technique works, it involves a lot of manual record-keeping. You must decide not only how often you'll take a new snapshot, but also whether changing only one or two files warrants creating an entire archive.
CVS, on the other hand, does the record-keeping for you. Once you've configured the system, you simply download a copy of your project, make any necessary changes, and submit the altered files to the system. CVS automatically creates a snapshot of the revised files and updates the main project.
CVS also simplifies the collaboration process by letting multiple contributors download working copies of the same CVS project. Each team member can then use CVS to submit updated files to the main project, while also updating their local copies to reflect changes made by others. (In this article, we'll concentrate on working with CVS as a single user, but the basic concepts are applicable to collaborative projects.)
Setting Up CVS
To set up CVS on your computer, you'll need OS X 10.1.5 or later and BBEdit 7.0.2 or later. CVS is included with Apple's free Developer Tools. If you haven't yet installed the Developer Tools software, look for it on the CD that accompanies OS X or download it from Apple's Web site (http://developer.apple.com).
Although BBEdit 7.0's CVS integration is handy, it's not comprehensive. BBEdit can't set up your CVS repository or check out your project files for you. To do this, you'll need to use OS X's Terminal utility. The good news is that you should need to do this only once for any project.
Create a Repository CVS stores all of a current project's files and revision histories in a centralized location called a repository (see "Basic CVS Terms"). You can create a repository anywhere on your disk; however, on Unix systems, the standard location is the /usr/local/ directory. This directory is hidden from the Finder, but that's OK -- CVS manages the repository for you, so you don't need to see it.
Open Terminal and type the following commands:
sudo mkdir cvsrep
sudo chgrp staff cvsrep
sudo chmod g+w cvsrep
The first two lines move you to the /usr/local/ directory and create a new directory named cvsrep within it. (You don't have to use this name, but it's the convention.) The last two lines change the owner and permissions of the new directory so you can use it without administrator authentication.
Next, you must tell CVS to use this new directory as the location of your repository. Open the .tcshrc configuration file in BBEdit by typing bbedit -c ~/.tcshrc in the Terminal window. When the .tcshrc file opens, type setenv CVSROOT "/usr/local/cvsrep" into the document; then save and close the file.
Return to Terminal and type source ~/.tcshrc to apply the changes you just made.
You're now ready to initialize the CVS repository. Type cvs init. If all goes well, you won't see any output from that command.
Add a CVS Project You've created a CVS repository, but there's currently nothing in it. Your next step, then, is to add a project -- in this case, a Web site. Create a folder named TestProjectImport on your desktop and copy a few HTML files to this folder. These files will be the basis for your new CVS project.
In Terminal, type the following commands:
cvs import -m "Initial project import" testproj me start
This tells CVS to import every file and folder from the current TestProjectImport folder into a new project named testproj. The Initial project import item is a log message that will be applied to the initial revision of every file in the project. (The me and start items are vendor and release tags. For more information on them, consult the CVS documentation. For now, you can ignore them.)
When the import process is finished, you'll have two copies of your Web site: the original on your desktop, and the copy you just imported into your CVS repository. CVS does not manage the desktop copy. After the import is completed, there's no connection between it and the copy in your repository. You'll want to ignore it.
To get a copy that CVS does manage, you need to do one more thing in Terminal -- you must check out your project files. The first step is deciding where you want to put the working copy of your site. For a Web-site project, a good location is the Sites folder in your Home folder.
In Terminal, type:
cvs checkout testproj
CVS will create a new folder named testproj (matching the name of the project in your repository) inside Sites. It'll place copies of all your project's files and folders in this new folder. CVS also places a subfolder named CVS inside each folder in the project. This is where CVS stores the version-control information. For the most part, you can ignore these CVS folders. There's just one limitation: you can't use this name for any other files or folders in your project.
Managing CVS Projects in BBEdit
Now that you've created a repository and checked out a copy of your project, BBEdit can handle the remaining CVS interaction. To start, open BBEdit's Preferences, click on the Tools panel, and make sure that the CVS Integration option is selected. If it's not, click on it; then quit and relaunch BBEdit.
You can access all of BBEdit's CVS commands from the CVS menu, represented in the menu bar by a yellow icon resembling a yield sign.
Commit a File You don't need to do anything special to edit a file in your CVS project. Simply open it in BBEdit -- you should make sure that you're working with the checked-out version of your file from the Sites folder -- and then you can begin entering your changes.
When you're done making changes, save the file. You now need to commit the modified file to your CVS repository so CVS can make a record of your revisions. From the CVS menu, choose Commit File. In the Commit File dialog box, specify the file you want to commit. BBEdit will automatically select the file for the frontmost document window. If you want to commit a different file, click on the File button and navigate to the correct file. Alternatively, you can drag a file from the Finder into the path field. At the bottom of the Commit File dialog box, you can type a log message that summarizes the changes made in this revision. Log messages can be very useful when you're searching for a particular revision. When you're done, click on OK.
CVS then creates a revision for the modified file and updates the project files.
You commit CVS files as frequently as you like. Generally, committing a file when you're finished making changes to it is a good idea. Committing changes every few minutes or each time you save the file would likely be overkill.
If you're making similar changes to multiple files, you can commit the changes to all of them in one action. For example, say you use BBEdit's Find And Replace command to update the copyright date in every HTML document in your project. When you're done, choose Commit Folder from the CVS menu. At the top of the Commit Folder dialog box, choose the folder you want to commit. If you choose the main folder for your project (testproj in our example), CVS will commit every modified file in the project -- including those in subfolders. When you enter a log message (for example, "Updated copyright date"), CVS applies it to every modified file.
Add New Files to a Project Adding new files to a CVS project is a three-step process. First, create the new file and save it in your working copy of the project -- here, that's the testproj folder in your Sites folder. Make sure the file you want to add is the frontmost document window in BBEdit. Then choose Add from the CVS menu. This adds the file to the CVS project but doesn't actually store the contents of the file in the CVS repository. To do that, you have to select Commit File from the CVS menu. This third step is easy to forget, but it's essential.
Revert to a Previous Revision Once you've committed a modified file, you can return to any previous revision by selecting Get Revision from the CVS menu. This brings up a dialog box listing each revision of the file since its initial import, including the date and time it was committed and a unique version number (1.1, 1.2, 1.3, and so forth). CVS automatically assigns these version numbers. BBEdit places a dot next to the revision currently included in your working copy of the project.
What makes revisions so useful is that they let you move backward and forward through your file versions. For example, if the most recent revision to your home page is version 1.3, you can choose Get Revision to go back to version 1.1. However, if you change your mind about reverting, you can also use the Get Revision command to return to version 1.3. It's sort of like time travel for documents.
Often, you don't want to revert completely to an older version but simply want to see what has changed between it and the current version. To do this, open the current version of the file. Then choose Compare Revision from the CVS menu. BBEdit displays a dialog box listing every revision to the file. Choose the one you want. BBEdit creates a temporary file, in which it displays a line-by-line list of the differences between the two versions. (The results are exactly like what you'd get using the powerful Find Differences command in BBEdit's Search menu.) When you close the Differences Results window, BBEdit automatically deletes the temporary file it created for the old revision.
If you aren't sure which version of a file you're using, choose Get CVS Status from the CVS menu. A dialog box that summarizes the file's current revision status will appear. To get a detailed history of any file -- including the log messages describing each revision -- choose Get Revision History from the CVS menu.
So Much More
We've really only scratched the surface of CVS's capabilities -- particularly when it comes to managing multiuser collaborative projects. But even if you're using CVS by yourself, its version-control tools can ensure that you'll never again have to wish, "If only I had an old version of this file."
JOHN GRUBER is a freelance writer, Web developer, and Mac nerd. He combines those interests on his Web site, www.daringfireball.net.