Codders, resources for programmers by Vokimon

Managing Application Releases with CVS

Managing Application Releases with CVS

Author: David Garcia Garzon / Wiki source

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.

Index

The project releases policy

Version numbers

A distributed team of programmers is going to develop an aplication named 'theapp'. They have choosen a 'M.m.r' version numbering schema being:

Major version number (M):
Will change when the release implies incompatibility with previous version or an important architectural change.
'theapp 2.4.1' -> 'theapp 3.0.0'
Minor version number (m):
Will change when some features have been added but there is no major changes.
'theapp 2.4.1' -> 'theapp 2.5.0'
Release (minor-minor) version number (r):
Will change when only bug fixes have been added without adding any user detectable feature.
'theapp 2.4.1' -> 'theapp 2.4.2'

Kinds of releases

The team can do differents kinds of releases for the project:

Snapshots are named appending an ISO date and a number (the snapshot order within the day) to the official release version that is being developed. For example, if you are developing towards '2.4.1' and you get an snapshot of it, it will be named 'theapp 2.4.1 20011124-1'. Another snapshot the same day will be 'theapp 2.4.1 20011124-2' and so.

Development progress

Achieving millestones
Evolutive development on the main branch

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.

Bugfixing released versions
Corrective development on the bug fixing branch

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.

Experimental development

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.

Experimental branches
Experimental development

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.

An example of CVS implementation

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:

CVS content after some releases
CVS content after some releases.

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.

Create a testing module

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:

It will contain data about the project progress. You will simulate development by adding lines to this file.

 cvs import -m 'MyApp project started' mymodule theapp_main theapp_unreleased

The '-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.

Do some 'development'

Now we will start the development of 'theapp 1.0.0'.

 cvs checkout mymodule

This will create the directory 'mymodule' containing the working copy.

 1.0.0
 * First feature
 
 Project starting point
 cvs commit -m 'First feature added'

Release an snapshot

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 mymodule

Although '-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.

Issue an official release

First of all we will do the 1.0.0 release

 cvs rtag -Fa theapp_1_0_0_release mymodule

This 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.

Fixing a bug on a released version

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'

  • When you are satisfied with the fixes, then, you can create a tag for the release 1.0.1

     cvs rtag -Fa -r theapp_1_0 theapp_1_0_1_release mymodule
    

    Notice: By adding '-r theapp_1_0' you are tagging only the 1.0 branch.

    Merge the fix on the main 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_0
    

    This 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'
    

    Fixing and merging a second fix

    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_0 
    

    This 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
    

    Backporting fixes from the main branch

    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.

    CVS content after some releases
    CVS content after some releases.

    Creating an experimental branch

    TODO

    Exporting tagged releases as source tarballs

    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/*
    

    Other CVS documentation

    It provides detailed information about CVS usage. Most CVS distributions bring it on several formats: 'info' pages, html pages, Windows help file... It is also available online.

    It is the tipical quick manual that is provided to developers that doesn't have to deal with repository management and project management. It is available on my web site as companion of the tutorial you are reading now.

    It describes the operations related to the CVS repository creation and administration. It is available on my web site as companion of the tutorial you are reading now.

    It is a list of advanced issues of CVS that could be helpfull. It is available on my web site as companion of the tutorial you are reading now.

    Multilingual terms glossary

    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.

    EnglishSpanishCatalanYour Language Here
    RepositoryRepositorioRepositori?
    SandboxCopia de trabajoCòpia de treball?
    MillestoneHitoFita?
    ReleaseEntregaEntrega?
    VersionVersiónVersió?
    BranchRamaBranca?
    TagMarcaMarca?
    PolicyPolíticaPolítica?
    TeamEquipoEquip?
    Life cycleCiclo de vidaCicle de vida?
    FeatureCaracterística, FuncionalidadCaracterística, Funcionalitat?
    BugFalloFalla?
    FixCorrecciónCorrecció?
    MergeFusiónFusió?
    DevelopDesarrollarDesenvolupar?
    SnapshotInstantáneaInstantània?
    PathRuta, LocalizaciónCamí, Localització?
    CommitConfirmarConfirmar?
    UpdateActualizarActualitzar?
    CheckoutCrear copia de trabajoCrear còpia de treball?