A Guided Tour of Subversion (SVN)

Assuming the reader has already installed Subversion (SVN) and created a repository, the article offers a guided tour through the most important and frequent Subversion usage scenarios.

In this article I assume, that you already have the Subversion installed and that your repository is already created and accessible (see Part 2 for how to do that). I will use both command line client (svn) and TortoiseSVN (graphical client for Windows) in parallel to demonstrate multiple ways to do things. In the examples I will use the http: protocol to access Subversion (for which the Apache HTTP server is needed), but you can equally good use the svn: (you need to run Subversion's svnserve server) or file: (with no server) to go through the sample scenarios. The root URL of the repository in my examples will be localhost / repos /sandbox/ (it's the repository created in Part 2 examples).

All the source files used in this article are available in the attached zip file.

The first important command we should get familiar with is help. Both tools have rich help, which assist us to quickly find reference information.

### Command Line

svn help

### Tortoise SVN

Right Click -> TortoiseSVN -> Help

When starting the work with some repository, we usually wan to check, whether the repository URL is correct and to get oriented in the repository structure. With command line client we can use the info and list commands, with Tortoise the easies way is to use the build-in Repo-browser. When using http protocol, there is also the alternative to simply use web browser to examine the repository structure/content.

### Command Line

svn info localhost/repos/sandbox/

and after that

svn list -v localhost/repos/sandbox/

(and eventually -R for recursive listing)

### Tortoise SVN

Right Click -> TortoiseSVN -> Repo-browser -> type in the URL localhost/repos/sandbox/ -> OK

During the above use case the clients might ask for user name/password, if the anonymous read access is not allowed (depending on your access file - as explained in Part 2), in different setup they might ask later - when a write operation is performed. By default the user credentials will be remembered and asked for only once per repository (the credentials are stored in your home folder).

Once we know our repository, we can start by importing our project. Let's assume we have a Java project called Hanoi, which solves the well known Towers of Hanoi problem (http://en.wikipedia.org/wiki/Towers_of_Hanoi). We have the project on our hard disk and we want to put it into Subversion repository. We have two options for importing data - either we just want to place files into version control or we want to place them into version control and turn the existing folders into SVN working copy, without moving the files. Let's go through the both cases. Firstly we will create the recommended project structure (trunk/branches/tags) by import, secondly we will turn the project folder into a working copy. Create the following structure in your temp folder:


Now we will import this structure into SVN.

### Command Line

cd \Temp

svn import structure http:// localhost / repos/sandbox/ -m "Importing the project structure"

The -m MESSAGE is common parameter for SVN commands which write data into the repository - you always have to specify the message. Try to execute the command without -m and see the result.

### Tortoise SVN

Right Click the "structure" folder-> TortoiseSVN -> Import... -> Enter the repository URL localhost/repos/sandbox/ and the commit message -> OK

Now we have the folder structure duplicated in the repository, but there is no connection between the files on our disk and in the repository - it's not a working copy - therefore there is no easy way to propagate changes from the temp folder to the repository.

We will use the other method to import the actual project files, because these are already placed on correct location in our working place and also we want to selectively avoid the import of some files (e.g. compiled binaries). First we will checkout the empty SVN project folder into our actual project (to create working copy), then we will add the necessary files into the version control and finally we will commit them into the repository. The project files are located in folder [1] in the source zip file.

### Command Line

Non recursively checkout the trunk folder into the project root (don't miss the ‘.' in the checkout command)

cd hanoi

svn checkout -N localhost/repos/sandbox/Hanoi/trunk/ .

Now your project is a working copy (there is the .svn folder there). Recursively add src folder into the cource control

svn add src

Non recursively add all other files

svn add -N *.*

Ignore any content inside the bin folder

svn propset svn:ignore "*.*" bin

Commit all changes at once into the repository

svn commit -m "Adding the project content"

### Tortoise SVN

Right Click the "hanoi" folder -> Checkout... -> Enter the URL localhost/repos/sandbox/Hanoi/trunk; check "Only checkout the top folder" -> OK -> Yes (to checkout anyway)

Now your project is a working copy (there is the .svn folder there). Add the files into version control:

Right Click the "hanoi" folder -> TortoiseSVN -> Add... -> uncheck the *.class -> OK

So now all the files, extept the classes in the bin folder are scheduled for addition on commit. Next we tell SVN to forever ignore the content of bin folder:

Go to hanoi\bin\, Right Click Solver.class -> TortoiseSVN -> Add to Ignore List -> *.class

And finally commit all the changes:

Right Click the "hanoi" folder -> SVN Commit... -> Fill in the commit message -> OK


Now you can explore the repository content to see the project files inside and you can also check, that the project folder on your local disk is a Subversion working copy (each folder contains the .svn subfolder). When invoked from inside of working copy, both command line client and Tortoise recognize that and behave accordingly, e.g. they determine the repository location from the working copy.

As now the project is in the repository, multiple people can start working on it. We will simulate that by checking out another working copy, which will represent another user's workspace.

### Command Line

cd \Temp

mkdir bob\hanoi

svn checkout http:// localhost/repos/sandbox/Hanoi/trunk/ bob\hanoi

### Tortoise SVN

Create \Temp\bob\hanoi

