Friday, 25 February, 2005
For all subversion questions and details, one should first take a look
at the Subversion Book (see Section 6, “Links to References”). Here are just
some notes that filled some minor gaps when I setup things on my
machine.
This section assumes that you have installed subversion and
related packages (such as the Apache module). The easiest way to do
this is to get the .rpm's or something similar based
on whatever packaging system your distribution uses. apt-get
subversion or something similar on
apt-enabled systems.
Next:
Create a new user, say svn by:
$ useradd -d /home/svnroot -c subversion svn
This also creates a new group, svn and at
this point only user svn is in the group.
Add users that will use the repository/make changes to the
group svn. Also, if you want to allow access
to the repositories using http and Apache, then the user that the
httpd process runs as must have permissions
to the repositories. Typically, this can be done by adding user
svn to the apache group.
$ usermod -G ...,svn user1
$ usermod -G svn,apache svn
Ensure that all members of the group have write access to the
repository. The script groupmod.sh can be used to
ensure that all files that are owner-writeable are
group-writeable.
Revision numbers in subversion are repository-wide. So typically, you
would want a separate repository for projects that are independent.
Repositories can be created as follows:
First, we create the repository:
$ svnadmin create /home/svnroot/project
Make sure that /home/svnroot/project/
has all the requisite permissions (for example, if all
users of the group svn will be making
modifications, then /home/svnroont/project
should be group-writeable.
Create a directory structure as follows:
project/
Now,
$ cd project
$ svn import . file:///home/svnroot/project
Branching is a concept common to most version control systems. Chapter
4 of the Subversion Book [1] explains the idea.
Subversion (and possibly other systems, like CVS?) provide the ability
to selectively merge changes in one branch into others. This has proven
to be quite useful for Linux kernel modifications I've been playing around
with. What I want to do is make changes and test them in UML (User-Mode Linux)
and then later port them back to a non-UML kernel. Though UML and the
regular kernel share most of the source, there are some differences
manifested in the form of uml-patches. Thus, there are two "similar"
but different code-bases. However, the experimentation I'm up to
is in the common areas, i.e., are not UML-specific. Hence, I want
to be able to avoid manually porting changes I make between the two.
This is where branches come in. Initially, we have the pure Linux
source. Then branch this off to create a UML branch. Apply the
uml patches to the source. So, now we have two branches - the
main or the "trunk" and a uml branch. Changes made to any one of
them that are safe for the other can be ported automatically by
subversion's merge. Here's how it goes:
Starting point: A repository with "pure" Linux source. Let it's
URL be file:///home/svnroot/linux with all
the code places in
file:///home/svnroot/linux/trunk.
Now we fork off a branch and apply the UML patches:
$ cd /tmp
$ svn copy file:///home/svnroot/linux/trunk \
file:///home/svnroot/linux/branches/uml \
-m "Creating a branch for UML"
$ svn checkout file:///home/svnroot/linux/branches/uml ./my-uml
$ cd my-uml
$ # Apply patches
$ patch -p1 < /path/to/patches/uml-....patch
$ svn commit
The svn commit operation above would give
you a revision number, suppose that's 3. Now, go ahead and
make any changes to this branch, i.e., to the UML code.
Compile it, test it and do whatever till you're ready to
merge the changes into the non-UML source. The final
commit operation will give you another
revision number, suppose that's 5.
At this point, you know that revision 3 is when you began
making your changes (revision 3 itself was just the UML patch).
And changes between revisions 3 and 5 are to be ported.
This can be done by checking out a copy of the non-UML code
and then using svn merge, as so:
$ cd /tmp
$ # Checkout trunk, or if you already have it checked out then
$ # skip this step
$ svn checkout file:///home/svnroot/linux/trunk ./non-uml
$ cd non-uml
$ # Merge changes between revisions 3 and 5 in the uml branch to here
$ svn merge -r 3:5 file:///home/svnroot/linux/branches/uml
Done!
NOTE: It seems that as of kernel 2.6.9,
user-mode-linux (UML) has been merged into the vanilla kernel source
and thus there is no reason to have separate branches for the UML and
non-UML kernels. Of course, this doesn't mean that there aren't any
other applications for branches and merging in subversion!
If the authentication you want to do is based on the users and
groups on the system, then probably the best thing to do is to
use SSH. This keeps things "secure" as you don't have to open
up any other ports on the host machine. This requires no
additional setup assuming that you have an ssh server running
on the host machine already.
If the repository is located at
/home/svnroot/project, then the URL for
remote access would be
svn+ssh://user@hostname/home/svnroot/project
Another option is to use the svnserve server
process that ships with subversion. The Subversion Book (see
Section 6, “Links to References”) explains this nicely. I configured
svnserve to be launched by
xinetd, so I added a file
svn in /etc/xinetd.d on
my Fedora Core 2 installation. The file looked so:
# default: on
# Subversion server
service svn
{
socket_type = stream
protocol = tcp
user = svn
wait = no
disable = no
server = /usr/bin/svnserve
server_args = -i -r /home/svnroot
port = 3690
}