An Introductory Subversion Tutorial

Faheem Mitha

February 4, 2004

1 Communicating with a local repository

We have two machines, a local one (called local) and a remote one  
(called remote). We first create a local repository where we store our revisions.
# Create svn repository locally. A subversion repository stores data  
# in a Berkeley database format.  
[faheem@local]$ svnadmin create repos
# Contents of repos  
[faheem@local]$ ls -l repos
# Create a checkout area and cd to it  
[faheem@local]$ mkdir wc; cd wc
# check out empty repository into checkout area  
# top level of repository is top level of checkout area  
[faheem@local] ~/wc$ svn co file:///home/faheem/repos .
# Create test directory and cd to it  
[faheem@local] ~/wc$ mkdir test; cd test
# Add test file to checkout area  
[faheem@local] ~/wc/test$ cat foo.txt  
This is a file which  
is about to be committed to the repository.
# Observe that subversion does not currently know about the test directory  
[faheem@local] ~/wc/test$  cd ..; svn st  
?      test
# Schedule test to be added at next commit; observe that `svn add' works  
# recursively by default.  
[faheem@local] ~/wc$ svn add test/  
A         test  
A         test/foo.txt
# Commit `svn ci' commits everything by default  
# Note that some editor environmental variable must be set, eg EDITOR  
# or SVN_EDITOR so `svn ci' knows what to use. Put `export SVN_EDITOR=jed'  
# in .bashrc if necessary.  
[faheem@local] ~/wc$ svn ci  
Adding         test  
Adding         test/foo.txt  
Transmitting file data .  
Committed revision 1.
# Check the log for the commit.  
[faheem@local] ~/wc$ svn log  
No commit for revision 0.  
------------------------------------------------------------------------  
r1 | faheem | 2004-01-18 16:47:31 -0500 (Sun, 18 Jan 2004) | 3 lines  
 
* test: Add new test directory  
* test/foo.txt: Add test file  
 
----------------------------------------------------------------------
# The revision is now saved to the repository. We remove the test/  
# directory but information is still stored locally in the .svn directory.  
[faheem@local] ~/wc$ rm -rf test/; ls -la  
total 16  
drwxrwxr-x    3 faheem   faheem       4096 Jan 18 21:26 .  
drwx------    8 faheem   faheem       4096 Jan 18 15:48 ..  
drwxrwxr-x    7 faheem   faheem       4096 Jan 18 21:24 .svn
# Subversion notices the missing directory and file when checking status.  
[faheem@local] ~/wc$ svn st  
!      test
# The files can be restored by the update command.  
[faheem@local] ~/wc$ svn up  
A  test  
A  test/foo.txt  
Updated to revision 1.
# We now modify the file foo.txt.  
[faheem@local] ~/wc$ cat test/foo.txt  
This is a file which  
has been committed to the repository.
# Subversion notices the file has local modifications.  
[faheem@local] ~/wc$ svn st  
M      test/foo.txt
# We can an obtain a diff from the last revision (in unified diff format).  
[faheem@local] ~/wc$ svn diff  
Index: test/foo.txt  
===================================================================  
--- test/foo.txt        (revision 1)  
+++ test/foo.txt        (working copy)  
@@ -1,2 +1,2 @@  
 This is a file which  
-is about to be committed to the repository.  
+has been committed to the repository.
# We now commit revision 2  
[faheem@local] ~/wc$ svn ci  
Sending        test/foo.txt  
Transmitting file data .  
Committed revision 2.
# The working copy is now out of date with respect to the repository,  
since it is still at revision 1 while the repository is at revision 2.  
[faheem@local] ~/wc$ svn log  
------------------------------------------------------------------------  
r1 | faheem | 2004-01-18 16:47:31 -0500 (Sun, 18 Jan 2004) | 3 lines  
 
* test: Add new test directory  
* test/foo.txt: Add test file  
 
------------------------------------------------------------------------
# Once we upate from the repository after running `svn up', the  
# log shows revision 2.  
[faheem@local] ~/wc$ svn up; svn log  
At revision 2.  
------------------------------------------------------------------------  
r2 | faheem | 2004-01-18 21:34:31 -0500 (Sun, 18 Jan 2004) | 2 lines  
 
* test/foo.txt: Changed file  
 
------------------------------------------------------------------------  
r1 | faheem | 2004-01-18 16:47:31 -0500 (Sun, 18 Jan 2004) | 3 lines  
 
* test: Add new test directory  
* test/foo.txt: Add test file  
 
