Jul 2006
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.
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
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..
svnadmin create /svnroot
What it does - creates an empty repository awaiting an import.
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:
[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.
[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 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 Projectsvn checkout svn://servername_or_IPADDRESS/svnroot/myproject
Checking Out A Particular Versionsvn checkout svn://servername_or_IPADDRESS/svnroot/myproject/1-0
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:
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.
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.
--------------------------------------------- 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.
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.