Dalke Scientific Software: More science. Less time. Products

Version Control

Subversion is a version control system. The SVN book contains all the details. Quoting from http://www.owlnet.rice.edu/~comp314/svn.html:

An important element of the modern software development process is source control (or version control). Cooperating developers commit their changes incrementally to a common source repository, which allows them to collaborate on code without resorting to crude file-sharing techniques (shared drives, email). Source control tools track all prior versions of all files, allowing developers to "time travel" backward and forward in their software to determine when and where bugs are introduced. These tools also identify conflicting simultaneous modfications made by two (poorly-communicating) team members, forcing them to work out the correct solution (rather than blindly overwriting one or the other original submission).

I'll walk through how to use subversion with the command-line tools. There are also GUIs like TortoiseCVS for Windows and various IDEs ,like WingWareIDE and Eclipse integrate SVN support.

The version control system puts all versions of a file in a place called repository. The first step in using SVN is to set up a repository. This will be used by everyone working on the project. I'm going to set up a repository on the server machine at 192.168.1.1 in my home directory named "svn-repo". I need to log into that machine and do the following:

svnadmin create /home/andrew/svn-repo
You only need one repository per project, so nominate someone's account for the repository owner.

Subversion strongly recommends a specific layout for your project. I'll start a project called "human_genome_project" with the correct layout.

[~/tmp] % mkdir human_genome_project
[~/tmp] % mkdir human_genome_project/trunk
[~/tmp] % mkdir human_genome_project/branches
[~/tmp] % mkdir human_genome_project/tags
The main work goes into the trunk. Use "branches" for things which modify the trunk but which might be thrown away. These are often experimental explorations. The tags directory collects a specific version of files from the repository. For example you might make a tag which is the files for "Version3".

I'll put a README file in the trunk directory and add everything into SVN.

[~/tmp] % svn import ~/tmp/human_genome_project svn+ssh://andrew@192.168.1.1/home/andrew/svn-repo/HGP -m "initial import"
Adding         /Users/dalke/tmp/human_genome_project/trunk
Adding         /Users/dalke/tmp/human_genome_project/trunk/README
Adding         /Users/dalke/tmp/human_genome_project/branches
Adding         /Users/dalke/tmp/human_genome_project/tags

Committed revision 1.
[~/tmp] % 
I had to use "andrew@" because my local login is "dalke". The '-m "initial import"' is a message that is attached to the checkin information for the new files.

I don't like having to type my password in all the time so I set up SSH to not need a password. It uses cryptography to verify the connection. Here's how to do it. On the machine you want to ssh from, create a key using 'ssh-keygen'. You need to specify the type of key with the '-t' option.

$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/andrew/.ssh/id_dsa): 
Created directory '/home/andrew/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/andrew/.ssh/id_dsa.
Your public key has been saved in /home/andrew/.ssh/id_dsa.pub.
The key fingerprint is:
93:a7:82:18:c6:a5:dc:59:6d:79:f8:7e:e6:1c:24:9a andrew@NBN-Course-Server
This created two files. The public one (the one that others can see without breaking security) is named ~/.ssh/id_dsa.pub. Here are the contents of the file. Note that this is a single line. I broke it up into multiple lines to make it easier to view.
ssh-dss AAAAB3NzaC1kc3MAAAEBAOIRMjnyT2GGJjvBV5txgObfSS6yq7cpEPG7ijil0B
kwN6XE1FjPJVoj5qAeHTinABRGxuI9t0ubLZGQ63sUUQLd4iQ1CZhkRcgLkI2bkFhwuPXZ
4hMXBt6WORZqxAUEdTzTKbtLESpebBD6juLlwul8dlV5hF3XwZxUchH3Wfv+LmPInRrN7i
Y70OmS5y2QaprDO4YDgS2oOxdoqUMfID5n0LVRoqSXwxC4SdxbQj3XWCbFtPjOSyT5HPXO
4DsNPEWUyYRbzGWayRiODs4Wlt3k0MW56kxU60PushcrVMloG/GbUNCA/lLhYYB1i5c4ZO
XbgkSMKIeegOf2oRyDNKMAAAAVAJ6iZHMfrmUYoCVnbNtmpbvSvDn3AAABAQDJfo3tN5Na
T78+Gd+Ml47UNqhG6fQLq1iGAQSDN09AS4aau8tIvwQJst2X7vt+Cjx18Alkk+2+5BE3jW
+3FbKhHeq+jOGKQbRtRU2NEjan6Fj5hUIqMn4RlsZE4Va7t6C2JzwKdE+0BhFQwhoz8Uxc
ouyawPg8qKV/TaVfJTfNRsf/y+3pLZjDEoanMlSIkRWlbvGtmhcdUXK0eFDwGKGvKDY27S
6zEyXqWqUVylXfX1KrN70LRR8ED1tYLCB5EZzI+k/7RVnnb+ww7xLYo7gap2CtvUQ6ukqO
zdircjNYJ30autuNSSqWhq4a1d3SH/ypP91dCAROQ4IboZax2zYpAAABAEhzNugnooiL4O
lG5CFmiP2KtLwbTqtPRZn2CWvhoW7kmJ8irMhkibDPgRAlPnzJCTK7oyFi4O7ZTAbgHNyR
Mt3rHWrI5ASJOut8h1SAB407U8e8IddEHHivrK4btA7E55pwHS5Q6uGX2PxV9UNL3HPiGg
vjWIiPBJEZTM6FLU+MR1bslD6O5Em8ZoKUU9XKjr7Ct7GRthMi4VSGfodOx8rqmH2g25Hz
w9+0HpCu53AExfZmy3LXApVxw/WuWFhu6sBnerMLtp+o7U5k10vVHYSQRXeQN9JSAUzUKT
9QFGS/Q3r4WdwZ4pAkn2AEOmDRvJrpgFR0zlLYsBA4dxLXcxU= andrew@NBN-Course-S
erver
Log into the remote machine. Edit the file ~/.ssh/authorized_keys (which might not exist) and add the above line. Save and log out. Log back in through ssh. It should work without asking you for a password.

