Learning CVS Using KDE’s Cervisia

CVS is a tool to record, manage and distribute different versions of files. In other words, CVS is a version control system. It allows easy collaborative work, as each of the contributors can work in his local copy at the same time, without fear of overriding each other modifications. It allows the recovery of past versions (useful for tracking bugs), the creation of branches (for experimental development or for releases) and more.

Introduction

A CVS repository holds the current files, and every contributor keeps their own local copy, named working folder. One can add his modifications to the CVS main repository (a process called "committing") and/or update his own copy to reflect recent changes made by other contributors. This article will show you how to manage your CVS repository using Cervisia, a easy to use CVS front end.

The main repository can be set to hold your own project, if you wish to use the nice revision control features of CVS. It is easy to set up a local repository, and you will gain the ability to:
  – Easily revert to a previous version
  – Track problematic changes
  – Avoid accidental loss of information
  – Experiment with your work while maintaining a more conservative version
  – Easily view (and review) the changes done by others
But you will get the most from CVS when the majority of the documents or files are saved as text files, because many of the CVS features are related with manipulating text. It is not surprising that version control systems are very popular with programmers and web developers, who work constanlty with text files.

The version control paradigm is very useful for non programmers, since we all do collaborative work at our jobs, in the universities, schools, etc… and complex personal projects can also benefit from its features. But text files saved in binary format (for example, OpenOffice.org and Koffice files are compressed) are unfortunately handled as binary files. Even when using text documents like .html, .rtf and xml, the format information (html tags, etc) restrict the user’s ability to read the raw source of the document, and therefore the raw changes (differences) that CVS outputs.

In an ideal world, the users would have the option to view the content, and not raw information for text and binary files for every CVS feature. But to reach this goal, the applications should be CVS aware, or in other words, able to parse the files and differences in a sensible way. As you can imagine, depending on the file type and application, this feature is not easy to implement. Let’s not drift too much here, discussing these issues is out of scope of this guide.

The objective of this guide is not to cover all CVS functions and commands, but to quickly inform the user how to perform the most common tasks. For instance, you shouldn’t have to memorize cvs command line arguments to help with documentations to an open source project, to download the sources of a program you want or to create and use a repository to enable collaboration features inside your company.

Cervisia is a version control system front-end. It aims to support CVS and other version control system programs in a unified interface. Currently, it offers several features, like conflict resolution, differences and history viewer, status for the working folder files, and support for the most used CVS functions. You can get Cervisia installing the kdesdk package (and the cvs package) using your distribution tools. The version of Cervisia used for this article is the 2.1 version, released with KDE 3.2.

When you are dealing with a CVS repository, the most common actions are:

checkout: copies the repository data creating a local working folder.
update: fetches the latest changes from the repository to your working folder.
difference: creates a file containing the differences between your working folder and the main repository.
add: tells cvs to add the specified file(s) or folder(s) (that already exist on your working folder) to the main repository on the next commit command.
remove: tells cvs to remove the specified file(s) or folder(s) from the main repository on the next commit command.
commit: apply to the main repository the modifications, additions and removals from the working folder.

Cervisia’s options are dictated by its own configuration, not by CVS usual ".cvsrc" file. Cervisia has very sensible defaults, so we won’t need to configure it.

Creating a Local Repository (Optional)

If you plan to do something a bit more sophisticated locally, it is a good idea to use the CVS features. It is easy to set up, and there is not much difference between working with a local repository or with a repository accessed via a network protocol: you make all changes in the working folder and use your favorite CVS tools to update and commit, just like if you were using the network. To create a local repository in the "user" home folder, and to start a "myproject" module for your work, type on any console application:

mkdir /home/user/repository
cvs -d /home/user/repository init
mkdir /home/user/repository/myproject

Now you have a local CVS repository at "/home/user/repository"!

Finding and Setting The Repository Location And The Retrieval Method

There are several methods to access a CVS repository. It may be a local repository, reached via password authentication (:pserver:), secure shell (using :ext:), kerberos authentication (:kserver:) and others. This guide covers local and password authenticated repositories. If you want to use another method, additional information can be found in the cvs info page. The format for the repository location is:

