CVS allows developers to "check out" a copy of a project, the developer makes changes to the project, and then "commits" those changes to the repository. If a second developer commits changes inbetween the first developer's checkout/commit, the first developers changes would be merged into the repository (unless there is a conflict which must be resolved first.)
CVS allows for project branching. A project can have any number of branches. For instance, each public release would be a branch of the same source tree. The development branch would be another. At any time, a developer could checkout any branch (say for bugfixing) and commit that branch back into the repository at the appropriate place. A developer can view all the differences between two branches, which makes porting fixes very easy.
CVS rocks my world. I wish I had looked at it earlier.