Okay, I've added the initial code to the repository. I'll remove the initial code (in real life I rename it, to be on the safe side) and check out the copy from the repository.

[~/tmp] % rm -rf human_genome_project/
[~/tmp] % svn co svn+ssh://andrew@192.168.1.1/home/andrew/svn-repo/HGP
A    HGP/trunk
A    HGP/trunk/README
A    HGP/branches
A    HGP/tags
Checked out revision 1.
Now I'll edit the 'README' file and use 'svn diff' to see the changes in the file.
[~/tmp] % cd HGP/trunk/
[~/tmp/HGP/trunk] % cat README 
The human genome sequencing project, in 3 easy steps
  1. get sample
  2. ???
  3. profit!
[~/tmp/HGP/trunk] % vi README
[~/tmp/HGP/trunk] % svn diff README
Index: README
===================================================================
--- README      (revision 1)
+++ README      (working copy)
@@ -1,4 +1,5 @@
 The human genome sequencing project, in 3 easy steps
   1. get sample
-  2. ???
-  3. profit!
+  2. sequence it
+  3. ???
+  4. profit!
[~/tmp/HGP/trunk] % 
When I've made the changes I check it in using 'svn commit'
[~/tmp/HGP/trunk] % svn commit README 
svn: Commit failed (details follow):
svn: Could not use external editor to fetch log message; consider setting the $SVN_EDITOR environment variable or using the --message (-m) or --file (-F) options
svn: None of the environment variables SVN_EDITOR, VISUAL or EDITOR is set, and no 'editor-cmd' run-time configuration option was found
Oop! I need to tell it which editor to use for making the comment about the check, or use a command-line option to specify the comment
[~/tmp/HGP/trunk] % setenv EDITOR vi
[~/tmp/HGP/trunk] % svn commit README
Sending        README
Transmitting file data .
Committed revision 2.
[~/tmp/HGP/trunk] % 
Every check-in increases the version number of the repository by 1. I can look at the check-in history using the "svn log" command
------------------------------------------------------------------------
r2 | andrew | 2006-07-19 10:18:16 +0200 (Wed, 19 Jul 2006) | 2 lines

I need to sequence the genome after taking a sample

------------------------------------------------------------------------
r1 | andrew | 2006-07-19 09:36:27 +0200 (Wed, 19 Jul 2006) | 1 line

initial import
------------------------------------------------------------------------

I'll add a new file to subversion using 'svn add'.

[~/tmp/HGP/trunk] % vi print_sequence.py
[~/tmp/HGP/trunk] % cat print_sequence.py 
#!/usr/bin/env python
print "ATACGATCTGCATGATCGA"
[~/tmp/HGP/trunk] % chmod +x print_sequence.py 
[~/tmp/HGP/trunk] % ./print_sequence.py 
ATACGATCTGCATGATCGA
[~/tmp/HGP/trunk] % svn add print_sequence.py 
A         print_sequence.py
[~/tmp/HGP/trunk] % 
I could check it in now but I'll also modify the README to describe what to do with this new file.
[~/tmp/HGP/trunk] % vi README 
[~/tmp/HGP/trunk] % svn diff README
Index: README
===================================================================
--- README      (revision 2)
+++ README      (working copy)
@@ -1,5 +1,5 @@
 The human genome sequencing project, in 3 easy steps
   1. get sample
-  2. sequence it
+  2. sequence it (use 'print_sequence.py' to see the result)
   3. ???
   4. profit!
[~/tmp/HGP/trunk] % 
and then check in all changes
[~/tmp/HGP/trunk] % svn commit
(I could also have commited only those two files by listing them on the command line
[~/tmp/HGP/trunk] % svn commit README print_sequence.py
). Here's what the editor showed me during the commit

--This line, and those below, will be ignored--

AM   trunk/print_sequence.py
M    trunk/README
Here's the full commit transaction
[~/tmp/HGP/trunk] % svn commit
Sending        trunk/README
Adding         trunk/print_sequence.py
Transmitting file data ..
Committed revision 3.
[~/tmp/HGP/trunk] % 
Both files were committed at the same time and have the same log message.

Subversion has a way to show when a given line of a file was changed, using the "svn annotate" (or "svn ann" or "svn blame" or "svn praise") command. This is very useful when you find a bug (or a fix) in the code - you can see when it was added and why.

[~/tmp/HGP/trunk] % svn annotate README
     1     andrew The human genome sequencing project, in 3 easy steps
     1     andrew   1. get sample
     3     andrew   2. sequence it (use 'print_sequence.py' to see the result)
     2     andrew   3. ???
     2     andrew   4. profit!
[~/tmp/HGP/trunk] % 

There are many other SVN commands. The two most useful are

It's pretty obvious what they do. :)



Copyright © 2001-2013 Andrew Dalke Scientific AB