[:method:][[user][:password]@]hostname[:[port]]/path/to/repository

Not all this information (user, password, hostname, port) is always necessary. For instance, if you created a local CVS repository from the example above, the name of the repository would be the path to the repository. (In the example, /home/user/repository).

Open source projects typically offer Anonymous CVS access to their sources. This means you can easily grab the latest sources without asking for a CVS account. Anonymous CVS uses password authentication.If you want to work with an project that offers this kind of access, visit the project homepage and search for the anonymous cvs location and mirrors.

As we will show, you don’t need a CVS account to improve your favorite project. With Anonymous CVS, you can modify your working folder, create a file with the modifications (a diff or patch file) and send them to the project. But if you start working in a regular way either as an artist, documenter, translator, web master, whatever, it is sensible to ask for a CVS account.

Below, we use the main KDE Anonymous CVS repository location in the command examples. Replace it with the location you selected. If you selected a location using pserver as retrieval method, you will need to login and type a password. If you are using an Anonymous CVS mirror, just hit enter when asked for this password. This is required only once per location, because the CVS passwords are stored for later use in the ".cvspass" file in your home folder. If you are using a local repository, you won’t need to login.

Cervisia has the ability to store different repository locations.

– To add a repository location, click the "Repository" menu then the "Repositories…" menu item. .
– The "Configure Access to Repositories" dialog box will pop up.
– Press the "Add…" button. The "Add Repository" dialog should appear.
– Type the repository location in the "Repository" text box. Press "OK". One example is "/home/user/repository". KDE’s main Anonymous CVS repository is ":pserver:[email protected]:/home/kde".
– If your repository’s retrieval method is pserver, you still have to log in. The "Status" column is probably showing "Not logged in".
– Press the "Login" button. If you are using an Anonymous CVS mirror just hit enter. Else, type your password. If everything went well, now the "Status" column should show: "Logged in". .
– If you want, add another location. Cervisia will store as many locations as you like!.

Checkout: Retrieving the Sources

Now that you successfully defined your repository location, it is time to grab the information from the repository to create your working folders. Modules are the name for the main folders inside a CVS server. Cervisia fetches the list of modules for you. Sometimes, more than one module is necessary to perform one task, therefore you will have to checkout multiple times. If you are not sure which modules you need, search for this information first (in your projects web pages).

You should also know the name of the branch you want. Cervisia and the cvs command checkout the main (latest) branch, also known as HEAD, by default. The branch your working folder is based on is called BASE (BASE may be equal to HEAD). Branches are created to allow a module to evolve in different directions. A good real life example of the utility of this feature is the release of a software project. After a major release, there are bugs in the code that should be fixed. At the same time, people want to add new features to the application, creating new bugs. To solve this, CVS lets you fork the development by creating a stable release branch, so people can decide what goes where: bugfixes to both, new features to HEAD resulting in stability to the released branch.

To checkout a module,
– Click the "Repository" menu then the "Checkout…"
menu item.
– The "CVS Checkout" dialog box will pop up. Now select the desired location from the "Repository Drop Down Box".
– Press the "Fetch List" button to obtain the modules list or type the module_name on the "Module Combo Box". If you want to get a specific folder of the module, enter the folder path too. For instance, you can checkout the "myproject" module you created if you are using the local repository example, or you can checkout the "arts" module, the first required to build KDE if you are using the KDE Anonymous CVS location.
– Type the name of the desired branch in the "Branch Tag Edit Box". If the box is empty, Cervisia will checkout the HEAD (main) branch. For example, the current arts stable branch is "ARTS_1_2_STABLE".
– Type the path to the folder where you want to locate the module’s working folder in the "Working Folder Edit Box", or press the "…" button to select it the file dialog.
– Press OK.

Now that you successfully checked out the module, the repository location is stored in your working folder, simplifying further operations between the working folder and the repository. You won’t need to choose the location again if you are working with a module you already checked out.

Updating The Working Folder

Now that you already have a copy of the repository contents in your working folder, the update command synchronizes it with the main repository by transferring the bits and pieces that changed.

