Tuesday, May 28, 2013

Hand to Hand Combat with Subversion and SmartSVN

In previous links I have extolled the virtue of both backups (obviously) and version control (less obviously) for what is in fact 'hobby' software development.  I had the 'bot under version control using Subversion on OSX with SmartSVN as the GUI client.  Somehow, however, I managed to screw things up to the point where it was unusable.  I spent a fair amount of time on the OSX box trying to figure out what I had done but finally decided that I wanted my repository to live on another server anyway.  Ubuntu was my most logical choice, as I have a couple of boxes running it already, so I got started.

I found some pretty straight forward instructions at this link and followed them closely.   When running on OSX I had relied on the SmartSVN GUI entirely but this time I wanted to have at least a basic understanding of how Subversion was working under the scenes.  This reflects my late realization that Subversion is actually doing all the heavy lifting and that this was being masked by the GUI.

In any case, following those instructions in detail gave me a pretty good handle on how Subversion works.   Everything went well locally but I did have some issues when I tried to access my repository remotely.   It turns out that in the process of getting my directory structures the way that I wanted them I had lost the changes that I had made to the 'svnserve.conf' file located in the 'conf' directory of the repository.   Without this file, and the passwd file also in the same directory, svnserve was denying me access.  My real problem was that I was convinced that I had done everything that I was supposed to have done...and did not look at the obvious (at least for a bit).

Once I had everything working at the command line it was simple to get SimpleSVN working again.

Here is a summary of the steps that I took based on (but with a few differences) the above mentioned link:

First create the directory structure for svn and your repository.   I put mine on the root thinking it might be easier to relocate it to it's own mount point later.   In this box I also created a group for subversion users and added myself to that group.
cd /
sudo mkdir svn
cd svn
sudo mkdir repos
cd repos
sudo groupadd svn
sudo chgrp svn /svn/repos

sudo chmod g+w /svn/repos
sudo chmod g+w /svn/repos
sudo usermod -a -G svn will
Note the two chmod commands.  The intent of these two commands is to make sure the svn group can write to the repository...and...that files created in the repository inherit that write-ability for the group.   I had to repeat these commands later so am not sure if they are needed here or not.

Now create the actual repository, or repositories, that you will use.   The umask is there so that group rights are protected...but...given my comment above I am not sure that you need these as the later chmods will accomplish the same thing?
umask 002
sudo svnadmin create /svn/repos/Arduino
umask 022

And finally the chmod's that I mentioned above.   Without these I was not able to commit to the repository as the group had, somehow, not gotten the right write rights all the way into the structures that subversion uses. 
sudo chmod -R g+w /svn/repos
sudo chmod -R g+w /svn/repos
sudo reboot
I did a reboot at this point but I think that all you really need is a logout / login to pickup the group rights for svn.

You should now be able to execute the following commands on your local machine to checkout the repository, create a file and add it to the repository, and then commit that change:
cd ~
svn checkout file:///svn/repos/Arduino

cd Arduino
cat 'This is a test file' > test.txt
svn add test.txt
svn commit -n 'Test file added'
You should have seen a version 0 checkout, that add of test.txt, and then a version 1 commit if all has gone well.

Next remote access...

First create a passwd file in the base directory that was created above.  In the case of the example this was /svn.   The format is below and should include the names for you (and your team if you have one!):
[users]
will = password


The go into each repository under repos and edit the svnserve.conf file (in the conf directory) to have the following minimum of entries:
[general]
anon-access = none
auth-access = write
password-db = /svn/passwd
realm = team

Note that I am pointing the password database to the file created above so you only need one of these.

Finally the command to start svnserve:
sudo svnserve -d -r /svn/repos

You should now be able to access your new repository from the network using the below command for a checkout:
svn checkout svn://workbench/Arduino --username will
Obviously with your IP address or host name substituted above!

Once all of the above was done I was also able to get back into SmartSVN and import this project.   Understanding for once what was going on in the background!  One last note...a very useful command while I was cleaning things up from my previous mess was 'rm -Rf .svn'.   This deletes the structures that mark a path as being in an svn repository.


The last thing that I did was to follow my own instructions, located here, to create a script to have svnserve start automagically on boot.   Here is the script that I created from my example:
#! /bin/sh
# /etc/init.d/noip

### BEGIN INIT INFO
# Provides:          svnserve
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Starts svnserve for local code repositories
# Description:       A simple script based on one from www.stuffaboutcode.com.
### END INIT INFO

# If you want a command to always run, put it here

# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting svnserve"
    svnserve -d -r /home/svn/repos
    ;;
  *)
    echo "Usage: /etc/init.d/svnserve {start}"
    exit 1
    ;;
esac

exit 0

There are obviously a LOT of other configuration and commands that can be done from here but this is a bare minimum to get me back to where

No comments:

Post a Comment