A Brief Overview of Version Control with SVN

By James Gregson, January 2013

Introduction

On any serious project, including programming projects, labs and assignments, you should be using some form of source version control. Version control allows you to keep a history of the code you're developing in a repository while you work on a second working copy. As you work and make changes to the code, you periodically check in or commit changes made to your working copy, which updates the repository.
 
By using version control, you protect yourself against accidentally deleting important files, as long as you don't delete the repository itself! You also reduce the risk of new changes breaking the codebase and not remembering how to undo those changes, since if you commit often you should never lose more than an hour or so of work. Consequently you should check in often; periodically as you work, any time that new functionality is finished, and immediately before making large changes.
 
Getting into this habit will (someday) save you days or weeks of lost work and frustration. Maybe not this course or this year, but eventually everyone messes up and loses some code. And it's awful, particularly if it's your final project that's due in two hours. So use version control!
 

Basic Subversion (SVN) Usage

Subversion is a commonly used source version control package available as command-line tools on Linux and Mac and on Windows via the Tortoise SVN interface.
 
The following instructions will guide you through setting up a repository on the department machines using the command line, which you can then access from anywhere. The focus is on the command line, but GUIÕs such as Tortoise SVN will use similar operations even though they are accessed through a UI.
 
The basic process is the following:
  1. Create a repository on remote.ugrad.cs.ubc.ca
  2. Add your new project to the repository
  3. Check out a working copy of your project
  4. Work on your project as usual from the working copy, checking in changes as you go
  5. Profit!
These steps are described in detail in the following sections.
 

Creating a Repository

You should only need to do this once when you are first starting to use SVN. Once you have a repository set up, you can add multiple new projects to it without any problems. Just be sure to put each into its own directory as discussed below.
 
First SSH to remote.ugrad.cs.ubc.ca and log in with your CS account
 
Create a SVN directory in your home directory with the command. This will hold your SVN repositories.
 
            $ mkdir ~/SVN
        
Next create the SVN repository by running the following:
 
            $ svnadmin create SVN
        
This will create an SVN repository in the SVN directory that you can access remotely. Finally run the following commands to get the full path to your repository:
            $ cd SVN
            $ pwd
        
Take note of the output of the pwd command; you will be typing it a lot. In the rest of this document it will be referred to as REPO-PATH, but you should type in the full path.
 
NEVER do anything to the SVN repository directory except through the svn commands discussed here, or in other SVN references. The directories in the SVN repository are a database of changes, not simply a set of code copies. Editing the subdirectories directly can break this database, losing your entire version history!
 
You can now start adding files to your repository using the svn commands described below. Generally you will want to group these into directories (OUTSIDE THE SVN DIRECTORY!) so projects don't get mixed together. At this point you can log out of remote.ugrad.cs.ubc.ca and work from whatever machine you like.
 

Adding a Project to Version Control

Suppose that you are currently in a directory 'simplex' on your local machine that has files that you want to add to version control. Typically this would be the directory where you have extracted lab/assignment templates. The first step is to create a directory to hold it in the remote repository.
 
Run the following from the command line, replacing USER with your CS account login name and REPO-PATH with the path to your repository:
 
            $ svn mkdir svn+ssh://USER@remote.ugrad.cs.ubc.ca/REPO-PATH/simplex -m "created project directory"
        
If prompted for a password, type it in and hit enter. You should see:
 
            Commited revision 1
        
This means there is now a place for simplex in the repository hosted on remote.ugrad.cs.ubc.ca. You can now add the files from your local machine to the remote repository using the import command from the simplex directory:
 
            $ svn import . svn+ssh://USER@remote.ugrad.cs.ubc.ca/REPO-PATH/simplex -m "added initial files"
        
Enter your password again, if asked. You should see something like the following, although the filenames will be different:
 
            Adding         build
            Adding         code
            Adding         code/source
            Adding         code/source/simplex.c
            Adding         code/source/main.c
            Adding         code/include
            Adding         code/include/simplex.h
            Adding         code/CMakeLists.txt
            
            Committed revision 2.
        
At this point you are ready to go! You can start using SVN on the current project (simplex in this example) using the path svn+ssh://USER@remote.ugrad.cs.ubc.ca/REPO-PATH/simplex from anywhere with SVN installed.
 

Checking Out a Working Copy

Before starting to work, you need to check out a working copy of your project. checking out is just a way of saying "retrieve from the repository" and a working copy is simply a directory that holds files retrieved from your SVN repository. You work on these files independently from the repository and periodically check them into the repository to save a history.
 
The working copy can be anywhere on your local computer, I keep mine in ~/Code, but they can be anywhere and you can have more than one working copy of the same repository, although usually that is not necessary.
 
To check out a working copy of the simplex project, first create a directory to hold the files and then use SVN to retrieve them. Be sure to change the paths in the mkdir and cd commands to match where you want to work from.
 
            $ mkdir ~/Code/simplex
            $ cd ~/Code/simplex
            $ svn checkout svn+ssh://USER@remote.ugrad.cs.ubc.ca/REPO-PATH/simplex
        