------------------------------------------------------------------------
# We can still see the differences between the first and second  
# revision by doing an `svn diff' with appropriate arguments.  
[faheem@local] ~/wc$  svn diff -r1:2  
Index: test/foo.txt  
===================================================================  
--- test/foo.txt        (revision 1)  
+++ test/foo.txt        (revision 2)  
@@ -1,2 +1,2 @@  
 This is a file which  
-is about to be committed to the repository.  
+has been committed to the repository.
# Similarly we can selectively view the log for revision 2.  
[faheem@local] ~/wc$ svn log -r2  
------------------------------------------------------------------------  
r2 | faheem | 2004-01-18 21:34:31 -0500 (Sun, 18 Jan 2004) | 2 lines  
 
* test/foo.txt: Changed file  
 
------------------------------------------------------------------------
# We can get back to revision 1 by using `svn up' with appropriate arguments.  
[faheem@local] ~/wc$ svn up -r1; cat test/foo.txt  
U  test/foo.txt  
Updated to revision 1.  
This is a file which  
is about to be committed to the repository.
# We get back to revision 2 by running `svn up' which by default gives  
# the most recent revision committed to the repository, also called HEAD  
[faheem@local] ~/wc$ svn up  
U  test/foo.txt  
Updated to revision 2.
# If we make a local change we later decide we don't want  
[faheem@local] ~/wc$ svn diff  
Index: test/foo.txt  
===================================================================  
--- test/foo.txt        (revision 2)  
+++ test/foo.txt        (working copy)  
@@ -1,2 +1,3 @@  
 This is a file which  
 has been committed to the repository.  
+Here is a new line.
# we can revert back to revision 2.  
[faheem@local] ~/wc$ svn revert test/foo.txt  
Reverted 'test/foo.txt'

2 Communicating with a remote repository

# To communicate with a remote repository it is convenient to set up a  
# passwordless login. The first step is to generate dsa or rsa keys. It  
# is simplest to use a blank passphrase.  
[faheem@local]$ ssh-keygen -t rsa  
Generating public/private rsa key pair.  
Enter file in which to save the key (/home/faheem/.ssh/id_rsa):  
Enter passphrase (empty for no passphrase):  
Enter same passphrase again:  
Your identification has been saved in /home/faheem/.ssh/id_rsa.  
Your public key has been saved in /home/faheem/.ssh/id_rsa.pub.  
The key fingerprint is:  
...
# Copy rsa public key to remote.  
[faheem@local]$ scp .ssh/id_rsa.pub faheem@remote:.ssh/id_rsa.pub.local  
faheem@remote's password:  
id_rsa.pub           100% |****************************************************************************|   239       00:00
# Rename id_rsa.pub.local to authorized_keys or add it to  
# authorized_keys if it exists.  
[faheem@remote] ~/.ssh$ mv id_rsa.pub.local authorized_keys  
[faheem@remote] ~/.ssh$ cat authorized_keys id_rsa.pub.local >  authorized_keys.tmp;  
                        mv authorized_keys.tmp authorized_keys
# Now we can ssh to remote without logging in. Assume there is a  
# repository on remote identical to that on local, which we check out.  
[faheem@local]$  mkdir wc_remote; cd wc_remote;  
               svn co svn+ssh://remote/home/faheem/repos .  
A  test  
A  test/foo.txt  
Checked out revision 2.
# We can similarly send commits back to the remote repository.  
[faheem@local] ~/wc_remote$  svn diff  
Index: test/foo.txt  
===================================================================  
--- test/foo.txt        (revision 2)  
+++ test/foo.txt        (working copy)  
@@ -1,2 +1,3 @@  
 This is a file which  
 has been committed to the repository.  
+We now make a change locally which will be committed remotely.
# Once automatic login is set up, the commit happens transparently.  
[faheem@local] ~/wc_remote$ svn ci  
Sending        test/foo.txt  
Transmitting file data .  
Committed revision 3.
# If we update the working copy, we see that the local change has been sent.  
[faheem@local] ~/wc_remote$ svn up; svn log  
At revision 3.  
------------------------------------------------------------------------  
r3 | faheem | 2004-01-18 23:51:19 -0500 (Sun, 18 Jan 2004) | 2 lines  
 
* test/foo.txt: Making local change which will be sent to remote  
  repository.  
 
------------------------------------------------------------------------  
r2 | faheem | 2004-01-18 21:34:31 -0500 (Sun, 18 Jan 2004) | 2 lines  
 
* test/foo.txt: Changed file  
 
------------------------------------------------------------------------  
r1 | faheem | 2004-01-18 16:47:31 -0500 (Sun, 18 Jan 2004) | 3 lines  
 
* test: Add new test directory  
* test/foo.txt: Add test file  
 
------------------------------------------------------------------------