This note compares PERFORCE and CVS, a publicly available source management system built upon RCS. Although CVS is freeware, at least one company provides commercial support, Cyclic Software.
This note assumes you already are familiar with CVS and want to learn more about PERFORCE. If you don't know about CVS, check with the references above. CVS and PERFORCE are similar in many ways; thus this note attempts to contrast the two.
PERFORCE benefits from a unified architecture with a built-in database and librarian (a high-performance reimplementation of RCS). CVS is still a hybrid of relatively new code built upon the existing RCS package.
CVS allows multiple files to be submitted at the same time, but doesn't assign that collective action an identity of its own: the fact that the files were submitted together is lost. Also, if you interrupt CVS during the submission, you can wind up with some files committed and some not.
CVS stores enough state information on the client to control its interaction with the repository, but doesn't otherwise hold information to help you keep track of what you are doing.
As of 1.7, CVS has a "watch" facility which can notify you when someone plans to edit a file. Its use is optional and can be turned on or off for individual files.
CVS has no way to lock the files in the repository against concurrent changes. You must permit concurrent changes, and then merge in changes from other users, if any, before checking in the files.
In CVS, each client directory corresponds to one repository directory, and you establish this relationship when you first checkout the directory. Thus directory names between the repository and the client don't have to be the same, but file names do. CVS has separate commands -- "checkout" and "update" -- for the initial fetch of files from the repository and for subsequent refreshing. By default, the checkout command recursively processes subdirectories. To describe arbitrary collections of directories (or parts of directories), CVS also has the notion of "modules". When you checkout directories, you can give a module name instead and CVS checks out the directories listed for that module. The module list is shared among all users of the CVS repository.
CVS uses the traditional branching model: branches are identified by a perturbed version number (e.g. 1.2.3.1.1.2). Symbolic names are usually applied so you don't have to deal with the numbers much.
In PERFORCE, variants of a file are just files with different names. A "branch view" and subsequent integration history relate the variants. Previously unrelated files can become variants of each other.
In CVS, variants of a file form a tree in the version namespace of the file. (File branches are on this tree.) Thus, all variants of a file are within the same file, and they are related by the file's name.
CVS doesn't track merges between branches: if you merge one branch into the other, change the first one again, and then merge again, you'll find yourself merging the same changes twice. If the first merge involved resolving a lot of conflicts, you see them all again. To avoid this, you can yourself tag revisions that have been integrated and use that tag the next time you merge.
When CVS updates your directory, any merging required is done on the spot. If you are updating a large tree, merges may be scattered throughout it. Each merged file replaces your working file, which itself is renamed to a hidden (.something) file.
When PERFORCE updates your client workspace, all merging is deferred until the "resolve" command is run. The "resolve" command steps through each file that needs merging takes you through an interactive session where you can compare and edit the various revisions taking part in the merge before replacing your working file.