Subversion - gher-uliege/Documentation GitHub Wiki

Subversion is an open source version control system (VCS).
The tool was the main VCS at GHER from 2008 to 2016. Since then, git has been increasingly used and several projects have been moved from SVN to git.

Documentation

Installation of Subversion on a server

sudo aptitude install subversion
sudo addgroup subversion
sudo adduser abarth subversion
sudo mkdir /home/svn
cd /home/svn
sudo mkdir repos
sudo chown -R www-data repos
sudo chgrp -R subversion repos
sudo chmod -R g+rws repos
sudo svnadmin create /home/svn/repos
sudo chmod -R g+rws /home/svn
sudo chgrp -R subversion /home/svn

Add a user to subversion

Create a user account on modb which belongs to the group "subversion".
From the command line:

sudo adduser aalvera
sudo adduser aalvera subversion

or using the GUI

sudo users-admin

It is advisable to use SSH keys and ssh-agent to cache your passphrase. Otherwise, Subversion will prompt you to enter your password/passphrase several times when communicating with the server. For more information: https://help.ubuntu.com/community/SSHHowto and instructions can be found here: http://fedoranews.org/dowen/sshkeys

Typical layout of a repository

For example, your repository might look like:

  calc/
     trunk/
     tags/
     branches/
  calendar/
     trunk/
     tags/
     branches/
  spreadsheet/
     trunk/
     tags/
     branches/

trunk : common development version

tags : contains the released versions of software. They are usually not changed afterwards

branches : parallel development branches contains usually new feature which are not yet well tested. Once the branch has stabilized it is merged into trunk.

Setting up a new project

Create a project with the following directory structure

mkdir tmpdir
cd tmpdir
mkdir -p projectA/{trunk,branches,tags}

Import this into the repository:

svn import . svn+ssh://modb.oce.ulg.ac.be/home/svn/repos --message 'Initial repository layout'

Clean-up:

cd ..
rm -rf tmpdir

Download a working copy

svn co svn+ssh://modb.oce.ulg.ac.be/home/svn/repos/projectA/trunk projectA
Checked out revision 0.

Add a file to the repository

cd projectA
cp /somewhere/hello.f90 .

svn add hello.f90
A         hello.f90

svn commit -m 'add some file'
Adding         hello.f90
Transmitting file data .
Committed revision 1.

Edit

Make some changes. Examine differences with

$ svn diff
Index: hello.f90
===================================================================
--- hello.f90   (revision 1)
+++ hello.f90   (working copy)
@@ -1,5 +1,6 @@
 program hello
  implicit none
