November 26, 2014
Hot Topics:

A Crash Course in Subversion

  • April 22, 2005
  • By Garrett Rooney
  • Send Email »
  • More Articles »

Creating and Populating the Repository

Before you can really do anything with Subversion, you need to have access to a Subversion repository. Because you'll need to have the ability to commit changes to a repository to do anything interesting (which is pretty much required if you want to learn more than just the basics), you'll want to create your own repository. The svnadmin program is used for this purpose (among other things, of course, which I'll discuss further in Chapter 3). Run the svnadmin create command, and you're ready to go. It looks something like this:

$svnadmin create myrepos
$ls -l myrepos/
-rw-r--r--   1 rooneg  staff  376 May 31 17:32 README.txt
drwxr-xr-x   2 rooneg  staff   68 May 31 17:32 dav/
drwxr-xr-x  17 rooneg  staff  578 May 31 17:32 db/
-rw-r--r--   1 rooneg  staff    2 May 31 17:32 format
drwxr-xr-x   7 rooneg  staff  238 May 31 17:32 hooks/
drwxr-xr-x   3 rooneg  staff  102 May 31 17:32 locks/
$

Inside the repository you just created are a number of files and directories, each of which has a specific purpose. You'll find out more about them later, so for the moment, don't touch them. With a few exceptions, you shouldn't modify anything inside the repository by hand. Instead, you should always use the svnadmin and svn programs to access the repository (that is, unless you really know what you're doing—but in that case, why are you reading this chapter anyway?).

Now that you've created a repository, you'll need to put something in it before it's much use to anyone. The first step is to create an initial repository layout. Unlike other version control systems, Subversion uses directories (and copies of directories) as tags and branches. This means that creating a new tag or branch is exactly the same as copying a directory. The only difference is a social one. The developers agree to treat certain copies of a directory in a specific way, either by confining some kind of development to them (as in a branch) or by leaving them completely read-only (as in a tag). I'll go into greater depth on how to work with tags and branches later, but for the moment you just need to know that if you want to make use of branches or tags in the future you'll want to create some subdirectories in your repository to hold them. Traditionally, most people create three top-level directories in their repository: one named /trunk to hold the main copy of the project where most development occurs, one named /branches to hold separate lines of development (remember, those will just be copies of /trunk), and one named /tags to hold copies of the project as it exists at significant points of time, such as a release. The only difference between the copies of /trunk that end up in /tags and the ones that end up in /branches is that everyone agrees not to modify the ones in /tags—they're only there because they're of historical interest.

You might be wondering why Subversion doesn't just create these top-level directories for you. The reason is quite simple: Subversion doesn't have any idea what you're going to put in your repository or what kinds of conventions you're going to use for repository layout. If you have a single project in your repository, the traditional top-level layout makes sense, but if you want your repository to hold multiple projects, you'll probably want each project to have its own trunk, tags, and branches directories contained within a top-level directory named after the project. Chapter 3 details the issues involved in selecting a repository layout.

Before you create your top-level directories, I should mention something about how to use the svn command-line client program. All of svn's subcommands take a target as one (or more) of their arguments. In many cases, this target can be either a local path or a URL that refers to something inside a repository. For many of these commands, if you don't provide a target, the command will assume you want to use your current working directory as the target. If the command targets something in your local working copy, no change you make will be reflected in the repository until you commit it in a separate command. Conversely, any change you make that targets the repository directly will cause an immediate commit, requiring you to specify a log message as with any other commit and creating a new revision in the repository.

Now let's move on to actually create your initial repository layout. You'll need to create each top-level directory via an svn mkdir that targets the repository directly. 1 The process looks like this:

$svnadmin create repos
$svn mkdir file:///absolute/path/to/repos/trunk \
           file:///absolute/path/to/repos/branches \
           file:///absolute/path/to/repos/tags \
           -m "creating initial repository layout"
Committed revision 1.
$

Let's examine that command for a second, and see what else you can learn from it. First of all, you see the syntax for accessing a repository via a file:// URL. Whenever a Subversion command uses the file:// schema for a URL, that means it's directly accessing the repository via Berkeley DB, so the repository needs to be located on the same machine you're running the command on, and you need read-write access to the database files within the repository itself (see Chapter 3 for more details about the internals of the repository). Look closely at the URLs you used to specify the directories you created. There are three slashes after file:, which might seem a bit odd, but if you think about it, it makes sense. It's just like accessing a web page over HTTP, except the part of the URL that would contain the domain name is empty, thus it skips directly to the third slash.

Second, you used the -m flag to pass a log message for the commit in on the command line. Because you're committing this change directly to the repository, a log message is required. If you don't pass one on the command line (either via -m or in a file specified with the --file argument), the client will run your editor of choice to give you an opportunity to enter one. 2

Now that the directories in question exist in the repository, let's confirm that fact via svn list. (Most people probably know this command better as svn ls.)

$svn list file:///absolute/path/to/repos
branches/
tags/
trunk/
$

Here you can see that the top level of the repository contains the three directories you just created. Of course, empty directories aren't all that useful, so let's put some data in them. Assuming that you already have some kind of project you want to bring into Subversion, you can import it via the svn import command. This command's command-line arguments are an optional path to a directory of files you want to import (if you don't specify a path, your current working directory is imported) and a URL to indicate where in the repository to place the data you're importing. Any directories at the end of the URL that don't yet exist in the repository will be automatically created. Take a look at this example to see what I mean:

$ls my-project/
foo.c
bar.c
main.c
$svn import my-project file:///path/to/repository/trunk \
            -m "importing my project"
Adding      my-project/bar.c
Adding      my-project/foo.c
Adding      my-project/main.c
Committed revision 2.
$svn list file:///path/to/repository/trunk
foo.c
bar.c
main.c
$

This is a basic example that imports a directory of files directly into the trunk of the repository. Note that once again you have to specify a log message because you're committing a change to the repository. If you want to import the files into a subdirectory of trunk, the process looks like this:

$ls my-project/
foo.c
bar.c
main.c
$svn import file:///path/to/repository/trunk/new-directory \
            -m "importing my project into new-directory"
Adding        my-project/bar.c
Adding        my-project/foo.c
Adding        my-project/main.c
Committed revision 3.
$svn list file:///path/to/repository/trunk/
foo.c
bar.c
main.c
new-directory/
$svn list file:///path/to/repository/trunk/new-directory/
foo.c
bar.c
main.c
$svn delete file:///path/to/repository/trunk/new-directory \
   -m "get rid of extra directory because it's not very useful"
Committed revision 4.
$

Finally, you can verify that the content of the files you just imported is actually in the repository by using the svn cat command. svn cat prints the contents of a file in the repository to the screen, and it can be a quick and dirty way to see what a given revision of a file looks like.

$svn cat file:///path/to/repository/trunk/main.c
#include <stdio.h>
int
main (int argc,char *argv [])
{
   printf ("hello world \n");
   return 0;
}
$cat my-project/main.c
#include <stdio.h>
int
main (int argc,char *argv [])
{
   printf ("hello world \n");
   return 0;
}
$

As you can see, there's no difference between the contents of main.c in your original directory and the contents of main.c in the trunk directory of the repository. The import has worked as you'd expect, loading the contents of your directory tree directly into the repository.





Page 3 of 5



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel