SVN Page

From CUC3
Revision as of 11:12, 30 November 2006 by import>Am592 (→‎Differences)
Jump to navigation Jump to search

Catherine suggested that we put all the bits and pieces we learn about SVN in one place. A jolly good idea as I do tend to forget about things!


As a CVS user, migrating to SVN was not without it's hiccoughs. I found the biggest one to be that SVN commands like svn diff, svn status (and maybe a few more) work against the pristine revision located in the .svn subdirectory in your working directory and not the latest revision in the SVN repository. In contrast, CVS commands always work against the latest revision in the CVS repository.

In the discussion that follows, call the pristine revision in the working directory BASE and the latest revision in the SVN repository HEAD.

Another hiccough is the use of revision numbers. This topic has been dealt with very well in the Subversion book [1]. See the section on SVN DIFF for a discussion of some of the issues related to version numbers that might make a CVS user weep.

--alston 18:10, 28 November 2006 (GMT)

Setting up your SVN details

(1) If you've got an account on the SVN server at WWMM, you should have a certificate file need by SVN to authenticate a session. Let's call this file svn_cert.p12. Place it in a convenient place, say, $HOME/certificates/

(2) Now edit the file $HOME/.subversion/servers It should contain the lines:

[groups]
wwmm = wwmm.ch.cam.ac.uk
                                                                                
[wwmm]
ssl-client-cert-file = $HOME/certificates/svn_cert.p12
ssl-client-cert-password = <the password Catherine gave you>

I'm not sure if you have to put your password there, but if you do, SVN won't prompt you for a password each time you try to use it.

(3) I found it convenient to define an environment variable pointing to my SVN directory on the WWMM server:

SVN=https://wwmm.ch.cam.ac.uk/svn/users/am592
export SVN

You could just add those lines to your .bashrc file.

Now you are set.

--alston 14:22, 31 October 2006 (GMT)

Creating a Project

There seem to be a couple of ways of doing this. The method reccommended by the SVN book (Version Control with Subversion - O'Reilly) is to use svnadmin create. This won't work as none of us users have access to the svnadmin command. The following works quite well:

$ svn mkdir $SVN/project1

This will create directory project1 in the repository. The svn mkdir command can also be used to make a directory in your working copy, but more on this later.

Now your project has its own directory on the SVN server. Let's get the files into it.

$ ls my_code
a.f90  b.f90
$ svn import my_code $SVN/project1
Adding     my_code/a.f90
Adding     my_code/b.f90
Committed revision 1.

That's done. Notice that the project is called my_code in my directory but project1 on the server. The names could be the same. --alston 14:22, 31 October 2006 (GMT)

Checking out a project

To check out a project from the repository:

$ svn checkout $SVN/project1 [PATH]

where $SVN/project1 is the URL for the project in the repository. If PATH is not given, subversion will create the same directory structure for you (if PATH is given, it will create any directories which don't exist).

svn co is shorthand for the svn checkout.

--james 13:50, 31 October 2006 (GMT)

Help

svn help <command> is very useful, as is the O'Reilly book, which available free online (and for download) here: SVN book.

--james 12:34, 31 October 2006 (GMT)

Differences

It's exceptionally useful to check the difference between a local file and the repository version. svn does provide svn diff, but this uses the standard diff engine, which is somewhat unhelpful. You (apparently) can change your diff engine (e.g. to xxdiff) in your ~/.subversion/config file, but I have never got this to work. Instead, I wrote a function using svn cat in my ~/.bashrc which does the job:

svndiff () {
    if [ "$#" -eq 0 -o "$1" == "-help" -o "$1" == "--help" ];    then
        echo "Usage: svndiff <file> [-r revision_number]"
        echo "Compare local copy to specified revision in the subversion"
        echo "repository (default: last commit) using xxdiff."
    else
        tempfile='/tmp/'`basename $1`
        svn cat $@ > $tempfile
        xxdiff $1 $tempfile
    fi
}

The servers do not have xxdiff installed, but they do have vimdiff, which works similarly. You can pass flags through such as revision number, so long as they come *after* the filename.

--james 12:34, 31 October 2006 (GMT)

The workstations definitely have xxdiff and it could be installed on the servers too - mail me if you want it installing --Catherine 12:34, 1 November 2006 (GMT)

CVS users use cvs diff in just two ways. The default behaviour of cvs diff is to difference a file against the latest version in the CVS repository. If a difference against a particular revision of a file was needed, a CVS user might use cvs diff -r N file.name. Things are different with SVN. First of all, the default behaviour of svn diff is to show only local differences; that is, differences against the pristine copy in the working copy (the BASE). Second, while you could use the command svn diff -r N file.name, since SVN maintains global revision numbers, version N of your file is quite likely the same as your current version. SVN provides a different set of commands to take care of these issues.

There are three kinds of differences you'd probably like to make:

(1) A difference against the latest version in the repository:

svn diff -r HEAD ''file.name''
or, if you've defined James' command (above),
svndiff ''file.name'' -r HEAD

As described in the preamble, HEAD refers to the latest version in the SVN repository.

(2) A difference against the pristine version of the file in the working copy:

svn diff ''file.name''
or
svn diff -r BASE ''file.name''
or
svndiff ''file.name''
or
svndiff ''file.name'' -r BASE

So this is the default behaviour of svn diff. The BASE is optional.

(3)

Logs

Logs can quickly become very length, so I find piping svn log through less is a good option (particularly as I tend to be more interested in recent changes). Note that unless you specify a revision number, you will only see the logs of commits from before your last update (so if you commit code, you won't see your own log message until you update your local version). The verbose flag results in the changed paths being printed out as well (very handy!).

Status

svn status returns the status of all the files in the current directory (or the path specified). This is a pain if you have lots of files produced by compiling your code/tex files, Makefiles and the ilk, which are not (and should not be) under source code management. svn status returns these marked by ?, which is not good if you have a few hundred such files. Fortunately, there is a way to change this! Open up ~/.subversion/config in your favourite text editor (which ought to be vi). Lines starting with # are comment lines. Uncomment [miscellany] and global-ignores. In the global ignores line, add any filenames and extensions you wish to ignore (e.g. *.o).

svn info gives you some useful information on a file/path (or current directory if no path is specified).

--james 12:44, 31 October 2006 (GMT)

svn status will return the status of your working copy with respect to your pristine copy located in the .svn sub-directory (the BASE).

If you wish to find out the status of your working copy with respect to the SVN repository (the HEAD), use

svn status --show-updates
or
svn status -u

This is non-intitutive for CVS users as cvs status always returns the status of the working copy w.r.t. the CVS repository.

--alston 16:57, 28 November 2006 (GMT)

Reverting

So, you have made some changes to your code and committed them, and now realise that your changes break everything. One of the strengths of using subversion (and other source code management systems) is to allow you to rollback code, however this is not intuitive in subversion.

svn revert <filename> reverts your *local* version back to the repository version. It doesn't accept a -r flag, so you can't use it to go back to older versions in the repository. It is useful if you've made some temporary changes for testing purposes, as you can revert to your clean code with one command).

(As an aside svn revert -R . will revert all files in the current and lower directories.)

To rollback to a previous version, first you need to find out which revision number you want to revert to. Then use svn update in a cunning way:

svn update -r <revision number>

--james 13:45, 31 October 2006 (GMT)