Using CVS together with Debian GNU/Linux 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.  Better yet, read the manual page,
cvs-inject(1).


Oldenburg, 6/2/97                           Joey (joey@debian.org)
                                            / Martin Schulze   /
Mobile,                                     Manoj Srivastava
                                            srivasta@debian.org

$Id: HOWTO,v 1.18 2003/07/03 18:29:40 srivasta Exp $

Note: in the following discussion, the entities in angle brackets <>
are meant to be changed for each case, and 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 -c "[-_a-zA-Z0-9]" "_" > 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). Note: you shall need to set 
		conf_prefix=debian
   In the cvsdeb.conf file (it is not so by default). (note: /etc/cvsdeb.conf 
   or ~/.cvsdeb.conf can be used)

   If more than one person is supposed to use CVS, you have to make
   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

   With the addition of cvs-inject, this process is essentially just
   one line. Assuming you have created a set of files for upload,
   including the orig.tar.gz, the .dsc. and the diff.gz file, just
   say: 

	$ cvs-inject <path to .dsc file>

   and you are done. (The old method was huge, it is now an appendix at
   the end of this message, the only reason it is still there is if
   you are curious about how the guts of this thing works.)

   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
   permissions before you add them to the CVS repository.

   If you have set up CVS as root, and have not set group write
   permissions, you need to create $CVSROOT/debian/<package> (note
   that is you use the debian/ dir you need to set conf_prefix=debian)
   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 fine.

   Also note that in some cases, there have been problems reported in
   creating the package directory despite having set up the modules
   file.  That is to say, sometimes the package is created in
   $CVSROOT/<package> rather than $CVSROOT/debian/<package> as it
   should be.  In this case, you can specify '-Mdebian/<package>'
   explicitly, or manually move the directory in the repository once
   it is created.  (Note: this is probably a bug in CVS, it is being
   investigated.)

   Note that the upstream sources are imported with a -ko (take care
   of binary files), but not the subsequent local changes you may 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 as CVS tags).

4. Prepare a release

   Before you can run some of the Debian commands that will build a
   package, you first have to commit local modifications. Change
   directory to your local checked out package dir (which is where you
   make your modifications), and run:

   $ cvs commit -m <message>

   Next, you use the 'cvs tag' command to tag all the various files in
   the CVS-managed sources as belonging to a release:

   $ cvs tag debian_version_<version | tr -c "[-_a-zA-Z0-9]" "_">-<debian-revision|tr -c "[-_a-zA-Z0-9]" "_">

   Note: you can skip this if you run cvs-buildpackage, in the next
   step, with the '-F' flag.

5. Make a release

   You could either use the cvs-buildpackage mechanism (preferred), or
   an manual export. First test the cvs-buildpackage stuff as a dry
   run in the top level directory of your checked out package (make
   sure that the tags match) like so: 

   $ cvs-buildpackage -d -n -rfakeroot

   If you have a problem, check whether you have configured
   /etc/cvsdeb.conf or ~/.cvsdeb.conf properly. 

 Note:   this   HOWTO  does   not   lead   you   through  setting   up
 cvs-buildpackage, please  ensure that  you understand the  concept of
 the rootdir  (which is a  scratch dir where  cvs-buildpackage exports
 packages  to and builds  them), and  that this  is distinct  from the
 directory where you checkl out the packages and edit things.

   Once you've confirmed that everything looks correct, do the real
   run, either using fakeroot to gain root privileges:

   $ cvs-buildpackage -rfakeroot
   
   or, as an alternative to fakeroot, you can use sudo or super or 
   whatever:

   $ cvs-buildpackage -rsudo

 Note: Wehn the -op option is used, then cvs-buildpackage will first
 unpack the orig.tar.gz, and then apply a diff produced by cvs to
 bring that unpacked tree up-to-date with what is in
 CVS. cvs-buildpackage will make debian/rules executable, but is
 unable to set any other permissions. If you need permissions set
 specially, you will need to use the -Ef<fix_script> option to specify
 a script that handles other permission, or go with the default
 behaviour of exporting everythingh out of CVS. For large packages
 kept in a remote repository, the -op optiona may increase speed
 significantly.

   Or, to do it all manually:

   Check out the package.

   $ cvs export -d $WORKDIR/<package>-<version> \
         -r debian_version_<version|tr -c "[-_a-zA-Z0-9]" "_">-<debian-revision|tr -c "[-_a-zA-Z0-9]" "_"> \
             <package>

   Where WORKDIR is the scratch directory where the package shall be
   exported and built.  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.

   This is easier now with the cvs-upgrade program. Put the
   orig.tar.gz file in the working directory for your site (typically
   /usr/local/src/Packages/<Package name>). The upstream sources
   should be put in 
   <Work directory>/<Package name>_<upstream version>.orig.tar.gz

   $ cvs-upgrade <Package Name> <upstream Version> 

   This shall unpack the original sources, and import them on the
   vendor branch. Since the upgrade may involve conflicts, this is not
   fully automated; cvs-upgrade stops to let you handle any conflicts,
   reminding you resolve conflicts, check things in, and tag the new
   version. 

   Now, we have to incorporate the changes we made into the new
   revision. This is how to do it:

   If you do not have a checked out working directory:	
   $ cd /where/your/source/tree/will/reside
   $ cvs checkout -jsource-dist:yesterday -jsource-dist <package>
   $ cd /where/your/source/tree/will/reside/<package>

   If you already have a working directory:
   $ cd /where/your/source/tree/will/reside/<package>
   $ cvs update -jsource-dist:yesterday -jsource-dist 

   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 -c "[-_a-zA-Z0-9]" "_"> \
                  -jupstream_version_<newversion|tr -c "[-_a-zA-Z0-9]" "_"> \
                   <package>
   Or, in the working directory:
   $ cvs update   -jupstream_version_<oldversion|tr -c "[-_a-zA-Z0-9]" "_"> \
                  -jupstream_version_<newversion|tr -c "[-_a-zA-Z0-9]" "_"> 
   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!

   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:

 A: CVS TAG CONVENTIONS

 |======================================================================|
 |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 -c "[-_a-zA-Z0-9]" "_">            |
 |CVS current tag     | debian_version_<version-revision | \            |
 |                    |                 tr -c "[-_a-zA-Z0-9]" "_">      |
 |======================================================================|

 Examples:
 |======================================================================|
 |                    | 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).

 B: THE OLD METHOD OF INJECTING SOURCES

   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 to the  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 zvvfx <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 -c "[-_a-zA-Z0-9]" "_">

   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 write permissions,
   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 fine.

   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 sometimes 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 -c "[-_a-zA-Z0-9]" "_">-<debian-revision|tr -c "[-_a-zA-Z0-9]" "_"> .

   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>

   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

APPENDIX B: Using pbuilder

 Please refer to the pbuilder documentation to set up pbuilder, and
 create the required base tar file as described. In order to hook that
 pbuilder chroot configuration, all you need to do is either add the
 following line to your ~/.cvsdeb.conf:
 
 conf_buildpackage='pdebuild --auto-debsign --buildresult ../'

 or call cvs-buildpackage with the following option:
% cvs-buildpackage ... -C'pdebuild --auto-debsign --buildresult ../'

 Since the gpg signing is done after the fact, do not set
 conf_rootcommand or conf_dpkg_options=(-pgpg "${dpkg_options[@]}");
 pbuilder handles all this for you.

