Because CVS documentation is so large and sparse, and, becasue it gives you too much freedom on how you use it, often is not that easy to choose the suited life cycle to follow for your CVS project.
This tutorial, first presents a model for project life cycle, and then, shows how it can be implemented using CVS. The reader will be guided to create a dummy project example and perform on it the key steps of such life cycle.
This section describes a typical release policy which includes most of the events a project may consider. Projects vary a lot on their release needs so take it just as an example.
A distributed team of programmers is going to develop an aplication named 'theapp'. They have choosen a 'M.m.r' version numbering schema being:
The team can do differents kinds of releases for the project:
The features to be reached at the next featured version (i.e. '2.4.0') are previously specified. The development team develops towards this millestone. When those features are reached (or abandoned), 'theapp' is released as 'theapp 2.4.0' and the the next millestone (2.5.0 or 3.0.0) starts to be developed.
Once you have started the development of the next featured version (say 2.5.0), you may detect bugs on 2.4.0. You can do the bug fixing on the 2.4.0 base code and then release that as 2.4.1.
The bug fixing can be done on the 2.4.1 line and then applied back to 2.5.0 line or the reverse process, that is fixing on 2.5.0 and applying back to 2.4.1. This mechanism will keep the 2.4.0 user bug fixed without having to wait new featured versions.
Another issue we have to deal are experimental development lines. Experimental development appears when you are trying to implement features that you don't know whether it will be part of any official release.
The same mechanism as for the experimental development is used to develop forward releases. That is, advancing the development of some features that they will not be present on the current featured version but in the next one. For example, you may want to start the implementation of 3.0.0 features while you are still developing 2.5.0
Rationale: One can think that the better way to manage an experiment is outside the repository (CVS) control. This is far from true. By evolving it in a branch you could get the benefits of frequent commits for change tracking, and it is also easier to make diffs and merges with the main trunk.
Notice: Experimental branches should have a very short life. As the code diverges from the main branch, the merge will be harder. To lighten this you should limit the files or folders under experimentation and do frequent merges from the main branch to the experimental one.
Now, I am going to guide you on creating a dummy CVS project and applying to it some of the key steps of the life cycle explained before.
Let's do the development from one featured version to another to be the main CVS branch. We will place CVS tags on snapshots points and create branches whenever a new featured version is reached. Bugfixed version will be performed on such branches and merged back to the main branch if necessary. Experimental development also takes part on a separated branch and it can be merged to the main branch anytime.
After the tutorial your cvs repository will get a look similar to this one:
The tutorial suposes that you have already an available cvs repository and that you have the CVSROOT environment variable pointing to it. It also suposes that you know the basic of CVS usage. That is:
I recommend you to create a directory named 'cvstutorial' or something like that where to place all the stuff of this tutorial. Consider that all the paths are relatives to that directory.
Let's create our dummy project named 'theapp' and let's add it as a new module named 'mymodule' on the cvs.
Note: It's common to put to the same name for the module and the application, but because this can be not your case, we will use different names for you to know which one we are talking about each time.
The steps are:
cvs import -m 'MyApp project started' mymodule theapp_main theapp_unreleasedThe '-m' option specifies a comment for the CVS action. If you don't put this option on any CVS command that requires it a text editor will appear. Using the editor is more easy for real usage.
Once the repository has been created you can forget about the initial directory.
Now we will start the development of 'theapp 1.0.0'.
cvs checkout mymoduleThis will create the directory 'mymodule' containing the working copy.
1.0.0 * First feature Project starting point
cvs commit -m 'First feature added'
Now that you have implemented the first feature it could be a good idea to get a development release.
cvs rtag -Fa theapp_1_0_0_20011124-1 mymoduleUnless '-Fa' options are not needed here, I always use them beause the same command line can be used to move the tag later if you were wrong placing it here.
First of all we will do the 1.0.0 release
cvs rtag -Fa theapp_1_0_0_release mymoduleThis will tag all the files in the main branch of your module with the tag 'theapp_1_0_0_release'.
Now, let's prepare the bug fixing branch for 1.0
cvs rtag -Fa -b -r theapp_1_0_0_release theapp_1_0 mymodule
Now you have two branches: the main branch, ready for the development of the 1.1.0 release and the 1.0 bugfixing branch ready for the development of the 1.0.1 release.
The workcopy is assigned to the main branch so further development on this working copy aplies to the 1.1.0 development. If you want to fix a bug for the 1.0.1 version, you must create a new working copy from the 1.0 branch.
cvs checkout -r theapp_1_0 mymodule
1.0.1 * First fix
cvs commit -m 'Fix: Something weird fixed'
cvs rtag -Fa -r theapp_1_0 theapp_1_0_1_release mymoduleNotice: By adding '-r theapp_1_0' you are tagging only the 1.0 branch.
Hint: This exercise will be more interesting if you perform and commit some development towards 1.1.0 on 'workcopy'.
Now you want to apply the fixes to the main branch.
cvs update -j theapp_1_0This will apply to your working copy all the changes you made on the 1.0 branch from the branching point.
cvs rtag -Fa -r theapp_1_0 theapp_1_0_merged_to_main mymodule
cvs commit -m 'Merged the first fix done for 1.0.1'
Additional fixings on this branch must be merged in a different way. We will use the tag 'theapp_1_0_merged_to_main' placed on the previous merging, as a reference point in order to specify which changes must be applied.
cvs rtag -Fa -r theapp_1_0 theapp_1_0_2_release mymodule
cvs update -j theapp_1_0_merged_to_main -j theapp_1_0This will apply to your working copy all the changes you made on the branch from the branching time.
cvs commit -m 'Merged fixes done for 1.0.2'
cvs rtag -Fa -r theapp_1_0 theapp_1_0_merged_to_main mymodule
Often bug fixes are done on the main branch as part of the normal development, and you want to apply this fixes to an older release.
The easiest way to proceed is to delimitate the changes, using dates or tags. In that case, you can apply the same steps used to apply fixes to the main branch but in the inverse sense, from the main branch to the BugFixed branch.
Just because having delimited changes is not always possible, you have to deal with patching files separately, using file revision numbers. File revisions are very different from application releases. Revisions are the name of differents commitments for a file. So dealing with revision you can isolate the changes done between two commitments of a file.
When you do a development release or an official release, you may want to offer a tarball containing the project files.
Because a working copy done with a ckeckout has, not only the project files but also some CVS administration files, is not a good idea to tarballing from it.
You can use the CVS 'export' subcommand that creates a clean copy of the project files with a concrete tag. So for a official release you will do:
cvs -d $CVSROOT export -r theapp_1_0_0_release -dtheapp mymodule tar cvfz theapp1.1.0-src.tar.gz theapp/*
and for a development relese you will do:
cvs -d $CVSROOT export -r theapp_1_0_0_20020110-1 -dtheapp mymodule tar cvfz theapp1.1.0-20020110-1-src.tar.gz theapp/*
The following table is provided to localize the project management vocabulary used on this tutorial. It is intended to help giving courses based on this tutorial but without abusing of english terms when native terms exists. I will be glad to receive additions, corrections and translations to your own languages.
English | Spanish | Catalan | Your Language Here |
---|---|---|---|
Repository | Repositorio | Repositori | ? |
Sandbox | Copia de trabajo | Còpia de treball | ? |
Millestone | Hito | Fita | ? |
Release | Entrega | Entrega | ? |
Version | Versión | Versió | ? |
Branch | Rama | Branca | ? |
Tag | Marca | Marca | ? |
Policy | Política | Política | ? |
Team | Equipo | Equip | ? |
Life cycle | Ciclo de vida | Cicle de vida | ? |
Feature | Característica, Funcionalidad | Característica, Funcionalitat | ? |
Bug | Fallo | Falla | ? |
Fix | Corrección | Correcció | ? |
Merge | Fusión | Fusió | ? |
Develop | Desarrollar | Desenvolupar | ? |
Snapshot | Instantánea | Instantània | ? |
Path | Ruta, Localización | Camí, Localització | ? |
Commit | Confirmar | Confirmar | ? |
Update | Actualizar | Actualitzar | ? |
Checkout | Crear copia de trabajo | Crear còpia de treball | ? |