You can also "update" your working folder to any branch, tag, or date, even from the unstable to the stable. For instance, suppose you were testing KDE 3.2 release candidate (during feature freeze), using the head branch. But in January 2004, the KDE_3_2_BRANCH was created, and HEAD was open again for commits. To continue testing KDE 3.2, you should update to the KDE_3_2_BRANCH, otherwise you will be testing KDE unstable. Later in the release cycle, you can easily go back to the HEAD branch, no problem!

Cervisia names the working folder “sandbox”. To update a module / working folder, do the following actions.

– Click the "File" menu then the "Open Sandbox…" menu item.
– Select a working folder / module in the file dialog.
– Click the "File" menu then the "Update" menu item, or simply press the Update button in the toolbar.
– Note that Cervisia performs menu and toolbar actions only to selected files and folders. If you select a file, only it will
be updated, but if you select a folder, the whole folder will be updated if you checked the "Update Recursively" check box in the Settings Menu, Cervisia will update all subfolders too.

To update the working folder to a branch.

– Click the "File" menu then the "Open Sandbox…"
menu item.
– Select the desired working folder / module in the file dialog.
– Click the "Advanced" menu then the "Update to Tag/Date…" menu item.
– The "CVS Update Dialog" will pop up.
– Press the “Fetch List” button under the "Update to Branch".
– Select the correct branch in the "Update to Branch" dropdown combo box.

– Press OK.

Alternatively, you can update the working directory to any date (useful for tracking problems), or tag. Tags are marks for a specific version of the repository, like a release. So if you want to get the exact same code of a release, you can do so by updating to that release tag.

Update Output and File Status

Using either the cvs command or Cervisia, while you update the working folder, you will see messages from CVS telling you what it is doing, and giving updated information on the status of each file. In Cervisia, you can see the cvs command output (for all actions, not only for update) in the lower of the main window.

P: libmedia.cpp
U: process.h
M: README
C: same_dialog.ui
?: TODO
A: new_dialog.ui
R: old_dialog.ui

The meaning of the first letter in these lines is:

"P" means that CVS has "patched" the file with a newer version, or in other words, downloaded only the differences between the two files, and applied it to make the two versions identical. "U" means essentially the same thing, except that CVS decided it would be more efficient to bring the file "update-to-date" by downloading the entire file rather than patching. This happens for all new files added from the repository to your working folder.
"M" means you have a modified version of the file in your working folder. This happens for all the files you modify: CVS respectsyour modifications and does not try to undo them. CVS will add to the files in your working folder modifications from other developers if they apparentlydon’t conflict with each other.
"C" means there are conflicts in a file you modified: while you where working on the file, another developer committed
some changes that affect the same lines you were working with. You will have edit the file and merge the modifications in a meaningful way. To avoid any loss of information, CVS saves an unmodified version of the file with the format ".#name_of_the_file . number_of_the_version_you_modified". Example: if you modified the file same_dialog.ui version 1.5, the backup file will be named ".#same_dialog.ui.1.5"..
"?" means there is a file in your working folder, that is not in the CVS repository and that is not in the list of files to be ignored. CVS leaves these files alone, but warns you that they are not categorized neither as part of the repository or as files to ignore.
"A" means you explicitely told CVS to add the file to the list of files you think are part of the project, but you did
not commit yet to upload it to the main repository. "R" means you told CVS to remove the file from the repository, but did not commit to perform this action. We will see more about this in the Adding, Removing and Committing section. These actions are only meaningful when you have your own CVS account, and therefore can commit.

Using the cvs update command output, it is difficult to quickly visualize the status of the files. Cervisia displays this information in a friendlier way: integrating the status of the files with the main window. Cervisia checks the status of the files automatically
after each update, but you also can use the "Status" menu item under the "File Menu" or you can press "F5" to know the status of the files without updating the working folder.

The files can be classified in the following states, regarding the differences between the working folder and the repository.

Up to date: The files are the same.
Locally Modified: The version in your working directory is different from the repository because you modified it.
Locally Added: You have explicitely told CVS that the file is part of the project, but did not commit it yet to the repository.
Locally Removed: You have explicitely told CVS that the file is not part of the project anymore, but did not commit it yet to the repository.
Needs Update and Need Patch: There is a newer version of the file in the repository.
Conflict: You made modifications to the file but did not commit and another developer committed changes to the same files.
An update won’t be sufficient to merge the files, as the changes conflict. You will have to edit the file to solve the conflict before committing your changes.