Right Click the "hanoi" folder-> SVN Checkout... -> Enter the URL localhost/repos/sandbox/Hanoi/tru (it's probably already preset since the last operation) -> OK

Bob is now going to edit some files. He will add a new class Counter.java and modify the run.bat. You can find the final files in folder 2 of attached sources.

### Command Line

cd \temp\bob\hanoi

First, use svn status to see which files are new and modified, you will get:

?      src\Counter.java

M      run.bat

which indicates one new file (?) and one modified (M). Note, that the Counter.class in bin folder gets ignored. Now add Counter into the source control:

svn add src\Counter.java

(try svn status gain) and commit

svn commit -m "Adding the counter"

### Tortoise SVN

It's much easier here, since the commit window already does a lot of work for us:

Right Click the "Hanoi" folder-> SVN Commit... -> Enter the commit message and check the checkbox next to Counter.class -> OK


Now we will get back to the first user (Alice, of course), who imported the project. She updates her working copy to get Bob's changes.

### Command Line

cd \temp\hanoi

svn update

### Tortoise SVN

Right Click the "\temp\hanoi" folder-> SVN Update...

In both cases, you will be given overview of what was updated.

The last scenario, which we will go through is branching and merging. Let's assume now, that Bob now has to do some performance optimization of the Counter class, which lasts long and therefore should be done in branch. Firstly, he creates the branch:

### Command Line

svn copy localhost/repos/sandbox/Hanoi/trunk/ localhost/repos/sandbox/Hanoi/branches/performance/ -m "Creating the performance branch"

### Tortoise SVN

Select the Hanoi/trunk folder in the Tortoise Repo-browser -> Right Click -> Copy to... -> Change the URL to http: // localhost/repos/sandbox/Hanoi/branches/performance/ -> OK -> Enter the commit message -> OK

Now the branch is ready and we need a working copy to modify. We can of course checkout the new working copy out of branch, but it is easier to switch the existing WC into branch. Switching has the advantage that it preserves the local modifications (if any). Therefore we can start working on some task and afterwards decide, that this requires branch and switch into the branch together with the changes.

### Command Line

cd \temp\bob\hanoi

svn switch localhost/repos/sandbox/Hanoi/branches/performance/

The command shows all the changes made to the working copy. To verify, that we are really in branch, we can use

svn info

### Tortoise SVN

Right Click on \temp\bob\hanoi -> TortoiseSVN  -> Switch... -> Change the URL to localhost/repos/sandbox/Hanoi/branches/performance/ -> OK

The actual changes to Counter.java class are in the folder 3 in sources zip file - you can copy it into the working copy. Of course, this change is far too trivial to be done in branch, but it's good enough as a sample. Now Bob commits the changes and switches his working copy back to trunk:

### Command Line

svn commit -m "Counter optimized"

svn switch localhost/repos/sandbox/Hanoi/trunk/

Notice, that the Counter.java file was updated back to it's trunk content

### Tortoise SVN

Right Click on \temp\bob\hanoi -> TortoiseSVN  -> Switch... -> Change the URL to localhost/repos/sandbox/Hanoi/branches/trunk/ -> OK

The last operation to finish the performance optimization is merging the changes back to trunk. This has two steps - first we merge the changes from branch into the trunk working copy and after verifying the result (and merging possible conflicts) we commit the result into the repository.

### Command Line

Firstly, we need to determine revision since which we want to merge the changes - in our case it's the revision in which the branch was created (you can use e.g. svn log command to discover the revision number). In my case, it's revision 5:

svn merge -r 5:HEAD http:// localhost/repos/sandbox/Hanoi/branches/performance/ --dry-run

Firstly we perform just the dry run, which prints all the information, but does not modify any files - we us it to verify correctness of the arguments. After checking the result, we can perform the actual merge:

svn merge -r 5:HEAD localhost/repos/sandbox/Hanoi/branches/performance/

After testing the result, we can commit

svn commit -m "Merging the performance branch"

### Tortoise SVN

Right Click on \temp\bob\hanoi -> TortoiseSVN  -> Merge... -> Change the From URL to http:// localhost/repos/sandbox/Hanoi/branches/performance/, use the Show Log to select the From revision (select the first revision, which actually contains the changes). select HEAD as To revision -> Press Dry Run to check the parameters are correct -> press Merge to perform the actual merge.

Now test the merge result and do commit afterwards:

Right Click on \temp\bob\hanoi -> SVN Commit... -> Fill in the commit message -> OK.


Now you can use the svn log or TortoiseSVN Show Log to examine all the changes done today.


And that's all. Today, we have imported project, edited the files, created branch, worked in branch and merged it back to the trunk. It was only the overview of basic operations, we avoided more complex use cases (like conflict resolution) and we also did present only one way to perform each task. However, this initial walk thought should give you the overall feeling of how things work and also the basis to explore the other commands and the options of the commands we have already used.

This is the end of the Part 3 of Subversion series. The next (and last) part will focus on process of migration from other Version Control System to Subversion and also will give some hints for adopting Subversion into the development process.

Michal Dobisek is Software Architect at Polarion Software GmbH. He has experience with CVS, Perforce and Subversion. He has two years experience in using, administering and tweaking Subversion. He holds a Masters degree in Cybernetics from Gerstner Laboratory of the Czech Technical University in Prague.

About the author

AgileConnection is a TechWell community.

Through conferences, training, consulting, and online resources, TechWell helps you develop and deliver great software every day.