<!-- $PostgreSQL: pgsql/doc/src/sgml/cvs.sgml,v 1.45 2007/07/10 23:03:18 tgl Exp $ -->

<appendix id="cvs">
 <appendixinfo>
  <authorgroup>
   <author>
    <firstname>Marc</firstname>
    <surname>Fournier</surname>
   </author>
   <author>
    <firstname>Tom</firstname>
    <surname>Lane</surname>
   </author>
   <author>
    <firstname>Thomas</firstname>
    <surname>Lockhart</surname>
   </author>
   <author>
    <firstname>David</firstname>
    <surname>Fetter</surname>
   </author>
  </authorgroup>
  <date>1999-05-20</date>
 </appendixinfo>

 <title>The <productname>CVS</productname> Repository</title>

 <para>
  The <productname>PostgreSQL</productname> source code is stored and managed using the
  <productname>CVS</productname> version control system.
 </para>

 <para>
  At least three methods, anonymous CVS, <productname>rsync</productname>,
  and <productname>CVSup</productname>,
  are available to pull the <productname>CVS</productname> code tree from the
  <productname>PostgreSQL</productname> server to your local machine.
 </para>

 <sect1 id="anoncvs">
  <title>Getting The Source Via Anonymous <productname>CVS</productname></title>

  <para>
   If you would like to keep up with the current sources on a regular
   basis, you can fetch them from our <productname>CVS</productname> server
   and then use <productname>CVS</productname> to
   retrieve updates from time to time.
  </para>

  <procedure>
   <title>Anonymous CVS</title>

   <step>
    <para>
     You will need a local copy of <productname>CVS</productname>
     (Concurrent Version Control System), which you can get from
     <ulink url="http://www.nongnu.org/cvs/"></ulink> (the official
     site with the latest version) or any GNU software archive site
     (often somewhat outdated). Many systems have a recent version of
     <application>cvs</application> installed by default.
    </para>
   </step>

   <step>
    <para>
     Do an initial login to the <productname>CVS</productname> server:

<programlisting>
cvs -d :pserver:anoncvs@anoncvs.postgresql.org:/projects/cvsroot login
</programlisting>

     You will be prompted for a password; you can enter anything except
     an empty string.
    </para>

    <para>
     You should only need to do this once, since the password will be
     saved in <filename>.cvspass</filename> in your home directory.
    </para>
   </step>

   <step>
    <para>
     Fetch the <productname>PostgreSQL</productname> sources:
<programlisting>
cvs -z3 -d :pserver:anoncvs@anoncvs.postgresql.org:/projects/cvsroot co -P pgsql
</programlisting>

     This installs the <productname>PostgreSQL</productname> sources into a
     subdirectory <filename>pgsql</filename>
     of the directory you are currently in.

     <note>
      <para>
       If you have a fast link to the Internet, you might not need
       <option>-z3</option>, which instructs
       <productname>CVS</productname> to use <command>gzip</command> compression for transferred data.  But
       on a modem-speed link, it's a very substantial win.
      </para>
     </note>
    </para>

    <para>
     This initial checkout is a little slower than simply downloading
     a <filename>tar.gz</filename> file; expect it to take 40 minutes or so if you
     have a 28.8K modem.  The advantage of
     <productname>CVS</productname>
     doesn't show up until you want to update the file set later on.
    </para>
   </step>

   <step>
    <para>
     Whenever you want to update to the latest <productname>CVS</productname> sources,
     <command>cd</command> into
     the <filename>pgsql</filename> subdirectory, and issue:
<programlisting>
cvs -z3 update -d -P
</programlisting>

     This will fetch only the changes since the last time you updated.
     You can update in just a couple of minutes, typically, even over
     a modem-speed line.
    </para>
   </step>

   <step>
    <para>
     You can save yourself some typing by making a file <filename>.cvsrc</filename>
     in your home directory that contains:

<programlisting>
cvs -z3
update -d -P
</programlisting>

     This supplies the <option>-z3</option> option to all <command>cvs</> commands, and the
     <option>-d</option> and <option>-P</option> options to <command>cvs update</>.  Then you just have
     to say:
<programlisting>
cvs update
</programlisting>

     to update your files.
    </para>
   </step>
  </procedure>

  <para>
   <productname>CVS</productname> can do a lot of other things, such
   as fetching prior revisions of the
   <productname>PostgreSQL</productname> sources rather than the
   latest development version.  For more info consult the manual that
   comes with <productname>CVS</productname>, or see the online
   documentation at <ulink url="http://www.nongnu.org/cvs/"></ulink>.
  </para>
  <para>
   <productname>CVS</productname> has deficiencies.  For example,
   generating diffs that add or remove files requires write access to the
   CVS repository.  To work around that deficiency, use
   <productname>cvsutils</productname>, which is packaged in several
   operating systems, and is available in source form at <ulink
   url="http://www.red-bean.com/cvsutils/"></ulink>.
  </para>

  <para>
   Note that building <productname>PostgreSQL</productname> from a CVS
   pull requires reasonably up-to-date versions of <application>bison</>
   and <application>flex</>, which are not needed to build from a distribution
   tarball because the files made with them are pre-built in a tarball.
   Otherwise the tool requirements are the same as building from source.
  </para>
 </sect1>

 <sect1 id="cvs-tree">
  <title><productname>CVS</productname> Tree Organization</title>

  <para>
   <note>
    <title>Author</title>
    <para>
     Written by Marc G. Fournier (<email>scrappy@hub.org</email>) on 1998-11-05
    </para>
   </note>
  </para>

  <para>
   The command <command>cvs checkout</command> has a flag, <option>-r</option>,
   that lets you check out a
   certain revision of a module.  This flag makes it easy to, for example,
   retrieve the
   sources that make up release 6_4 of the module `tc' at any time in the
   future:

<programlisting>
cvs checkout -r REL6_4 tc
</programlisting>

   This is useful, for instance, if someone claims that there is a bug in
   that release, but you cannot find the bug in the current working copy.

   <tip>
    <para>
     You can also check out a module as it was at any given date using the
     <option>-D</option> option.
    </para>
   </tip>
  </para>

  <para>
   When you tag more than one file with the same tag you can think
   about the tag as <quote>a curve drawn through a matrix of file name vs.
   revision number</quote>.  Say we have 5 files with the following revisions:

   <programlisting>
             file1   file2   file3   file4   file5

             1.1     1.1     1.1     1.1  /--1.1*      &lt;-*-  TAG
             1.2*-   1.2     1.2    -1.2*-
             1.3  \- 1.3*-   1.3   / 1.3
             1.4          \  1.4  /  1.4
                           \-1.5*-   1.5
                             1.6
   </programlisting>

   then the tag <literal>TAG</literal> will reference
   file1-1.2, file2-1.3, etc.

   <note>
    <para>
     For creating a release branch, other than a
     <literal>-b</> option added to the command, it's the same thing.</para>
   </note>
  </para>

  <para>
   So, to create the 6.4 release
   I did the following:

<programlisting>
cd pgsql
cvs tag -b REL6_4
</programlisting>

   which will create the tag and the branch for the RELEASE tree.
  </para>

  <para>
   For those with <productname>CVS</productname> access, it's simple to
   create directories for different versions.
   First, create two subdirectories, RELEASE and CURRENT, so that you don't
   mix up the two.  Then do:

<programlisting>
cd RELEASE
cvs checkout -P -r REL6_4 pgsql
cd ../CURRENT
cvs checkout -P pgsql
</programlisting>

   which results in two directory trees, <filename>RELEASE/pgsql</filename> and
   <filename>CURRENT/pgsql</filename>. From that point on,
   <productname>CVS</productname>
   will keep track of which repository branch is in which directory tree, and will
   allow independent updates of either tree.
  </para>

  <para>
   If you are <emphasis>only</emphasis> working on the <literal>CURRENT</literal>
   source tree, you just do
   everything as before we started tagging release branches.
  </para>

  <para>
   After you've done the initial checkout on a branch:

<programlisting>
cvs checkout -r REL6_4
</programlisting>

   anything you do within that directory structure is restricted to that
   branch.  If you apply a patch to that directory structure and do a:

<programlisting>
cvs commit
</programlisting>

   while inside of it, the patch is applied to the branch and
   <emphasis>only</emphasis> the branch.
  </para>
 </sect1>

 <sect1 id="rsync">
  <title>Getting The Source Via <productname>rsync</productname></title>

  <para>
   An alternative to using anonymous CVS for retrieving the
   <productname>PostgreSQL</productname> source tree is
   <productname>rsync</productname>, an incremental file transfer tool.
   A major advantage to using <productname>rsync</productname> is that it
   can reliably replicate the <emphasis>entire</emphasis> CVS repository
   on your local system, allowing fast local access to <command>cvs</>
   operations such as <option>log</option> and <option>diff</option>.
   Other advantages include fast synchronization to the
   <productname>PostgreSQL</productname> server due to an efficient
   streaming transfer protocol which only sends the changes since the last
   update.
  </para>

  <para>
   You can download the CVS repository using this command:
<programlisting>
rsync -avzCH --delete rsync.postgresql.org::pgsql-cvs cvsroot/
</programlisting>
   For full instructions, see the "rsync" section in the 
   <ulink url="http://pgfoundry.org/docman/view.php/1000040/4/PGBuildFarm-HOWTO.txt">
   pgbuildfarm instructions</ulink>.
  </para>
 </sect1>

 <sect1 id="cvsup">
  <title>Getting The Source Via <productname>CVSup</productname></title>

  <para>
   Another alternative to using anonymous CVS for retrieving
   the <productname>PostgreSQL</productname> source tree
   is <productname>CVSup</productname>.
   <productname>CVSup</productname> was developed by
   John Polstra (<email>jdp@polstra.com</email>) to
   distribute CVS repositories and other file trees for the
   <ulink url="http://www.freebsd.org">FreeBSD project</ulink>.
  </para>

  <sect2>
   <title>Preparing A <productname>CVSup</productname> Client System</title>

   <para>
    Two directory areas are required for <productname>CVSup</productname>
    to do its job: a local <productname>CVS</productname> repository
    (or simply a directory area if you are fetching a snapshot rather
    than a repository; see below)
    and a local <productname>CVSup</productname> bookkeeping
    area. These can coexist in the same directory tree.
   </para>

   <para>
    Decide where you want to keep your local copy of the
    <productname>CVS</productname> repository. On one of our systems we
    recently set up a repository in <filename>/home/cvs/</filename>,
    but had formerly kept it under a
    <productname>PostgreSQL</productname> development tree in
    <filename>/opt/postgres/cvs/</filename>. If you intend to keep your
    repository in <filename>/home/cvs/</filename>, then put:

<programlisting>
setenv CVSROOT /home/cvs
</programlisting>

    in your <filename>.cshrc</filename> file, or a similar line in
    your <filename>.bashrc</filename> or
    <filename>.profile</filename> file, depending on your shell.
   </para>

   <para>
    The <application>cvs</application> repository area must be initialized.
    Once <envar>CVSROOT</envar> is set, then this can be done with a
    single command:

<programlisting>
cvs init
</programlisting>

    after which you should see at least a directory named
    <filename>CVSROOT</filename> when listing the
    <envar>CVSROOT</envar> directory:

<programlisting>
$ ls $CVSROOT
CVSROOT/
</programlisting>
   </para>
  </sect2>

  <sect2>
   <title>Running a <productname>CVSup</productname> Client</title>

   <para>
    Verify that
    <application>cvsup</application> is in your path; on most systems
    you can do this by typing:

<programlisting>
which cvsup
</programlisting>

    Then, simply run
    <application>cvsup</application> using:

<programlisting>
cvsup -L 2 <replaceable class="parameter">postgres.cvsup</replaceable>
</programlisting>

    where <option>-L 2</option> enables some status messages so you
    can monitor the progress of the update,
    and <replaceable class="parameter">postgres.cvsup</replaceable> is
    the path and name you have given to your
    <productname>CVSup</productname> configuration file.
   </para>

   <para>
    Here is a <productname>CVSup</productname> configuration file
    modified for a specific installation, and which maintains a full
    local <productname>CVS</productname> repository:

<programlisting>
# This file represents the standard CVSup distribution file
# for the <productname>PostgreSQL</> ORDBMS project
# Modified by lockhart@fourpalms.org 1997-08-28
# - Point to my local snapshot source tree
# - Pull the full CVS repository, not just the latest snapshot
#
# Defaults that apply to all the collections
*default host=cvsup.postgresql.org
*default compress
*default release=cvs
*default delete use-rel-suffix
# enable the following line to get the latest snapshot
#*default tag=.
# enable the following line to get whatever was specified above or by default
# at the date specified below
#*default date=97.08.29.00.00.00

# base directory where CVSup will store its 'bookmarks' file(s)
# will create subdirectory sup/
#*default base=/opt/postgres # /usr/local/pgsql
*default base=/home/cvs

# prefix directory where CVSup will store the actual distribution(s)
*default prefix=/home/cvs

# complete distribution, including all below
pgsql

# individual distributions vs 'the whole thing'
# pgsql-doc
# pgsql-perl5
# pgsql-src
</programlisting>
   </para>

   <para>
    If you specify <option>repository</> instead of <option>pgsql</>
    in the above setup, you will get a complete copy of the entire
    repository at cvsup.postgresql.org, including its
    <filename>CVSROOT</filename> directory. If you do that, you will
    probably want to exclude those files in that directory that you
    want to modify locally, using a refuse file. For example, for the
    above setup you might put this in
    <filename>/home/cvs/sup/repository/refuse</>:
<programlisting>
CVSROOT/config*
CVSROOT/commitinfo*
CVSROOT/loginfo*
</programlisting>
    See the <productname>CVSup</> manual pages for how to use refuse files.
   </para>

   <para>
    The following is a suggested <productname>CVSup</productname> configuration file from
    the <productname>PostgreSQL</>
    <ulink url="ftp://ftp.postgresql.org/pub/CVSup/README.cvsup">
    ftp site</ulink>
    which will fetch the current snapshot only:

<programlisting>
# This file represents the standard CVSup distribution file
# for the <productname>PostgreSQL</> ORDBMS project
#
# Defaults that apply to all the collections
*default host=cvsup.postgresql.org
*default compress
*default release=cvs
*default delete use-rel-suffix
*default tag=.

# base directory where CVSup will store its 'bookmarks' file(s)
*default base=<replaceable class="parameter">/usr/local/pgsql</replaceable>

# prefix directory where CVSup will store the actual distribution(s)
*default prefix=<replaceable class="parameter">/usr/local/pgsql</replaceable>

# complete distribution, including all below
pgsql

# individual distributions vs 'the whole thing'
# pgsql-doc
# pgsql-perl5
# pgsql-src
</programlisting>
   </para>
  </sect2>
 </sect1>
</appendix>