Creating Patches, Viewing Differences and Applying Patches to Your Working Folder

Even if you don’t have a CVS account for any given project, this does not restrict your ability to contribute to it. You can create patches against the repository. A patch is the difference between two files or group of files in a standard format that allows someone else to apply it to his working folder and get your modifications in his files.

Remember to give a name for the patch that express the changes and the name of the original files. Suppose you proofed a text file in the repository. A good file name for the patch is file_name-proofread.diff, where file_name is the name of the original file. (It is also standard procedure to proof the text you modified and test the modifications before you send them in the form of a patch).

Currently, one difference file is generated for all modifications in the working folder, recursively. This means you create a single patch for all your the changes against the repository.

– Open the sandbox (working directory) where the modifications are located.
– Click the "Advanced Menu", and then the "Create patch
Against the Repository" menu item.
– KDE’s File Dialog will pop up. Type the name of the patch file you
will create, (for instance, press OK, and you created the patch!..

Cervisia’s built in difference viewer is user friendly and complete, making viewing your changes a breeze.

– Open the sandbox (working directory) where the files are located.
– In Cervisia’s Main Window, select the modified file.
– Click the "View Menu", and then the "View Difference to
repository (BASE)" menu item. (You can also right click the file
to access this menu item).
– Cervisia’s difference viewer will pop up, enabling you to browse
the differences. You can easily go forward to the next difference
and backwards, by scrolling down and up or pressing the
"<<" or ">>" buttons.

You can also apply patches to your working folder Suppose you reported a bug. The developer may post a patch and ask you to test it to see if it solves your problems. You will have to apply the patch and recompile the application in order to test it. To apply the patch to a file or group of files, you can use the "patch" command line utility, that is part of the GNU Diffutils. To make sure the patch command will succeed, please apply the patch to the correct target, being a folder (and all subfolders and files) or a file. If you are not sure which is the target, open the patch file in any text editor, and look in the beginning of the file. The Kompare program in the kdesdk module also shows the patch target.

# To apply a patch, first move to the folder that contains the target file.
cd path/to/target/folder
patch <path_file

The patch command output will tell you if the merge was successful. For more information about the patch command, please type in a console application man patch or info patch.

Resolving Conflicts

A conflict occurs because while you where working on the file, another developer committed some changes that affect the same lines you were working with. You will have edit the file and merge the modifications in a meaningful way.

CVS marks the conflicting changes in the following manner:

<<<<<<<
Changes in your working folder
=======
Changes in the Repository
>>>>>>> revision_number

You should replace this whole block with the new merged version. Then you can commit or create a patch against the repository.

Fortunately, Cervisia offers a nice interface for handling these conflicts. This does not mean that you will never need to manually edit the files, but eliminate the need to do so for the trivial conflict resolution.

– Open the sandbox (working directory) where the files are located.
– In Cervisia’s Main Window, select the conflicting file.
– Click the "View Menu", and then the "Resolve…" menu item. (You can also right click the file to access this menu item).
– Cervisia’s conflict resolver will pop up.
– You can easily go forward to the next conflict and backwards by pressing the "<<" or ">>" buttons.
– The "A" button in the bottom left part of the dialog keep your modifications and remove the repository modifications for that specific conflict (they can be more than one per file).
– The "B" button does the opposite: keep the repository modifications and remove your modifications.
– The "A+B" button merge the modifications using yours as the base.
– The "B+A" button merge the modifications using the repository modifications as the base.
– The edit button lets you manually merge the modifications.

The Commit Process: Changing, Adding and Removing Files and Folders

Committing Your Changes to The Repository

In CVS language, to commit means to perpetrate the changes from your working folder to the repository. In order to commit to a network repository, you must have a CVS account, and you will need to retrieve the involved modules using this account. Anonymous CVS does not allow committing. It is strongly recommended that you read the project guidelines for developers and contributors before committing. For instance, the KDE project has a Developer’s FAQ and a CVS Commit Policy Page to guide new contributors.

