Using CVS with AnyJ
Quick introduction to CVS
CVS is an open source command line based version control system. If you know other version control systems,
here are some significant differences to most other systems:
- CVS puts all files into a repository ('CVSROOT'). You get a local copy of the repository (or parts of the repository)
to work on the files.
- CVS is capable to work on whole file trees.
- In CVS, a developer does not lock files. CVS uses an optimistic locking mechanism to allow concurent
modification of a project. Whenever you want to save ('COMMIT') your changes from a local copy to the repository,
it checks whether other developers have modified the same sections in a file since you last updated your local copy
from the repository (this is called 'CONFLICT').
If a conflict is detected, CVS puts control back to you and you have to manually merge the two modification into one version. After that
you can try again to commit your changes.
- Words known from other version control systems such as 'Check in' and 'Check out' have a different meaning in CVS.
- The basic working cycle is:
- UPDATE your local copy from the repository to get changes made by other developers.
- EDIT your local copy
- COMMIT your changes to the repository to make them available to other developers.
- during COMMIT you may have to MERGE changes made by other developers, since they have modified the same
files. Merging is done automatically by CVS. If you edited the same section as other developers, you'll have to ressolve a
'CONFLICT' before you can try again to commit the changed file.
- CVS supports common features known from other vc systems such as branches, tagging ('labeling'), ...
- CVS can be run in file-based mode, the repository is mounted as part of your file system.
- CVS can be run in client server mode, in this case your cvs client (=the commandline tools) communicates
using TCPIP with the repository.
For more information on CVS see menu 'Help|CVS Home' and 'Help|CVS Help'.
AnyJ's built in CVS support
AnyJ supports daily used funtions such as UPDATE, COMMIT, DIFF, creating a CVS-project, adding/removing files.
There is no special support to configure CVS (this is textfile based), use the CVS command line tools to do this. You should
read the original documentation of CVS to understand what is going on.
AnyJ does not do any hidden or magic things. All CVS commands executed by AnyJ's GUI-frontend are logged in the
output panel of AnyJ.
Creating a cvs-playground
We create a new workspace to be able to play around a bit. We mount a temporary directory to the new workspace.
Creating a CVS repository using AnyJ
First, it is necessary to create a repository and init it.
After pressing the 'Init' button, you have created a fresh CVS repository. See below on how to edit the config files. Also notice
the CVS-log showing which command has been executed.
Note that you should not edit the files in the repository directory. You edit the configuration files of
CVS by getting them, editing them and commiting the changes to the repository.
Initially getting a CVS project from the repository
Modification of the configuration files of CVS (textfiles) works exactly the same as wortking with any other project ('modules').
The CVS configuration files are a kind of of a 'built-in' project (named 'CVSROOT').
So we are able to demonstrate both in the following section: usage of CVS and some important settings of CVS.
Create a folder (e.g. c:\temp\cvsconfig), select it in the file tree and choose 'Versioning|Initial CVS Checkout' from
the menu. Note that the combobox at the top is empty since this is your first checkout, so AnyJ doesn't know anything
about the repository. Type 'CVSROOT' (==CVS-internal project name for CVS-config files) as project name and press the 'Checkout' button.
Now you made an initial checkout. From now on you can use 'update' and 'commit' on this directory (from within AnyJ use the
'CVS Commit and Update Center').
Often it is a good idea to ingore specific file-types by version control. CVS looks for a file name 'cvsignore' which contains
patterns describing which files should be ignored by version control. We create a file 'cvsignore' ('File|New|Empty File') in
our local copy of the configuration files and add some entries:
Another good idea is to mark some filetypes as binary files.
If a binary file is handled as sourcecode, CVS would probably destroy the binary file by doing keyword substitution and
CR/LF conversion.
This can be configured in the 'cvswrappers' file of CVS.
Now its time to commit the changes we made to the configuration files to the repository. Therefore we select the parent directory
of the CVS config files and choose 'Versioning|CVS Commit and Update Center'
Since we changed one file ('cvswrappers') it appears in the 'Local modified' Listbox. Selecting the file and pressing the commit button
puts this file to the repository.
Since we added one file ('cvsignore') it appears in the 'New/Add/Rem' Listbox. Selecting the file and pressing the add button
schedules the file for addition. It has to be commited to be added 'really' to the repository.
Selecting the 'cvsignore' file in the filetree an selecting 'Versioning|CVS Differences' opens the Diff Viewer. By selecting
one revision in the table at the top, differences to your local version can be viewed. By selecting two revisions in the table
a diff between those revisions can be seen. If only one row is selected, a diff to your local working copy is shown.
Creating a CVS project from existing source
For test purposes we copied some source to our temporary workspace. We select the root of the source-tree and choose
'versioning|Create CVS project'.
Behind the scenes AnyJ does the following:
1. the original directory is renamed (ensure there is no file-lock on this directory
or one of its subdirectories).
2. the renamed directory is imported into the repository
3. the newly created CVS module is updated from the repository to the original directory you selected for import. Therefore
files marked by 'cvsignore' are not present in this directory, you'll have to get them from the renamed original. It is recommended
to backup the renamed directory to another place.
We now create two checkouts of the new project to simulate concurent modification (create folder 'developerA', 'developerB',
use 'Versioning|Initial CVS Checkout').
At first we act as 'developerA' and modify two files by adding some comments. If we now open the 'Commit and Update Center'
on the project root ('DeveloperA') directory we'll see the following:
You can diff your local version against the repository by using the 'Versioning|CVS Differences' as described above.
Developer A commits his changes to the repository by pressing the commit button.
Updating your file tree
Now we act as developer B. We modify some other files, and open the 'Update and Commit Center' on the root directory of
developer B's local version.
Pressing the 'Update' button would update the local version of Developer B from the repository.
Entries in the 'Needs Update' Listbox indicate, that the version of the repository is newer than your local copy. But
we don't update since we want to create a conflict situation.
Merging and Conflict handling
Developer B now changes the same files as developer A
without updating his local copy. We open the update center again (or just press the 'Check Status' button).
We now have created two conflicts (developer A put modifications to the repository, developer b changes the same files, without
getting the actual version from the repository). If we press the 'Update' button, the version of the repository would be copied to
the local version of developer B. The changes of developer B would get lost. Pressing the 'Merge' button merges the changes
from the repository into the local version of developer B (changes of Developer A and Developer B are merged).
The two merged files move from the 'Conflict' Listbox to the 'Locally modified' Listbox.
You are encouraged to review the merged files, since autommerging may produce compile errors. If both developers
modify the same lines in a file, CVS does not merge, but inserts both versions marking them with '>>>>>>>>>>' and '<<<<<<<<'.
The merged files now can be commited to the repository the usual way.