Found at: http://publish.ez.no/article/articleprint/36/

Version Control management with CVS - Part 2



CVS is a Version Control System which helps multiple developers manage software projects. In this second part I'll show the basics of committing your changes to a project, adding new files, creating patches and explaining version numbers. For those of you who missed the first part you can read it here.

Comitting

Committing, the second of the two widely used CVS commands (the first is updating), takes care of sending all your local changes to the CVS repository. To be able to commit your changes you need write access to the CVS repository, so any anonymous logins won't work.

Before I start explaining the commit command I'll tell you a little secret that will make your committed work so much more appreciated. The scenario is this.

You're working on a project and have successfully enhanced it by adding your own super code locally. You've tried out your personal changes several times and everything seems to work OK. Now you probably want to send these changes to the repository so you perform the commit command. However while you were busy creating your changes somebody else has done some other changes to the project which directly affects your work. If you were to commit you changes as it is now one of three things could happen:

1. No conflicts or compile problems occur for other co-developers.
2. No conflicts occur but the code will not compile with the latest CVS version.
3. Conflicts occur because you and one or more co-developers have modified the same code lines as you.

If number 3 happens you won't be able to commit because you don't have the latest version, and you cannot commit a lower version over a newer version, this means you have to update your local CVS repository.
Number 1 is harmless since it works for all parts, but number 2 is something you want to avoid since it might break code. So how do you avoid number 2 you ask?

As a rule of thumb you should always, and I mean always, update before you do a commit. Why so? Well if you have the latest version locally and your new code still works, you can rest assure it will work for your co-developers as well(unless you consider conflicts).

With that said I'll continue with explaining how to commit.

Committing is done with the CVS command commit. You do this with:

cvs commit

or short

cvs com

another short form

cvs ci


Remember that you can use the global options you learned in part 1, for instance the -z3 might be useful.

When the command is run CVS will start looking trough your directories, starting in the current and recursing trough subdirectories, finding files which are modified locally. When this is done CVS will ask you for a message regarding the changes you have made, this is done with the editor set in the CVSEDITOR variable (this is explained in part 1), when you save this message and quit the editor the changes will be sent to the repository with the change message.
If you want to abort the commit you can do this by quitting the editor without saving.

However committing this way is not what will make you popular with your co-developers, this is because your change message will be appended to all modified files. For instance your bug fix in one of the code files has no use being in the README file. This means that you should commit each file separately (or at least groups of files which belong together). To do this you supply the file(s) after the commit command, for instance:

cvs commit README

which will only commit changes for the README file.

Or using several files

cvs commit qaregexp.cpp qaregexp.hpp

which will commit changes for both the C++ body and header files (C++ body and header files are closely related).

The message itself can also be specified directly to the CVS program by using the -m option. For instance

cvs commit -m "Changed the mail addresses to my new one" README


The last word on committing is that you write sensible messages. Messages saying, fixes, stuff or other meaningless sentences are useless, spend some time writing the messages and make sure you get all changes in it. And remember the spellchecker is not your enemy.

Adding files

Being able to do changes and committing them is now possible, but how do you add new files to the repository? Thanks to marvelous new technology this is possible with a few simple steps.

The command for adding new files is add. For instance to add the installation file you do:

cvs add INSTALL


You can also add sub-directories, for instance if src is a sub-directory do:

cvs add src

But remember only the sub-directory will be added not the content, you need to add these yourself afterwards.

If you have more than one file to add you can specify them all to the command line, to add all .cpp files, the FAQ and the installation file do:

cvs add *.cpp FAQ INSTALL


After the file(s) are added you need to commit the changes, this allows you to write an nice initial message explaining why you added it.

There is one important thing you should know about files in the CVS repository, and that is that they never disappear (they never get smaller either). It will disappear from the local copy and the local files may look smaller, but in the real CVS repository all changes you, and your co-developers, have ever committed will be present.
At first this might seem strange, but consider what would happen if you wanted an earlier version of the project and the files didn't exist anymore? Well it wouldn't work. That is why CVS keeps all information sent to it.

With this said you probably wonder how you remove files from CVS. As always you do this with a CVS command and this time it's called remove.

For instance to remove the installation file we added earlier do:

cvs remove INSTALL

But remember CVS will not remove the file in the repository unless it is removed locally first(it can be renamed/moved too if you want to keep it), the file will now be marked as removed.
To perform the removal you have to do a commit (with a nice comment). The file will then be moved, in the repository, from the current directory to a sub-directory called Attic. All removed files will be put in the Attic.

Creating patches

The two previous pages explained how you can commit your changes and add files to a CVS repository if you have the proper write access. But what if you only have anonymous access and want the changes you have made locally to appear in the CVS repository?
Luckily for you there is one option and that is to create a patch and send it to someone with write access. But don't count on the changes to appear at all, it's entirely up to each developer to use the patches submitted by you. To help on this you should always send a detailed description on what you have changed and ask politely.

To create a patch you have to find out what the difference between your local copy and the CVS repository is. This is done with the CVS command diff, the usual option to use for diff is -u which outputs the difference in a unified format. You can also use the -c option which uses the context output format. So we want to do:

cvs diff -u

After a while it will start spitting out lots of text explaining the differences, to put this into a file we use redirection.

cvs diff -u >my.patch

This creates a file called my.patch which can be emailed to the developer, and hopefully will be incorporated into the CVS tree.

Version numbers

You might have noticed when working with a CVS repository that each file has a given number. For instance it might have 1.0, 1.2 or 1.8, the number is what's commonly called a revision number, which gives the user a clue on how many times the file has been modified. Files which are frequently modified will have high numbers, for instance 1.50.
Revision numbers are not be confused with program version. A program with version 1.4.2 might have files with varying revision numbers.

A version number will always have an even number of period-separated decimal integers. So a revision number of 1.3.2.2.4.5 is allowed. Revision 1.1 is by default the first version of a file. When revision numbers have more than one period it is part of a branch, branches will be explained in a later part. Normally there's no reason to care about revision numbers as CVS will automatically increase them internally. However sometimes you might want to change the revision on all your files when you have released major version of your software.
Note that using tags, which will be explained in a later part, is a much better way to handle releases.

So if you wanted all files to have a new revision number you would use the commit command with an option. For instance

cvs commit -r 3.0

will bring all your files up to revision 3.0. Revision numbers can only be increased, so trying to set a revision number of 1.3 when other files have revision 1.5 will fail.

Conclusion

You should now have the knowledge to perform changes to projects, whether good or bad, with the use of CVS. You should also know how to create patches in case you just have anonymous read access. So why not help out your favorite Open Source project and make the world a better place.

The next part in this series will go into the details of CVS repository management, that is creating a new CVS repository, importing sources and handling CVS modules. For those of you who simply cannot wait I recommend you either check out the man pages for CVS, read it's PostScript version (usually located in /usr/doc/), the online manual or the PDF document

Any comments on how to improve this article or future parts is very welcome.


| Back to normal page view |