+ integer :: i
\
  write(6,*'hello world'

Upload changes

svn commit -m 'add integer'

Don't Forget ...

... to make backups! It's possible to dump the contents of the repository (including all revisions) into a dumpfile. This format is portable, and you can use it to reconstruct a repository if necessary.

`svnadmin dump /home/svn/repos | gzip -9 > svndump-$(date +%Y%m%d-%H%M).gz

This way, the repository can be restored via

gunzip -c `<file>`.gz | svnadmin load /home/svn/repos

Restore

gunzip -c .gz | svnadmin load /home/svn/repos

SSH configuration

The following configuration allows you to access the subversion server on modb without entering your password all the time. All commands shown hereafter are to be exectuted on your local machine (normally you do not need to work directly in your modb account)

Include the following in your file ~/.ssh/config file (create it if it does not exist):

Host modb gher04 modb.oce.ulg.ac.be
  HostName modb.oce.ulg.ac.be
  ForwardAgent yes
  User `<your username on modb>

It is also convenient to define the following:

Host *
  ForwardX11 yes
  ForwardAgent yes

Create a SSH key:

ssh-keygen -t rsa -b 4096 -C "some comment"

Copy your SSH key to modb:

ssh-copy-id -i ~/.ssh/id_rsa.pub modb

Main commands you will need

Execute the commands on your computer at the directory where your copy of the project is found.

List existing projects

svn list svn+ssh://[email protected]/home/svn/repos

Download a project, for example Gher3D:

svn checkout svn+ssh://[email protected]/home/svn/repos/Gher3D/trunk local-directory

If you downloaded the files before, update your local version with the command:

svn update

Edit the files in your local directory. To see changes between local and repository:

svn diff

To add or delete files on the repository, use

svn add filename
svn delete filename
```bash
To actually commit these changes on the server, use
```bash
svn commit -m "some comments"

For a good tracking of the changes, try to add comments when you do the commit.

Download a project under SVN

To find out which projects are in the modb.oce.ulg.ac.be subversion repository:

svn list svn+ssh://modb.oce.ulg.ac.be/home/svn/repos
```bash

If the user-name on the local machine is not the same as on the server
you can use something like
```bash
svn [command] svn+ssh://[email protected]/home/svn/repos

Download a particular revision of a project

If you are interested in a particular revision of a project (let's say, the number 3008), you can use the command checkout with additionnal arguments:

svn checkout svn+ssh://modb.oce.ulg.ac.be/home/svn/repos/Project_Name@3008

Make release(s) or branch(es)

These operations simply consists in copying the trunk to a another directory.

Release(s)

The trunk is copied to a directory under tags:

svn copy svn+ssh://modb.oce.ulg.ac.be/home/svn/repos/projectA/trunk svn+ssh://modb.oce.ulg.ac.be/home/svn/repos/projectA/tags/r1.1 -m 'release 1.1'

Subversion stores only differences between files. The command svn copy does thus not physically copy the whole repository. To checkout a particular release, we need only to specify its location:

svn co svn+ssh://modb.oce.ulg.ac.be/home/svn/repos/projectA/tags/r1.1 projectA

Branch(es)

Now the trunk is copied to the directory branch:

svn copy svn+ssh://modb.oce.ulg.ac.be/home/svn/repos/projectA/trunk \
         svn+ssh://modb.oce.ulg.ac.be/home/svn/repos/projectA/branches/parallel -m 'MPI version'

To checkout a branch, we need only to specify its location:

svn co svn+ssh://modb.oce.ulg.ac.be/home/svn/repos/projectA/branches/parallel projectA

When working with multiple branches, it might be useful to checkout everything:

svn co svn+ssh://modb.oce.ulg.ac.be/home/svn/repos/projectA`\
A    projectA/trunk
A    projectA/trunk/hello.f90
A    projectA/trunk/Makefile
A    projectA/branches
A    projectA/branches/parallel
A    projectA/branches/parallel/hello.f90
A    projectA/branches/parallel/Makefile
A    projectA/tags
A    projectA/tags/r1.0
A    projectA/tags/r1.0/hello.f90
A    projectA/tags/r1.0/Makefile

Keeping a branch in sync

To avoid that trunk and branche diverge, it is good to reintegrate the changes done in the trunk to the branch on a regular basis. All changes of the branch have to be commited, then

cd /path/to/branch
svn status # no changes
svn merge ^/OAK/trunk

Before merging a branch back to the trunk, it is safer to merge first all changes from trunk to the branch and test the code.

See "Keeping a Branch in Sync" http://svnbook.red-bean.com/en/1.7/svn.branchmerge.basicmerging.html.

Reintegrate branch to trunk

After running the steps in "Keeping a branch in sync", one can reintegrate the branch into trunk:

cd /path/to/trunk
svn up
svn status
svn commit -m 'last changes'
svn up
svn merge --reintegrate ^/divaonweb/branches/divaonweb-nginx

File history and differences

As SVN stores the differences between versions of a same file, tracking changes is very easy.

History of a file

Use the command svn log with the name of the file as argument. The log indicates:

  • who modified the file and when it was modified
  • the revision number corresponding to the revision
  • a message explaining the change (the ''-m 'message for commit' '' option of svn commit)
$ svn log hello.f90`\
------------------------------------------------------------------------
r10 | abarth | 2008-02-24 18:02:35 +0100 (Sun, 24 Feb 2008) | 1 line 
\
add a real
------------------------------------------------------------------------
r2 | abarth | 2008-02-22 21:57:57 +0100 (Fri, 22 Feb 2008) | 1 line
\
add some file
------------------------------------------------------------------------

Changes on a file

Check the diff command in the SVN bool: http://svnbook.red-bean.com/en/1.7/svn.ref.svn.c.diff.html

What is the difference between version 10 and 2:

$ svn diff -r 10:2 hello.f90
Index: hello.f90
===================================================================
--- hello.f90   (revision 10)
+++ hello.f90   (revision 2)
 @@ -1,7 +1,6 @@
 program hello
  implicit none
  integer :: i
- real :: r
\
  write(6,*'hello world'

If you type only

svn diff hello.f90

the output will be the differences between the last committed version and the version you are working on.

Add options to the diff command

If the tabulations and/or spaces in the file have changed, then the

svn diff

command will yield a long list of differences that you probably don't care about. In this case, you would prefer to use

diff -E -b -w

where

  • -E : Ignore changes due to tab expansion.
  • -b : Ignore changes in the amount of white space/
  • -w : Ignore all white space.

To force svn to use these optional arguments, the syntax is as follows:

svn diff --diff-cmd diff -x "-E -w -b" -r10:2 hello.f90

or

svn diff --diff-cmd /usr/bin/diff -x "-E -w -b" -r10:2 hello.f90

Hence it is the --diff-cmd option that allows the user to select the diff command, while the argument placed after the -x are the actual options of the diff command.

Undoing changes

For situations when you want to go back to an older version of a file, the command to use is svn merge, as explained at http://svnbook.red-bean.com/en/1.2/svn.branchmerge.commonuses.html#svn.branchmerge.commonuses.undo

The typical steps to follow are:

1. Roll back the changed made:

svn merge -r 3010:3008 svn+ssh://modb.oce.ulg.ac.be/home/svn/repos/projectA/trunk/file_to_modify

2. Check the status

svn status
M  file_to_modify

3. Check if the unwanted changes are removed:

svn diff

4. Commit

svn commit -m "Undoing change committed in r3010."

Managing conflicts

Before solving conflicts, the best thing is to try to avoid them. If you know you are going to work on a same projects with other colleagues at the same time, try to work on different files.

If for some reasons you have to face conflicts, the first thing is to consult the SVN book: http://svnbook.red-bean.com/en/1.7/svn.tour.cycle.html#svn.tour.cycle.resolve

Diagnosing conflicts

The conflicts will appear when you use the command

svn update

If you try to commit when a conflict was detected, then the commit will be aborted.

Different possibilities can occur for a given file. If before the name of the file you have

  • U: it means that the file was updated.
  • G: the file was merged, meaning that your modifications and those from the other users were done without any overlap.
  • Conflict discovered in file_name: a conflict has to be solved.

Resolving the conflict

In that case, several options are offered:

  • (p) postpone: the conflict will be resolved later
  • (df) diff-full: show all changes made to merged file
  • (e) edit: change merged file in an editor
  • (mc) mine-conflict: accept my version for all conflicts (same)
  • (tc) theirs-conflict: accept their version for all conflicts (same)
  • (s) show all options.

For ever conflicted file, three extra unversioned files are created in your working copy:

  1. filename.mine
  2. filename.rOLDREV
  3. filename.rNEWREV

Once you have solved the conflict, use the command

svn resolved file_name

and commit the file. The three intermediate files will be removed automatically.

Nested check-outs

An SVN checkout within an SVN checkout from a different repository is possible, using the svn:externals property:

`svn propget svn:externals . > /tmp/svn_external

add a line to the file /tmp/svn_external (maybe empty) with the local directory name and the URL:

ncArray https://svn.code.sf.net/p/octave/code/trunk/octave-forge/extra/ncArray/inst

Update the properties and checkout

svn propset svn:externals  -F /tmp/svn_external .
svn up

Notes and caveats

  • When working over SSH, it is advisable to use keys and ssh-agent to cache your passphrase. Otherwise, Subversion will prompt you to enter your password/passphrase several times when communicating with the server.

  • Avoid using two files with the same name in the same directory using different lower case and upper case letters. This can cause trouble when using SVN on some systems (Windows-Dos).

Change the permissions of a file

For example to set a file permission to executable), do not use

chmod +x filename
svn commit -m 'changed permission'

since no change on the file will be captured by svn. The solution is to use

svn propset `[`svn:executable`](svn:executable)` '*' filename
svn commit -m 'changed permission'

Source: http://lexfridman.com/blogs/research/2011/02/21/executable-files-in-svn/

'out of date' error during the commit

The message looks like

Transmitting file data .......svn: Commit failed (details follow):                               
svn: While preparing 'filename' for commit
svn: File 'filename' is out of date 

Possible solution: use the update command

svn delete filename
svn commit -m 'message'
svn update 
svn add filename
svn commit -m 'another message'

Add only new files to subversion

svn add *

will work but gives warning messages. Another solution is

svn status | grep -v "^.[ \t]*\..*" | grep "^?" | awk '{print $2}' | xargs svn add

which looks for files of which the status is ?

Source: http://snipplr.com/view/15471/

⚠️ **GitHub.com Fallback** ⚠️