LDP/LDP/ref/docbook/CVS-BestPractices/cvs-bestpractices.xml

1144 lines
41 KiB
XML

<?xml version="1.0"?>
<!-- $Id$ -->
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!-- Document version -->
<!ENTITY DOCVERSION "0.7">
<!-- File Includes -->
<!ENTITY GFDL-FILE SYSTEM "gfdl.xml">
<!-- Text substitution macros -->
<!ENTITY CVS "Concurrent Versions System">
<!ENTITY OPENSOURCE "Open Source">
<!ENTITY CVSAB "CVS">
<!ENTITY SCMAB "SCM">
<!ENTITY SCM "Software configuration management">
<!ENTITY MYEMAIL "vivekv at yahoo dot com">
<!-- All the best practices described in one place.... -->
<!ENTITY section2-useguiclient "Use GUI &CVSAB; client">
<!ENTITY section1-devsandbox "Developer Sandbox">
<!ENTITY section2-clockinsync "Keep System clocks in Sync">
<!ENTITY section2-dontshare "Do not share the sandbox">
<!ENTITY section2-syncup "Stay in sync with the repository">
<!ENTITY section2-workinside "Do not work outside the sandbox">
<!ENTITY section2-cleanupatcompletion "Cleanup after Completion">
<!ENTITY section2-checkin "Check-in Often">
<!ENTITY section1-serverconfig "&CVSAB; Server Configuration">
<!ENTITY section2-accesscontrol "&CVSAB; access control">
<!ENTITY section2-scripting "Server side scripting">
<!ENTITY section2-notification "Server Notification">
<!ENTITY section1-branchmerge "Branching and Merging">
<!ENTITY section2-branchowner "Assign ownership to Trunk and Branches">
<!ENTITY section2-tagrelease "Tag each release">
<!ENTITY section2-branchatrelease "Create a branch after each release">
<!ENTITY section2-bugfixbranches "Make bug fixes to branches only">
<!ENTITY section2-patchesfrombranches "Make patch releases from branches only">
<!ENTITY section1-chgpropagation "Change Propagation">
<!ENTITY section2-mergebugfix "Merge branch with the trunk after release">
<!ENTITY section1-softwarebuild "Software Builds">
<!ENTITY section2-bebo "Build Early and Build Often">
<!ENTITY section2-automate "Automate build Process completely">
<!ENTITY section2-ensurecheckin "All necessary files must be checked-in before build">
<!ENTITY section1-instprocess "Institutionalize &CVSAB; in the Organization">
<!ENTITY section2-chngmgmt "Implement Change Management Process">
<!ENTITY section2-objectives "Make &CVSAB; Usage part of Objectives">
<!ENTITY section2-metrics "Collect metrics on &CVSAB; usage">
]>
<article>
<title>CVS Best Practices</title>
<articleinfo>
<author>
<firstname>Vivek</firstname>
<surname>Venugopalan</surname>
<affiliation>
<address><email>&MYEMAIL;</email></address></affiliation>
</author>
<revhistory>
<revision>
<revnumber>0.7</revnumber>
<date>2005-10-15</date>
<authorinitials>vv</authorinitials>
<revremark>A bunch of minor fixes as suggested by readers.</revremark>
</revision>
<revision>
<revnumber>0.6</revnumber>
<date>2002-09-10</date>
<authorinitials>vv</authorinitials>
<revremark>Added content related to tagging and daily builds. Changed
Linuxdoc URLs to tldp. Fixed stale links and added other corrections
suggested by readers.</revremark>
</revision>
<revision>
<revnumber>0.5</revnumber>
<date>2002-08-25</date>
<authorinitials>vv</authorinitials>
<revremark>Fixed some more errors in the document and added references to
other CVS sources and some server side scripting</revremark>
</revision>
<revision>
<revnumber>0.4</revnumber>
<date>2002-03-10</date>
<authorinitials>vv</authorinitials>
<revremark>Added new email address, Added an example flow to show how the
practices help</revremark>
</revision>
<revision>
<revnumber>0.3</revnumber>
<date>2001-12-06</date>
<authorinitials>vv</authorinitials>
<revremark>Grammatical errors cleanup</revremark>
</revision>
<revision>
<revnumber>0.2</revnumber>
<date>2001-11-27</date>
<authorinitials>vv</authorinitials>
<revremark>Incorporated first round of feedback and
some minor fixes</revremark></revision>
<revision>
<revnumber>0.1</revnumber>
<date>2001-11-20</date>
<authorinitials>vv</authorinitials>
<revremark>Created</revremark>
</revision>
</revhistory>
</articleinfo>
<abstract>
<para>
<indexterm>
<primary>CVS Best Practices</primary>
</indexterm>
This article explores some of the best practices that can be adopted
while using CVS as the configuration management tool in your software
projects.
</para>
</abstract>
<sect1 id="section1-intro">
<title>Introduction</title>
<blockquote>
<attribution>Henry David Thoreau (1817-1862)
</attribution>
<literallayout>Men have become the tools of their tools.
</literallayout>
</blockquote>
<para>This article outlines some of the best practices that can be adopted
when &CVS; is used as the configuration management tool in your software
project. </para>
<para>&CVS; (&CVSAB;) is an <ulink
url="http://www.opensource.org">&OPENSOURCE;</ulink> configuration management
tool that is now being looked at seriously by many commercial organizations as
a viable alternative to other commercial &SCM; tools. </para>
<para>This spotlight on &CVSAB; has led to the inevitable question of best
practices for deploying &CVSAB; as the backbone &SCMAB; tool for large
software development projects. Having answered this question many times
verbally as a bunch of <quote>gotchas</quote> on &CVSAB;, it was time to put
down on paper some of the best practices that will work well for
&CVSAB; based projects. </para>
<note> <para>This paper assumes that the reader is familiar with the
fundamentals of software version control. Including features like
branching, merging, tagging (labelling) etc., offered by modern version
control tools such as &CVSAB; </para>
<para>Further, This paper is not an introduction to &CVSAB; and its usage. There are
excellent articles available on the net for the same. This paper assumes
that the reader is familiar with &CVSAB; commands and is looking at
deploying &CVSAB; in his or her organization. Some of the popular
&CVSAB; related links that can provide &CVSAB; education are. </para>
<orderedlist>
<listitem>
<para>The <ulink url="http://ximbiot.com/cvs/wiki/index.php?title=Main_Page">&CVS; site</ulink> where
current informaton about CVS is available. Including the <ulink
url="http://ximbiot.com/cvs/wiki/index.php?title=Cederqvist">&CVSAB; manual</ulink>.
</para>
</listitem>
<listitem>
<para>Karl Fogel's book, <ulink url="http://cvsbook.red-bean.com">Open Source Development with
CVS</ulink> is available online.
</para>
</listitem>
</orderedlist>
</note>
<!-- Section2: copyright -->
<sect2 id="copyright">
<title>Copyright Information</title>
<para> This document is Copyright &copy; 2001 Vivek Venugopalan. Permission
is granted to copy, distribute and/or modify this document under the terms of
the <link linkend="gfdl"><citetitle>GNU Free Documentation
License</citetitle></link>, Version 1.1 or any later version published by the
Free Software Foundation with no Invariant Sections, no Front-Cover Texts, and
no Back-Cover Texts. A copy of the license can be found in <xref
linkend="gfdl"/>. </para>
<para> This document may be reproduced and distributed in whole or in part, in
any medium physical or electronic, as long as this copyright notice is
retained on all copies. Commercial redistribution is allowed and encouraged;
however, the author would like to be notified of any such distributions.
</para>
<para> All translations, derivative works, or aggregate works incorporating
this document must be covered under this copyright notice. That is, you may
not produce a derivative work from this document and impose additional
restrictions on its distribution. Exceptions to these rules may be granted
under certain conditions; please contact the author at the address given
below. </para>
<para> In short, we wish to promote dissemination of this information through
as many channels as possible. However, we do wish to retain copyright on the
document, and would like to be notified of any plans to redistribute the same.
</para>
</sect2>
<!-- Section2: disclaimer -->
<sect2 id="disclaimer"> <title>Disclaimer</title>
<para> No liability for the contents of this document can be accepted. Use
the concepts, examples and other content at your own risk. As this is a new
edition of this document, there may be errors and inaccuracies that may of
course be damaging to your system. Proceed with caution, and although this is
highly unlikely, the author(s) do not take any responsibility whatsoever.
</para>
<para> All copyrights are held by their respective owners, unless specifically
noted otherwise. Use of a term in this document should not be regarded as
affecting the validity of any trademark or service mark. </para>
<para> Naming of particular products or brands should not be seen as
endorsements. </para>
<para> You are strongly recommended to take a backup of your system before
major installation and backups at regular intervals. </para> </sect2>
<!-- Section2: newversions-->
<sect2 id="newversions">
<title>New Versions</title>
<para> This document is Version : &DOCVERSION;. </para>
<para> The latest version of this document can be obtained from (In the order of latest version availability) </para>
<orderedlist>
<listitem>
<para>
<ulink url="http://www.sanchivi.com/cm/cvs-bestpractices/index.html">My website</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="http://tldp.org/REF/CVS-BestPractices/html/index.html">The linux documentation project</ulink>
</para>
</listitem>
</orderedlist>
</sect2>
<!-- Section2: credits -->
<sect2 id="credits">
<title>Credits</title>
<para>The list of people who have provided information and correction for this
paper in no particular order are.
<orderedlist>
<listitem> <para>Jens-Uwe Mager </para> </listitem>
<listitem> <para>Jorgen Grahn </para> </listitem>
<listitem> <para>Thomas S. Urban </para> </listitem>
<listitem> <para>Cam Mayor </para> </listitem>
<listitem> <para>Sally Miller</para> </listitem>
<listitem> <para>Niels Jakob Darger</para> </listitem>
</orderedlist>
</para>
</sect2>
<!-- Section2: feedback -->
<sect2 id="feedback">
<title>Feedback</title>
<para> Feedback is most certainly welcome for this document. Without your
submissions and input, this document wouldn't exist. Please send your
additions, comments and criticisms to the following email address :
<email>&MYEMAIL;</email>. </para>
</sect2>
</sect1>
<sect1 id="section1-focusareas">
<title>Focus Areas</title>
<para>The focus areas for best practice are
</para>
<orderedlist>
<listitem>
<para><xref linkend="section1-guitools"/>
</para>
<itemizedlist>
<listitem>
<para><xref linkend="section2-useguiclient"/>
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><xref linkend="section1-devsandbox"/>
</para>
<itemizedlist>
<listitem>
<para><xref linkend="section2-clockinsync"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-dontshare"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-syncup"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-workinside"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-cleanupatcompletion"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-checkin"/>
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><xref linkend="section1-serverconfig"/>
</para>
<itemizedlist>
<listitem>
<para><xref linkend="section2-accesscontrol"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-scripting"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-notification"/>
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><xref linkend="section1-branchmerge"/>
</para>
<itemizedlist>
<listitem>
<para><xref linkend="section2-branchowner"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-tagrelease"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-branchatrelease"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-bugfixbranches"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-patchesfrombranches"/>
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><xref linkend="section1-chgpropagation"/>
</para>
<itemizedlist>
<listitem>
<para><xref linkend="section2-mergebugfix"/>
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><xref linkend="section1-softwarebuild"/>
</para>
<itemizedlist>
<listitem>
<para><xref linkend="section2-bebo"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-automate"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-ensurecheckin"/>
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><xref linkend="section1-instprocess"/>
</para>
<itemizedlist>
<listitem>
<para><xref linkend="section2-chngmgmt"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-objectives"/>
</para>
</listitem>
<listitem>
<para><xref linkend="section2-metrics"/>
</para>
</listitem>
</itemizedlist>
</listitem>
</orderedlist>
</sect1>
<!-- Using GUI Tools -->
<sect1 id="section1-guitools" xreflabel="GUI Tools">
<title>Using <acronym>GUI</acronym> Tools</title>
<para>The traditional interface available for CVS is the command-line client.
There has also been a slew of GUI client applications that can
<quote>talk</quote> to a &CVSAB; server. These GUI clients provide a
<quote>point and click</quote> interface to the &CVSAB; repository.
</para>
<sect2 id="section2-useguiclient" xreflabel="&section2-useguiclient;">
<title>&section2-useguiclient;</title>
<para> This paper recommends using such GUI clients during the initial
deployment of &CVSAB; in an organization.</para>
<para>Developers typically use integrated development environments that have
the CM tools integrated into them. These tools minimize the learning for the
developers about the intricacies of &CVSAB; usage and instead allow them to be
productive from day one. Developers who are accustomed to other CM tools will
find the &CVSAB; command-line interface daunting. The adoption and usage of
&CVSAB; can be improved by using GUI tools for &CVSAB; clients. </para>
<para> GUI tools for &CVSAB; are available at <ulink
url="http://cvsgui.sourceforge.net/">http://cvsgui.sourceforge.net/</ulink>.
GUI interfaces are available for most of the popular platforms (Windows, Mac
and Linux). In addition, on the Windows platform there is an
<acronym>SCC</acronym> extension that allows integration of &CVSAB; as the
configuration control tool with popular IDE.</para>
</sect2>
</sect1>
<!-- Developer Sandbox -->
<sect1 id="section1-devsandbox" xreflabel="&section1-devsandbox;">
<title>&section1-devsandbox;</title>
<para>The developer <quote>sandbox</quote> is where each developer keeps his
or her working copy of the code base. In &CVSAB; this is referred to as the
working directory. This is where they build, test and debug the modules that
they are working on. A sandbox can also be the area where the staging build
or the production build is done. Changes made in the work area are checked
into the &CVSAB; repository. In addition, changes made in the repository by
others have to be updated in the sandbox on a regular basis. </para>
<para>The best practices related to developers sandbox are:
</para>
<sect2 id="section2-clockinsync" xreflabel="&section2-clockinsync;">
<title>&section2-clockinsync;</title>
<para>&CVSAB; tracks change to source files by using the timestamp on the
file. If each client system date and time is not in sync, there is a
definite possibility of &CVSAB; getting confused. Thus system clocks must be
kept in sync by use of a central time server or similar mechanism.
</para>
<para>&CVSAB; is designed from ground up to handle multiple timezones. As
long as the host operating system has been setup and configured correctly,
&CVSAB; will be able to track changes correctly.
</para>
</sect2>
<sect2 id="section2-dontshare" xreflabel="&section2-dontshare;">
<title>&section2-dontshare;</title>
<para>Sandboxes have to be unique for each developer or purpose. They
should not be used for multiple things at the same time. A sandbox can be a
working area for a developer or the build area for the final release. If
such sandboxes are shared, then the owner of the sandbox will not be aware
of the changes made to the files resulting in confusion. </para>
<para>In &CVSAB;, the sandbox is created automatically when a working copy is
checked out for a &CVSAB; project using the <command>cvs checkout
{project-name}</command> command. </para>
<para>In very large projects, it does not make sense for the developers to
check-out the entire source into the local sandbox. In such cases, they can
take the binaries generated by the build team on a regular basis for all those
components of the application that is not changed by them and only check-out
the parts that are built by the developer. </para>
<para>For example, in a Java project, the build team can keep the results of
their last successful build in a standard location in the form of JAR files on
the network file servers. Individual developers will use a standard classpath
setup that has the network drives mounted on standard paths. Thus, the
developers will automatically get the latest version of the files as required
by them.</para>
</sect2>
<sect2 id="section2-syncup" xreflabel="&section2-syncup;">
<title>&section2-syncup;</title>
<para>To gain the benefits of working within a sandbox as mentioned above,
the developer must keep his or her sandbox in sync with the main repository.
A regular <command>cvs update</command> with the appropriate tag or branch
name will ensure that the sandboxes are kept up to date. </para>
</sect2>
<sect2 id="section2-workinside" xreflabel="&section2-workinside;" >
<title>&section2-workinside;</title>
<para>The sandbox can be thought of as a controlled area within which &CVSAB;
can track for changes made to the various source files. Files belonging to
other developers will be automatically updated by &CVSAB; in the developer's
sandbox. Thus the developer who lives within the sandbox will stand to gain
a lot of benefits of concurrent development. </para>
</sect2>
<sect2 id="section2-cleanupatcompletion" xreflabel="&section2-cleanupatcompletion;">
<title>&section2-cleanupatcompletion;</title>
<para>Make sure that the sandbox is cleaned up after completion of work on
the files. Cleanup can be done in &CVSAB; by using the <command>cvs
release</command> command. This ensures that no old version of the files
exists in the development sandbox. As explained previously, pre-built
binaries from the build team can be used to ensure that all the parts of the
application are available to the developer without the need for a complete
compilation in the sandbox. </para>
</sect2>
<sect2 id="section2-checkin" xreflabel="&section2-checkin;">
<title>&section2-checkin;</title>
<para>To help other developers keep their code in sync with your code, you
must check-in your code often into the &CVSAB; repository. The best
practice would be to check-in soon as a piece of code is completed, reviewed
and tested, check-in the changes with <command>cvs commit</command> to
ensure that your changes are committed to the &CVSAB; repository. </para>
<para> &CVSAB; promotes concurrent development. Concurrent development is
possible only if all the other developers are aware of the ongoing changes
on a regular basis. This awareness can be termed as <quote>situation
awareness</quote> </para>
<warning> <para>One of the <quote>bad</quote> practices that commonly occur
is the sharing of files between developers by email. This works against
most of the best practices mentioned above. To share updates between two
developers, &CVSAB; must be used as the communication medium. This will
ensure that &CVSAB; is <quote>aware</quote> of the changes and can track
them. Thus, audit trail can be established if necessary. </para>
</warning>
</sect2>
</sect1>
<sect1 id="section1-serverconfig" xreflabel="&section1-serverconfig;">
<title>&section1-serverconfig;</title>
<para>This section deals with best practices for &CVSAB; server side setup and
configuration.
</para>
<sect2 id="section2-accesscontrol" xreflabel="&section2-accesscontrol;">
<title>&section2-accesscontrol;</title>
<para>One of the important questions that I have been asked time and again is the
ability to have access control for files/folders/branches etc., within
the &CVSAB; repository for various users. Unfortunately &CVSAB; does not
come with a built in Access control capability but it does support a
rudimentary form of access control through the readers/writers files in
the CVSROOT repository. I have put together a set of scripts that use
the readers/writers files to provide a slightly useable version of access
control. This is available at <ulink
url="http://cvspermissions.sarovar.org">http://cvspermissions.sarovar.org</ulink>
as an &OPENSOURCE; project. Feel free to use it and let me know how it
works for you. </para>
</sect2>
<sect2 id="section2-scripting" xreflabel="&section2-scripting;">
<title>&section2-scripting;</title>
<para>Server side scripting refers to the ability to make &CVSAB; server
execute certain scripts when an event occurs. A common script that
helps is to verify that all cvs commits contain acomment entered by the
developer. The process involves setting up the
<filename>CVSROOT/verifymsg</filename> file to run a script when a file is
checked-in. </para>
<programlisting>
------CVSROOT/verifymsg---------
#Set the verifymsg file to fire a script
DEFAULT /usr/local/bin/validate-cvs-log.sh
------/usr/local/bin/validate-cvs-log.sh ---------
#!/bin/sh
#
# validate-cvs-log.sh logfile
# test that log message has some characters in it
if [ `cat $1 | wc -c ` -lt 10 ] ; then
echo "log message too short; please enter a description for the changes"
exit 1
else
exit 0
fi
</programlisting>
</sect2>
<sect2 id="section2-notification" xreflabel="&section2-notification;">
<title>&section2-notification;</title>
<para>The &CVSAB; server can be configured to notify through e-mails in case
of a commit happening. This can be used to verify whether commits are
occurring during the course of a daily/release build. If such commits
occur, based on the project policy, the commits can be ignored or the entire
build automatically restarted.</para>
</sect2>
</sect1>
<!-- Branching and merging -->
<sect1 id="section1-branchmerge" xreflabel="&section1-branchmerge;">
<title>&section1-branchmerge;</title>
<para> Branching in &CVSAB; splits a project's development into separate,
parallel histories. Changes made on one branch do not affect the other
branches. Branching can be used extensively to maintain multiple versions
of a product for providing support and new features. </para>
<para> Merging converges the branches back to the main trunk. In a merge,
CVS calculates the changes made on the branch between the point where it
diverged from the trunk and the branch's tip (its most recent state), then
applies those differences to the project at the tip of the trunk. </para>
<sect2 id="section2-branchowner" xreflabel="&section2-branchowner;">
<title>&section2-branchowner;</title>
<para>The main trunk of the source tree and the various branches should have a
owner assigned who will be responsible for. </para>
<orderedlist>
<listitem>
<para>Keep the list of configurable items for the branch or trunk.
</para>
<para>The owner will be the maintainer of the contents list for the branch or
trunk. This list should contain the item name and a brief description about
the item. This list is essential since new artifacts are always added to or
removed from the repository on an ongoing basis. This list will be able to
track the new additions/deletions to the repository for the respective branch.
</para>
</listitem>
<listitem>
<para>Establish a working policy for the branch or trunk.
</para>
<para>The owner will establish policies for check-in and check-out. The
policy will define when the code can be checked in (after coding or after
review etc.,). Who is responsible to merge changes on the same file and
resolve conflicts (the author or the person who recently changed the file).
</para>
</listitem>
<listitem>
<para>Identify and document policy deviations
</para>
<para>Policies once established tend to have exceptions. The owner will be
responsible for identifying the workaround and tracking/documenting the same
for future use. </para>
</listitem>
<listitem>
<para>Responsible for merge with the trunk
</para>
<para>The branch owner will be responsible for ensuring that the changes in
the branch can be successfully merged with the main trunk at a reasonable point
in time. </para>
</listitem>
</orderedlist>
</sect2>
<sect2 id="section2-tagrelease" xreflabel="&section2-tagrelease;">
<title>&section2-tagrelease;</title>
<para>As part of the release process, the entire code base must be tagged with an
identifier that can help in uniquely identifying the release. A tag gives a
label to the collection of revisions represented by one developer's working
copy (usually, that working copy is completely up to date so the tag name is
attached to the <quote>latest and greatest</quote> revisions in the
repository). </para>
<para>The identifier for the tag should provide enough information to
identify the release at any point in time in the future. One suggested tag
identifier is of the form. </para>
<literallayout>
<literal>release_</literal>{major version #}_{minor version #}
</literallayout>
<note> <para>As one reader pointed out to me, a good practice here is to tag
the release first. Checkout the entire codebase using the tag, and then
proceed to go through a build / deploy / test process before making the
actual release. This will absolutely ensure that what <quote>leaves the
door </quote> is a verified and tested codebase.</para> </note>
</sect2>
<sect2 id="section2-branchatrelease" xreflabel="&section2-branchatrelease;">
<title>&section2-branchatrelease;</title>
<para>After each software release, once the &CVSAB; repository is tagged, a
branch has to be immediately created. This branch will serve as the bug fix
baseline for that release. This branch is created only if the release is
not a bug fix or patch release in the first place. Patches that have to be
made for this release at any point in time in the future will be developed
on this branch. The main trunk will be used for ongoing product
development. </para>
<para>With this arrangement, the changes in the code for the ongoing
development will be on the main trunk and the branch will provide a separate
partition for hot fixes and bug fix releases. </para>
<para>The identifier for the branch name can be of the form. </para>
<literallayout>
<literal>release_</literal>{major version #}_{minor version #}<literal>_patches</literal>
</literallayout>
</sect2>
<sect2 id="section2-bugfixbranches" xreflabel="&section2-bugfixbranches;">
<title>&section2-bugfixbranches;</title>
<para>This practice extends from the previous practice of creating a
separate branch after a major release. The branch will serve as the code
base for all bug fixes and patch release that have to be made. Thus, there
is a separate repository <quote>sandbox</quote> where the hot fixes and
patches can be developed apart from the mainstream development. </para>
<para>This practice also ensures that bug fixes done to previous releases do
not mysteriously affect the mainstream version. In addition, new features
added to the mainstream version do not creep into the patch release
accidentally. </para>
</sect2>
<sect2 id="section2-patchesfrombranches" xreflabel="&section2-patchesfrombranches;">
<title>&section2-patchesfrombranches;</title>
<para>Since all the bug fixes for a given release are done on its
corresponding branch, the patch releases are made from the branch. This
ensures that there is no confusion on the feature set that is released as
part of the patch release. </para>
<para>After the patch release is made, the branch has to be tagged using the
release tagging practice (see <xref linkend="section2-tagrelease"/>). </para>
</sect2>
</sect1>
<!-- Change propagation -->
<sect1 id="section1-chgpropagation" xreflabel="&section1-chgpropagation;">
<title>&section1-chgpropagation;</title>
<para>Change propagation practices explore how changes made to one version of
the application are migrated to other living versions of the application.
</para>
<sect2 id="section2-mergebugfix" xreflabel="&section2-mergebugfix;">
<title>&section2-mergebugfix;</title>
<para>After each release from a branch, the changes made to the branch
should be merged with the trunk. This ensures that all the bug fixes made
to the patch release are properly incorporated into future releases of the
application. </para>
<para>This merge could potentially be time consuming depending on the amount
of changes made to the trunk and the branch being merged. In fact, it will
probably result in a lot of conflicts in &CVSAB; resulting in manual merges.
After the merge, the trunk code base must be tested to verify that the
application is in proper working order. This must be kept in mind while
preparing the project schedule. </para>
<para>In the case of changes occurring on branches for a long period,
these changes can be merged to the main branch on a regular basis even
before the release is made. The frequency of merge is done based on certain
logical points in the branch's evolution. To ensure that duplicate merging
does not occur, the following practice can be adopted. </para>
<para>In addition to the branch tag, a tag called {branch_name}_MERGED
should be created. This is initially at the same level as the last release
tag for the branch. This tag is then <quote>moved</quote> after each
intermediate merge by using the <command>-F</command> option. This
eliminates duplicate merging issues during intermediate merges. </para>
</sect2>
</sect1>
<!-- Software builds -->
<sect1 id="section1-softwarebuild" xreflabel="&section1-softwarebuild;">
<title>&section1-softwarebuild;</title>
<para>This section deals with the best practices for software builds. Build
is the process of creating the application binaries for a software release.
They are done in a periodic manner by the build teams to provide baseline
binaries for daily work. </para>
<sect2 id="section2-bebo" xreflabel="&section2-bebo;">
<title>&section2-bebo; (<acronym>BEBO</acronym>) </title>
<para>A variation of this adage has been around in the &OPENSOURCE;
community called "Release Early and Release Often" for quite some time
albeit for a different reason. BEBO helps a development team identify
issues that can arise from checking in the wrong files. BEBO will address
integration issues at the application level that might have slipped passed
individual developer builds. It will also improve the team morale when they
see a working version of the application.</para>
<para>Builds must be done on a regular basis. There should be a dedicated
resource(s) assigned to do the same. The entire project team must be
trained to view the daily build as an important activity and not as a chore.
Builds must be completed without any failures on a regular basis. Build
failures must be a rare event and should be treated with utmost seriousness.
The project team should ensure that successful builds are top priority on
their agenda. The seriousness can be emphasised by setting up a penalty for
breaking the build. </para>
<para>Each build can be tagged in CVS using a standard naming convention.
This can help developers checkout a working version of the entire system
from daily builds for local development. </para>
</sect2>
<sect2 id="section2-automate" xreflabel="&section2-automate;">
<title>&section2-automate;</title>
<para>Another key practice for software builds is to automate the build
process completely. The automation process must also include automatic
retrieval of the right source files from the &CVSAB; repository. This
ensures that the build process is completely repeatable and consistent. In
addition, the chances of a build with the wrong version of the application
source files are reduced to a large degree. </para>
<para>By automating the build process, the task of building often becomes
less burdensome. </para>
</sect2>
<sect2 id="section2-ensurecheckin" xreflabel="&section2-ensurecheckin;">
<title>&section2-ensurecheckin;</title>
<para>This adage sounds trivial at first but this problem is very common
even with experienced development teams due to oversight. The problem of
oversight cannot be easily addressed since the onus is on the individual
developer to ensure that his or her file has been checked in. This practice
should be drummed into the team in the form of training and pre-build
announcements to ensure that the right version of source code is available
in the repository. </para>
<para>Automated build process as explained above will help in catching this
problem to a certain degree since they will automatically take the source
code from the &CVSAB; repository and perform the software build. Any missed
items will surface during the build process itself (makefiles etc.,) or
during the regression testing of the product (older version of the file
checked in). </para>
<para>A penalty based system can be setup to handle wrong check-in. Having a
kitty for a post project party to which each person who makes a wrong check-in
will contribute a fixed amount will act a good penalty system. </para>
</sect2>
</sect1>
<!-- Institutionalize CVS -->
<sect1 id="section1-instprocess" xreflabel="&section1-instprocess;">
<title>&section1-instprocess;</title>
<para>Here we will look at the best practices for institutionalizing &CVSAB;
usage in the organization.
</para>
<sect2 id="section2-chngmgmt" xreflabel="&section2-chngmgmt;">
<title>&section2-chngmgmt;</title>
<para>All organizations must implement a good Change management process
(<acronym>CMP</acronym>). A good CMP will define how changes are received,
recorded, tracked, executed and delivered. &CVSAB; provides version
control for your project. Change management addresses the <quote>bigger
picture</quote> of how enhancements and bugs are received, tracked and
closed. &CVSAB; will play a smaller but a very important part in this
entire picture. With a formal change management process in place in the
organization, tools such as &CVSAB; will be looked at as aiding this process
instead of acting as a general development overhead. </para>
<para>Change management is quite a vast topic that cannot be done justice
here. Please look up other sources of information on change management. </para>
</sect2>
<sect2 id="section2-objectives" xreflabel="&section2-objectives;">
<title>&section2-objectives;</title>
<para>To institutionalize &CVSAB;, it can be made as part of the performance
objectives for the developer to use &CVSAB; in the project. In addition, it
can also be made as part of the objective for the project manager to deploy
&CVSAB; in his or her project. </para>
<para>Compliance of this can then be reviewed as part of the appraisal cycle
for the employee. </para>
</sect2>
<sect2 id="section2-metrics" xreflabel="&section2-metrics;">
<title>&section2-metrics;</title>
<para>&CVSAB; usage metrics can be collected in terms of percentage of
deployment in the organization, project size handled etc., This information
will spur other line managers and program managers to look at &CVSAB; as a
tool that will aid them in their daily operations. </para>
</sect2>
</sect1>
<!-- Case Study -->
<sect1 id="section1-inaction" xreflabel="Best Practices in Action">
<title>Best Practices in Action</title>
<para>The best way to explain the need for these best practices is by
putting together an example of a real world project scenario and show how
exactly will these best practices fit into the <quote>bigger
picture</quote>. Also, a lot of readers have told me that the sections on
<xref linkend="section1-branchmerge"/>
and <xref linkend="section1-chgpropagation"/> will require examples for better
explanation. Listening to the readers is a Good Thing so I have
put together a particular project scenario and then create a series of
events to show how the best practices, if followed, would help is making
operations smoother. </para>
<sect2 id="section2-inception">
<title>Inception</title>
<para>Consider a software project where version 1.0 has just been put into
production and everyone is done celebrating. The next step is to start
working on the new features of the subsequent release. Also, the users of
the system have started to use it full-time and bug reports of various
levels have started to come in. </para>
<para> Before jumping into new enhancements or bug fixes, the best practices
for <xref linkend="section1-branchmerge"/> should be followed. Few of
the important practices are <xref linkend="section2-tagrelease"/> and
<xref linkend="section2-branchatrelease"/>. These practices will
effectively established two <quote>development environments</quote>,
one for regular enhancements and the other for bug fixes and minor
enhancements on the last release.</para>
<para>Let us assume that the release was tagged as
<literallayout>
<literal>release_1_0</literal>
</literallayout>
</para>
<para>Then the branch was created with the branch name
<literallayout>
<literal>release_1_0_patches</literal>
</literallayout>
</para>
</sect2>
<sect2 id="section2-dand">
<title>Development and Delivery</title>
<para>Now, we are ready for business. Let us examine the bug fixes and
enhancements track. Assume that there are three bugs of which two are of a
high priority that should be fixed right away (possibly within a week) and the
third can be delivered after some time (say after 4 weeks). In the
middle of this schedule there is a regular release scheduled in three weeks.
Considering that we have a busy month ahead, let us see how exactly we can
use the Best practices to ease the days ahead.</para>
<para>The timeline for the various release in the next month looks like this.
</para>
<programlisting>
Fix Enhancement Fix
Today Release 1 Release Release 2
|_______|______________|_________|
Time --&gt;
</programlisting>
<para>We have two teams, one working on the bug fix branch and another team
working on the features for the next release on the main trunk. These
teams must make sure that they start out with the right version in
their sandbox.</para>
<orderedlist>
<listitem>
<para>
The bug fix team will check out using the command line
</para>
<para>
<command>cvs checkout -R -r release_1_0_patches {project name}</command>
</para>
</listitem>
<listitem>
<para>The team that is working on the next release will use the command line
</para>
<para>
<command>cvs checkout -R {project name}</command>
</para>
</listitem>
</orderedlist>
<para> As soon as the bug fix team completes the two top priority bugs, they
will update, verify a successful build and commit their changes to the bug
fix branch using the command line
</para>
<para>
<command>
cvs update -R -r release_1_0_patches {module name}
</command>
</para>
<para>The team should perform a build at this point to verify that the
update did not break any code on the branch. Once the build is successful,
the branch should be committed back into the repository.
</para>
<para>
<command>
cvs commit -R -r release_1_0_patches {module name}
</command>
</para>
<para><xref linkend="section2-bebo" /> : On a daily basis, each developer
will check in code to &CVSAB; and to ensure sanity of code, daily builds on
the bug fixed branch will be undertaken by checking out from
&CVSAB; on a clean environment and completely rebuilt. These daily builds
can be tagged in &CVSAB; using the following naming convention </para>
<literallayout>
<literal>build_1_1_yyyymmdd : for the branch</literal>
<literal>build_2_0_yyyymmdd : for the trunk</literal>
</literallayout>
<para>The regular process of build-test-fix is followed to make a version
ready for delivery. The tag will help developers checkout a working copy of
the latest build as and when necessary. </para>
<para> When the source code is released to the outside world, two practices
have to be followed. </para>
<orderedlist>
<listitem>
<para> <xref linkend="section2-tagrelease"/> : This ensures that the bug fix
release is tagged correctly and so can be traced out at a later point in
time if necessary.
</para>
</listitem>
<listitem>
<para><xref linkend="section2-mergebugfix"/> : This ensures that the bug fix
is merged back into the main trunk ensuring that all future
releases is a truly cumulative delivery.
</para>
</listitem>
</orderedlist>
</sect2>
</sect1>
<sect1 id="section1-conclusion" xreflabel="Conclusion">
<title>Conclusion</title>
<para>These best practices are meant to help software teams get a head start
on using &CVSAB; for their development. The ideas presented here have to be
constantly reviewed and evolved. I would like this to be a growing and
evolving document. Please send your comments and ideas to
<email>&MYEMAIL;</email> </para>
</sect1>
<!-- Include the GNU FDL -->
&GFDL-FILE;
</article>