Subversion : The new generation CVS
Software development is an iterative process that benefits from coordination between developers and historical archives. To facilitate such practices, developers can turn to special versioning software. In this article we will explore Subversion, one of the most recently released version control suites.
If you have ever collaborated on an open source project you are probably no stranger to Concurrent Versions System (CVS) , the most popular open source version control system. A great majority of code bases are under CVS control. Even if you have developed mostly proprietary software, chances are good you have worked with CVS, since it offers a great alternative to more expensive proprietary versioning systems like Bitkeeper or Perforce. Subversion builds on CVS concepts.
We will start of by creating a Subversion repository. The process is very similar to that of CVS:
** In CVS **
bash$ cvs -d /home/web init
** In Subversion **
bash$ svnadmin create /home/web
The /home/web directory represents the location at which the repository will be created. The repository is rarely modified or accessed directly.
Next up, we need to bring a series of files under the control of Subversion:
** In CVS ** (Where files to be placed
are in the working directory)
bash$ cvs import -m "Our initial files"
linux justmine myversion
** In Subversion ** (Any location)
bash$ svn import /tmp/linux/ file:///home/web/
-m "Our initial files"
The first parameter represents the directory where the unrevised files reside. The second option indicates the location of the Subversion repository. The -m flag represents an initial comment for the import. Other special flags are available for the process of importing files in Subversion, like --editor-cmd, which allows you to specify a text editor for adding an extensive comment, and -N, which performs the import in a non-recursive manner.
If you import a binary file with this process, you will notice a welcome difference from CVS. Subversion automatically detects the binary format, thus avoiding the need to execute an easily forgettable CVS command to toggle a file's flag to a binary format (cvs admin -kb). CVS's design forces it to store changed binary files as full copies, thus bloating the size of the repository. Subversion's design allows it to store binary files differentially, reducing the amount of space used.
Our next step is to create working copy -- but wait. Even if you successfully executed the previous commands, you now have only an independent Subversion repository (back end) and client. The actual communication has its own details, as we will now examine.
Subversion is tightly integrated with the Apache Web server, which allows it to provide a robust back end for repositories in areas such as authentication, path-based authorization, and browsing, although support is provided by an external module. This configuration is very Apache-specific, so we will not address any details here. As an alternative, Subversion offers a lightweight solution named svnserve which uses a proprietary protocol running over TCP. For our simple needs svnserve will do. If you followed the default installation instructions you should be able to access it. Place it in the background with the command svnserve -d.
Now that we have an active server process for accessing our Subversion repository, let's execute the command svn checkout svn://localhost/home/web/ linux. This creates a working copy from the linux module located in the repository defined at localhost under the /home/web/ directory.
Notice that we need to use a fully qualified name for our repository location, including its protocol -- svn for our Subversion's native implementation. If you're an avid CVS user you are probably asking yourself, isn't there an SVNHOME for defining the repository location as an environment variable? Today there isn't, so you need to type in a fully qualified URL or define your own bash environment variables and use them at the command line.
Once you have the working copy, make some changes to it so we can illustrate Subversion's update and commit process.
A common practice before transferring changes from a working copy to a repository is to recheck what files have been modified. In CVS, this is typically done with the command cvs update, which displays a list of files that are altered, compared to the repository. In Subversion you have to use the command svn status to display this information; the command svn update only does an actual update, and does not have the side effect of displaying a comparative state between the working copy and repository.
The command to transfer changes from a working copy to the repository is identical to the one used in CVS: svn commit. However, the actual commit process has a few enhancements. Whereas CVS's commit process is done on a per-directory basis, Subversion's process is atomic in the same fashion as a relational database: no part of a commit takes effect until the entire batch commit has succeeded. Another change is that revision numbers are assigned on a per-commit basis and not on individual files. This same process also provides for comments being archived at each commit.
The renaming and deletion of files and directories in CVS has long been a nuisance, since you are required to manually modify the repository or inspect obsolete files in working copies. Subversion offers svn rename, which upon committal transfers the working copy renamed files or directories to the repository without duplication. Subversion also automatically transfers these changes when a user updates his own working copy.
Another Subversion enhancement appears in the forking or branching process. Assuming you're inside a working copy named linux and you wish to fork a new branch from the current revision, you would execute the command svn copy linux/ myforkedlinux/. This would schedule the addition of a new set of files exactly as they are present in the linux folder to be added under a directory named myforkedlinux upon the next commit. The newly created copy provides an entry point into the already existing tree in the repository, or in Unix lingo a "hard link," which obviously reduces the size of your repository. For this reason this process is often dubbed "cheap copies."
These are the main commands you need to get up to speed with Subversion, as well as its main enhancements when compared to CVS. You can take advantage of these and other provisions to ease your collaborative development. If you want to migrate your old CVS projects, Subversion provides a special script/tool that allows you to convert CVS repositories to Subversion back ends.