You should see a bunch of output like the following:
 
            A    simplex/build
            A    simplex/code
            A    simplex/code/source
            A    simplex/code/source/simplex.c
            A    simplex/code/source/main.c
            A    simplex/code/include
            A    simplex/code/include/simplex.h
            A    simplex/code/CMakeLists.txt
            Checked out revision 2.
        
At this point you have a local working copy and you can start using the code normally, with a few changes. From here on, IÕm assuming you have a terminal open in the working copy directory.
 

Committing Changes

As you work, you should periodically commit your code to the repository. Each time you commit is a time that you can revert to should disaster strike so the more commits the better, although it's best if your code actually builds and (sort-of) runs at each commit. You can commit your code with the command line:
 
            svn commit -m "description of changes, state, etc"
        
This will only create a history for files that are version-controlled, which are currently just the files that were originally imported. Other files need to be added to the repository as they are added to the working copy, see below.
 
Always use helpful, descriptive comments for the -m "description" argument. This will help you find specific versions of the code later on if you need to revert to an older version.
 

Adding New Files to the Working Copy

When you add a file (e.g. file.ext) locally to your working copy, you should add it to the SVN repository, thus placing it under version control. You can do this with the svn add command, e.g.
 
            $ svn add file.ext
        
Don't both adding executable or temporary files that are generated by the compiler since these will clutter up the repository and make it take a long time to check out and commit changes. Just put source code, project files and input files into the repository.
 
After adding a file be sure to run svn commit or your 'added' file will not be under version control until the next time you commit
 

Check the Repository Status

You can check what files are under version control in the repository and their status using the command svn status, e.g.:
 
            $ svn status
            ?       build/CMakeCache.txt
            ?       build/CMakeFiles
            ?       build/cmake_install.cmake
            ?       build/CMakeScripts
            A       build/simplex.xcodeproj
            A       build/simplex.xcodeproj/project.pbxproj
            M       code/source/main.c
        
The '?' means a file is not under version control, 'A' means the file was added and 'M' means it has been modified since the last commit. You should run svn status before committing to be sure that everything is included in the repository that should be included, or after committing to be sure you haven't missed anything. Having files with '?' is OK as long as you don't want them version controlled (e.g. like compiler temporary files).
 

Update a Repository

If you are working with code from third parties or as part of a team, other people may update the repository by committing changes, leaving your working copy out of date. To update your repository to the most recent version, you can use svn update. This will fetch any new files that have been added and overwrite any existing files in your working copy directory with the most recent version, provided you haven't modified these files yourself.
 
        $ svn update
        
If you have modified files that no-one else has touched, SVN will leave them in place. However if you and someone else have edited the same file, SVN will attempt to merge the two sets of changes automatically. If this fails, or the changes are too sweeping to be merged, SVN reports a conflict will prompt you whether you want to keep your file or use the modified copy from the repository.
 
Dealing with conflicts can be painful and beyond the scope of this quick tutorial. However you can often avoid conflicts entirely by communicating with your teammates about who is making changes to what file, keeping your commits small and compact, and updating frequently. When you make a commit, tell your teammates about it directly or by email so they know to update their working copies.
 

Remove a file from version control

If your code no longer needs a specific file, file.ext, you can delete it from the repository using svn remove
 
            $ svn remove file.ext
        
Removed files display a 'D' when svn status is run. As in the case of add, it will not be actually removed until you next run svn commit. Files are only removed from the most recent revision (the 'HEAD' revision), any earlier versions referring to the file will be unaffected.
 

Revert to a Previous Version

If you've messed something up in your code you can easily go back to a previous version of the code. First you have to find the code version you want to go back to. The command svn log will print a log of the version history including those helpful commit messages that you were sure to include:
 
            $ svn log
            ------------------------------------------------------------------------
            r2 | jgregson | 2013-01-14 09:29:10 -0800 (Mon, 14 Jan 2013) | 1 line
            
            added simplex
            ------------------------------------------------------------------------
            r1 | jgregson | 2013-01-14 09:28:41 -0800 (Mon, 14 Jan 2013) | 1 line
            
            made directory
            ------------------------------------------------------------------------
        
Once you know the version to go back to, you can go back to it with 'svn merge':
 
            $ svn merge -rHEAD:2
        
Where you should replace the '2' with the appropriate version number.
 

Conclusions

If you've followed and understood these steps you should now be able to work effectively with SVN. SVN has many more advanced features that allow you to merge changes from different people back into the repository, blame your friend when he/she breaks the code and more. However the simple commands here should be enough to get you using version control so you don't accidentally lose or overwrite code ever again.
 
There are plenty of resources to start learning more about SVN, the best overall reference is Version Control with Subversion, but there are plenty of blog postings and web-forums that can provide answers to specific 'How do I ...' questions.