Using CVS together with Debian packages

This short document is only intended to give a short help in converting packages to CVS management. It is probably only interesting for a few people who are not very familiar with CVS and version management. Also, there is a script in /usr/share/doc/cvs-buildpackage called cvs-pkginit (both the script and the man page are gzipped), which will print out a synopsis of this HOWTO document.

For example, to convert a package foo, version bar1, Debian revision 3, try:

% cvs-pkginit foo bar1 3
and look at the synopsis.
Oldenburg, 6/2/97                           Joey (
                                            / Martin Schulze   /
Mobile,                                     Manoj Srivastava

Note: in the following discussion, the entities in angle brackets <> are meant to be changed for each case, everything else is to be taken literally. For example, if you are talking about a package with upstream version 2.1.82, then <$version> means 2.1.82, and upstream_version_<$version | tr . _> means upstream_version_2_1_82.

  1. Set up CVS
       $ CVSROOT=/where/your/repository/will/be
       $ export CVSROOT
       $ cvs init
       $ mkdir $CVSROOT/debian

    This allows you to separate your Debian packages from anything else in your repository, either currently or in the future. Even if you think you may not need CVS for anything else, it is easier to classify your repository now than to be sorry later (it is a mess moving things around in your repository later).

    If more than one person is supposed to use CVS, you have to makes sure they can actually modify the repository using CVS. Choose a group (or a set of groups) that have access to a part of the repository, and set the permissions:

       # chgrp <archive> $CVSROOT/debian
       # chmod g+ws    $CVSROOT/debian

    This makes sure that members of the archive group are allowed to configure the repository. Now you have to make sure that the correct groups of people are able to modify parts of the repository.

       # mkdir $CVSROOT/debian/<package1>
       # chgrp <group1> $CVSROOT/debian/<package1>
       # chmod g+ws     $CVSROOT/debian/<package1>
       # mkdir $CVSROOT/debian/<package2>
       # chgrp <group2> $CVSROOT/debian/<package2>
       # chmod g+ws     $CVSROOT/debian/<package2>

    As a normal user you should also make your CVS repository public, either by using "-d /where/your/repository/will/be" or by putting such a fragment into your profile.

       $ CVSROOT=/where/your/repository/will/be
       $ export CVSROOT
  2. Use Modules
       # cvs checkout CVSROOT
       # cd CVSROOT
       # vi modules

    In the following, <package> should be the package name as in debian/changelog file.

    Add the following lines, the first is essential, the second can be duplicated and is self-explanatory:

       modules   CVSROOT modules
       <package> debian/<package>
       # cvs commit -m 'Define first modules'
  3. Prepare to use CVS

    Insert your source tree with the following commands (assuming you already have debianized it, and there is on orig.tar.gz file). Note that the upstream sources are imported with a -ko (take care of binary files), but not local changes we make. Please note that epoch numbers are ignored while determining the CVS tag name (they are generally used to change dpkg's opinion of package ordering, and are generally not relevant for CVS tags).

    Change directory to where you have your non-cvs unpacked debianized development source tree, which is what we are trying to inject into CVS (this is not under CVSROOT, generally).

    I REPEAT: In the following, <package> should be the package name as in the debian/changelog file.

       $ cd /where/your/source/tree/resides/
       $ tar zvfx <package>_<version>.orig.tar.gz
       $ cd <package>_<version>.orig
       $ cvs import -ko -m 'Import of bare source' debian/<package> source-dist upstream_version_<version|tr . _>

    You may change the branch tag source-dist to whatever you wish. (The cvs-buildpackage maintainer habitually uses the tag upstream (which is a study in redundancy ;-))).

    If you have set up CVS as root, and have not set group writability, you need to create $CVSROOT/debian/<package> as root and change the group or user ownership in the repository to the particular group or user respectively. The CVS import will print one warning that it cannot create the debian/<package> directory, but that's ok.

    The next step is to check out the whole tree and incorporate all of your changes.

       $ cd /where/your/source/tree/will/reside
       $ cvs checkout <package>

    If you have already created a debianized version but haven't used CVS before you might want to run the following commands to incorporate your changes. After that you should tag that release to be able to check it out sometime later.

       $ cd /where/your/source/tree/resides/<package>-<version>
       $ diff -qrBbw . /where/your/source/tree/will/reside/<package>/ | grep -v CVS
       $ FILES_CHANGED_LOCALLY="<output from above>"
       $ tar cf - $FILES_CHANGED_LOCALLY | tar -C /where/your/source/tree/will/reside/<package> -xvpf -
       $ cd /where/your/source/tree/will/reside/<package>

    Please make sure that the file debian/rules is executable, since this way it shall be executable when exported, and there will be no problems running dpkg-buildpackage on the exported sources. In general, make sure all files have the right permission before you add them to the CVS repository.

       $ cd /where/your/source/tree/will/reside/<package>
       $ cvs add debian <any other files added as well>

    Also, please note that you have to add all additional files manually which should be placed in the repository, especially all files in the debian subdirectory. Also, please note that the cvs add command does not work recursively, so you shall have to manually add whatever subdirectories you have. (cd debian; cvs add *)

    A nice thing is that running cvs update will show you the status of all files in the directory.

       $ cd /where/your/source/tree/will/reside/<package>
       $ cvs update

    The output looks like:

           cvs update: Updating .
           M Makefile
           cvs update: Updating debian
           A rules
           ? example1
    M means modified (has to be committed), A means Added (has to be committed), ? means CVS does not know about the file (needs to be added, maybe?). When you are satisfied that nothing has been missed, and all files have the required permissions, you are ready to commit.
       $ cd /where/your/source/tree/will/reside/<package>
       $ cvs commit -m 'Made all debian changes'
       $ cvs tag debian_version_<version|tr . _>-<debian-revision|tr . _> .

    The new source tree will reside in a directory that doesn't contain the version number. This is no problem as we'll see later.

    If instead you are creating the debian directory from scratch (may be simpler, though less automated):

       $ mkdir debian

    Create all needed debian files and add them into source control.

       $ cvs add debian
       $ cd debian
       $ cvs add *

    After that the next check in will include all your files.

       $ cd /where/your/source/tree/will/reside/<package>
       $ cvs commit -m <some message>
  4. Prepare a release

    Before you can run some of the Debian commands that will build a package you have to check out the module without all the CVS subdirectories. This is done with the `export' command. But first of all you need to check in all your modifications and mark it with a release number.

       $ cvs commit -m <message>
       $ cvs tag debian_version_<version|tr . _>-<debian-revision|tr . _>
  5. Make a release

    You could either use the cvs-buildpackage mechanism (preferred), or a manual export. First test the cvs-buildpackage stuff as a dry run (make sure that the tags match) like so (Should have configured /etc/cvsdeb.conf):

       $ cvs-buildpackage -d -n -rsudo

    Then do the real run with, expecting sudo being a program with which you could gain root access.

       $ cvs-buildpackage -rsudo

    Or, to do it all manually:

    Check out the package.

       $ cvs export -d <package>-<version> -r debian_version_<version|tr . _>-<debian-revision|tr . _> <package>

    Now you can go on with the normal release export mechanism.

    You are done! Congratulations! Here are a few tasks you can do on your source tree:

  6. Remove or rename a file

    The normal way to move a file is to copy OLD to NEW, and then issue the normal CVS commands to remove OLD from the repository, and add NEW to it. (Both OLD and NEW could contain relative paths, for example `foo/bar.c').

       $ mv OLD NEW
       $ cvs remove OLD
       $ cvs add NEW
       $ cvs commit -m "Renamed OLD to NEW" OLD NEW

    This is the simplest way to move a file, it is not error-prone, and it preserves the history of what was done. Note that to access the history of the file you must specify the old or the new name, depending on what portion of the history you are accessing. For example, `cvs log OLD' will give the log up until the time of the rename.

  7. Updating a module with the import command

    When a new release of the source arrives, you import it into the repository with the same `import' command that you used to set up the repository in the first place. The only difference is that you specify a different release tag this time, and a different message.

       $ cd /where/your/source/tree/will/reside/<new source directory>
       $ cvs import -m 'Import new release' debian/<package> source-dist upstream_version_<version|tr . _>

    Now, we have to incorporate the changes we made into the new revision. The best way to do this is to move aside our working copy (based on the older upstream source), and check out a new copy of the package incorporating the changes made in the upstream source. This is how to do it:

       $ cd /where/your/source/tree/will/reside
       $ mv <package> <package>.old
       $ cvs checkout -jsource-dist:yesterday -jsource-dist <package>
       $ cd /where/your/source/tree/will/reside/<package>

    The above command will check out the latest revision of <package>, merging the changes made on the vendor branch `source-dist' since yesterday into the working copy. If any conflicts arise during the merge they should be resolved in the normal way. Then, the modified files may be committed.

    Using a date, as suggested above, assumes that you do not import more than one release of a product per day. If you do, you can always use something like this instead:

       $ cvs checkout -jupstream_version_<oldversion|tr . _> -jupstream_version_<newversion|tr . _> <package>

    In this case, the two above commands are equivalent.

    For files that have not been modified locally, the newly created revision becomes the head revision.

    So, check and see if all the files have been correctly updated. Especially, remember to change the debian/changelog file!

    When you are satisfied, you may remove the old version of the working directory. Be very sure you are removing the right directory!

       $ rm -rf ../<package>.old

    Now you are ready to prepare a release.

  8. Remove the source tree to conserve disk space

    To remove the actual working source tree you are advised not to use rm -rf but use the CVS command that also tests if you have made any local changes that are not committed yet.

       $ cd /where/your/source/tree/will/reside/
       $ cvs release -d <package>
  9. Glossary
       Tags		symbolic names for revisions
       Repository	Archive of source files
  10. Appendix:


     |Upstream Version    | <version>                                       |
     |Debian Revision     | <revision>                                      |
     |Orig tar file name  | package_<version>.orig.tar.gz                   |
     |Debian package name | package_<version>-<revision>_<arch>.deb         |
     |CVS Vendor tag      | upstream_version_<version  | tr . _>            |
     |CVS current tag     | debian_version_<revision | tr . _>              |


     |                    | upstream sources       | Debian only package    |
     |Upstream Version    | 2.76                   | 3.38                   |
     |Debian Revision     | 1.2                    |                        |
     |Orig tar file name  | make_2.76.orig.tar.gz  |                        |
     |Debian package name | make_2.76-1.2_i386.deb | kpkg_3.38_i386.deb     |
     |CVS Vendor tag      | upstream_version_2_76  | upstream_version_3_38  |
     |CVS current tag     | debian_version_2_76-1_2| debian_version_3_38    |

    Note that the epoch numbers are ignored while determining the CVS tag name (they are generally used to change dpkg's opinion of package ordering, and are generally not relevant for CVS tags).