Jul 2006

Setting Up Subversion

The subversion versioning system is great and comes with many features and documentation. This text will focus on getting, configuring and using a subversion repository quickly.

Getting, Configuring and Building Subversion

In the example, subversion is installed to a single tree to simplify things. The sources are available fo download from Tigris'. The initial steps are unpack then configure.

tar xjvf subversion-1.3.1.tar.bz2
cd subversion-1.3.1
./configure --prefix=/usr/local/subversion
make

(as root or sudo)

make && make install

Creating a Subversion Repository

A subversion repository can be created by anyone who has permissions on the filesystem. The same repository may also have access controls handled by the same user who created it if file level (local) access is used or the user has permissions to start a subversion server. To keep things simple one repository is created by some user. Individual and group permissions via the svn protocol will also be addressed..

Create a Repo

svnadmin create /svnroot

What it does - creates an empty repository awaiting an import.

Adding External Users

Several methods exist to access a subversion repository. File level access can be used by specifying file on the command line with the svn command like so:

svn file:///path/to/repo

The method demonstrated in this text is using the subversion protocol itself. The other two methods of authentication are webdav and svn+ssh. In order to add basic users, edit the /svnroot/conf/passwd and /svnroot/conf/svnserve.conf. The following entries are required to add users john_doe and jane_doe to the repository:

/svnroot/conf/passwd
[users]
john_doe = john_doe_passwd
jane_doe = jane_doe_passwd

The [john,jane]_doe_passwd password entry should be a better password entry than the example.

/svnroot/conf/svnserve.conf
[general]
john_doe = write
jane_doe = write

passwordd-db = passwd

The configuration file has other options such as read only and the ability to create authentication realms.

Using the Repository

Using the repository once users are setup is pretty simple. The subversion server is the first step:

svnserve -d

With the server started, a project can be imported:

mkdir -p /tmp/svn/myproject/trunk
cd myproject
cp -Rp * /tmp/myproject/trunk
cd /tmp/svn
svn import . svn://servername_or_IPADDRESS/svnroot \
        -m "Initial import of myproject"

Many variations for checking in exist, if myproject already has a release copy, it can be added to the initial import as well:

mkdir -p /tmp/svn/myproject/trunk
mkdir -p /tmp/svn/myproject/1-0
cd myproject/
cp -Rp * /tmp/myproject/trunk
cd myproject-v1.0
cp -Rp * /tmp/myproject/1-0
cd /tmp/svn
svn import . svn://servername_or_IPADDRESS/svnroot \
         -m "Initial import of myproject"

To checkout a project, just use the svn command:

svn checkout svn://servername_or_IPADDRESS/svnroot/myproject/trunk

Subversion can checkout all of the projects files or by directory:

Checking Out the Entire Project
svn checkout svn://servername_or_IPADDRESS/svnroot/myproject
Checking Out A Particular Version
svn checkout svn://servername_or_IPADDRESS/svnroot/myproject/1-0

Working with Branches

Most projects follow a standard path of trunk or head with branches to mark releases and maintenance and/or patch branches. A good scenario for an example is to use all three and show how the operations would be done.

First the initial import of the trunk:

mkdir -p /tmp/svn/usertools/trunk
cd /path/to/usertools
cp -Rp * /tmp/svn/usertools/trunk
cd /tmp/usertools
cd /tmp/svn
svn import svn://servername_or_IPADDRESS/svnroot .\
     -m "Initial import of usertools"

With the trunk imported, a checkout is performed for development:

svn checkout svn://servername_or_IPADDRESS/svnroot/usertools/trunk \
        usertools-current

Note that the sources from trunk can be checked out to another local directory name, when doing commits, subversion will automatically commit to the correct location in the repository regardless of the local top level directory name.

Assuming that it is now time for a release, three branches are created for the release:

  1. The main release branch.
  2. A patch branch for minor bug patches.
  3. Maintenance branch to merge large patchsets into and any after release maintenance that may have come up.

Several approaches to releases can be used, for instance, having only a patch or maintenance branch.

To create the branches, svn copy is used:

svn copy svn://servername_or_IPADDRESS/svnroot/usertools/trunk \
        svn://servername_or_IPADDRESS/svnroot/usertools/1.0-release
svn copy svn://servername_or_IPADDRESS/svnroot/usertools/trunk \
        svn://servername_or_IPADDRESS/svnroot/usertools/1.0-patch
svn copy svn://servername_or_IPADDRESS/svnroot/usertools/trunk \
        svn://servername_or_IPADDRESS/svnroot/usertools/1-maint

As a safety step, it might be wise to ask the subversion administrator to set the release branch to read only to freeze the branch. The maintenance branch is not tied to a minor number which is explained later.

Patching and Maintenance

A patch branch is generally used for small security and bug fixes. Patches can be generated back against the release branch for source patching or by simply shipping new executables from the patch branch itself.

A maintenance branch should also have patches applied and be a sandbox for where larger changes such as large security changes or driver upgrades would take place. Because smaller patches are applied to the maintenance branch, many projects choose to only have a maintenance branch and forego the additional work of managing patch and maintenance branches.

Another issue is what to merge into trunk and when. Usually this is handled on a case by case basis. A simple way is to just pull up the patches and see if any conflicts are kicked out, then test.

Moving code between branches is done with svn merge by merging the sources of the current directory into the specified location - for example: merging the patch branch into the maintenance branch:

svn checkout svn://servername_or_IPADDRESS/svnroot/usertools/1-maint \
        usertools-1-maint
cd usertools-1-maint
svn merge -r svn://servername_or_IPADDRESS/svnroot/usertools/1.0-patch
svn commit -m "Merged patch branch into maintenance"

Finally, it is time for a dot release or maintenance release. In the example, the maint branch should have all major changes and patches applied to it, so now a branch relative to the maintenance branch is done for a minor release and patch branch:

svn copy svn://servername_or_IPADDRESS/svnroot/usertools/1-maint \
        svn://servername_or_IPADDRESS/svnroot/usertools/1.1-release
svn copy svn://servername_or_IPADDRESS/svnroot/usertools/1-maint \
        svn://servername_or_IPADDRESS/svnroot/usertools/1.1-patch

Again, a good idea is to make the new release branch read only. Note that no new maintenance branch was created, this is because one is not needed, the maintenance branch is effectively the trunk for the major release and will stop being developed when that particular release has reached end of life.

A Map of the Example

--------------------------------------------- usertools-trunk -->
\                                      
 ----- usertools-1.0
 |
 ------ usertools-1.0-patch ---
 |                             \
 ------ usertools-1.0-maint ----\-------------------------------- ..
                                 \                           /
                                  --- usertools-1.1         /
                                  |                        /
                                  --- usertools-1.1-patch -

A simpler method is simply to have one branch for fixing up and enhancing a release so merging what is applicable into the main trunk is easier:

------------------------------------------------ usertools-trunk -->
\                             |           |   \
 ----- usertools-1.0          |           |    --- usertools-2.0
 |                            |           |    |
 ------ usertools-1.0-maint ---------------    ---- usertools-2.0-maint
                            \               \
                             usertools-1.1  usertools-1.2

It is important to note that only applicable changes should be merged into the trunk. As is often the case, entire subsystems of a given project are rewritten in the ever changing trunk portion and straight merges will be impossible.

Summary

Subversion is easy to get up and running quickly just using a very basic setup. Subversion is also very flexible due to the dir centered design. Visit the subversion documentation to learn other features of subversion.