To commit a file or group of files to the repository, do the following actions.

– Click the "File" menu then the "Open Sandbox…"
menu item.
– Select a working folder / module in the file dialog.
– Select the files or folders you want to commit.
– Note that Cervisia performs menu and toolbar actions only to selected files or folders. If you select a file, only it will be committed, but if you select a folder, all modified files in the folder will be committed (if you checked the "Commit & Remove
Recursively" check box in the Settings Menu, Cervisia will commit all modified files from the subfolders too).
– Click the "File" menu then the "Commit…" menu item, or simply press the Commit (Up) button in the toolbar.
– The Commit Dialog will pop up.
– Type the log message describing your changes. If you want to use one of your older log messages, Cervisia stores them in the "Older messages" dropdown.
– Click OK.

Adding and Removing Files

CVS only recognize files as part of the working directory after you tell CVS explicitely to do so. This is a smart policy, because there are a wide range of automatically generated files, like backups, binary files resulting from a build process, etc… that should not be uploaded with the sources, because they are easily generated derivatives. So let’s suppose you created or copied a new file to your working folder: first you have to add it to the positive list of files CVS will not ignore. Than you can commit it. Likewise, to remove a file from the repository you shouldn’t only delete it, since CVS will create it again on the next update! You have also to tell CVS to remove it from the repository. The specified files will be removed only after you commit them.

It is also important to keep in mind that CVS was designed to handle text files. Many features, like revision merging, creating differences in a readable form, etc… are only performed to text files. This does not mean you cannot use CVS to keep binary files, it just means you have to tell CVS it is a binary file, otherwise the file may get corrupted.

To add files in a module / working folder to the repository, do the following actions.

– Click the "File" menu then the "Open Sandbox…" menu item.
– Select a working folder / module in the file dialog.
– Select the files you want to add. Note that the add command is not recursive.
– Click the "File" menu then the "Add to repository…" menu item, if the files are text files or "Add binary…" if they are binary files.
– The Add Dialog will pop up.
– Click OK.
– Now you have to commit these files to the repository, to actually add them.

To remove files in a module / working folder and in the repository, it is almost the same:

– Click the "File" menu then the "Open Sandbox…" menu item.
– Select a working folder / module in the file dialog.
– Select the files you want to remove.
– Click the "File" menu then the "Remove from Repository…" menu item.
– The Remove Dialog will pop up.
– Click OK.
– Now you have to commit these files to the repository (using the method described above) to actually remove them.

Conclusion

As you can see, working with CVS is not hard at all. There are a few unintuitive concepts, like handling differently text and binary files and having to perform a two steps operation to add and remove files, but that’s all.

And Cervisia makes it even simpler, by adding nice interfaces to checking out files, viewing differences, resolving conflicts and checking the status of the files in the working folder.


The author want to thanks the contributions of Gary Cramblitt, author of the “Building the KDE Source Newbie Guide” and the corrections of Christian Loose, Cervisia maintainer.


About the Author:
Carlos Leonhard Woelz is a Quanta Plus sponsor, and is currently involved with the KDE Quality Team, a program to improve the level of quality of KDE applications by lowering the barriers to contribute to the project and consequently attracting new contributors, developers and non developers.

22 Comments

  1. 2004-02-20 7:35 am
  2. 2004-02-20 7:44 am
  3. 2004-02-20 7:47 am
  4. 2004-02-20 8:23 am
  5. 2004-02-20 9:44 am
  6. 2004-02-20 10:14 am
  7. 2004-02-20 11:45 am
  8. 2004-02-20 12:16 pm
  9. 2004-02-20 12:20 pm
  10. 2004-02-20 12:57 pm
  11. 2004-02-20 3:27 pm
  12. 2004-02-20 3:29 pm
  13. 2004-02-20 3:51 pm
  14. 2004-02-20 4:15 pm
  15. 2004-02-20 5:27 pm
  16. 2004-02-20 5:40 pm
  17. 2004-02-20 7:47 pm
  18. 2004-02-20 7:49 pm
  19. 2004-02-22 5:18 pm
  20. 2004-02-23 12:30 pm
  21. 2004-02-23 1:11 pm
  22. 2004-02-23 2:58 pm