Subsections

A. Common operations

In true Perl spirit there are more than one way to perform the below tasks. It is also assumed that the subversion repository is residing on a server (here, svn.example.com is running a web server with svn support), and calc is used as the example project. Furthermore, since we are anticipating branching of the project, we must prepare our repository for branching. Command examples are typed as

command --with-option example

and

sample output is typed like this

A..1 Setting up a repository

Setting up a new personal repository is straight forward, do

svnadmin create /path/to/svn/repos/project

and subversion is now ready accept addition of projects into the repository. If the repository resides on a server, then you need access to server and do some more initialisation steps (see Appendix E.1).

A..2 Handing over control to subversion

If the repository is empty (still at revision 0), you start by creating the initial directory structure to be imported into the repository, and (optionally) add files to be imported.

mkdir /tmp/myproject/branches
mkdir /tmp/myproject/tags
mkdir /tmp/myproject/trunk
cp ...

Import the project with

svn import /tmp/myproject http://svn.example.com/calc -m "Initial import"

Subversion does not store the root name /tmp/myproject, so these are only temporary names.

A..3 Initial checkout of a project

Assuming we want to checkout the main trunk of the project a simple

svn checkout http://svn.example.com/calc/trunk calc

will do. This will create a sub-directory calc containing the latest revision of the project.

A..4 Set up of editor to use for log messages

There two ways to set your favourite text editor for log message editing. Either you define it in the config file, or set one of the environment variables SVN_EDITOR, VISUAL, or EDITOR to point at your preferred editor. svn will use the first one it finds in the order we described the different possibilities here.

A..5 Undoing changes

If we realize that a change committed to the repository is unwanted we can reverse these by reversing the order of revisions;

svn merge -r 303:302 http://svn.example.com/calc/trunk

Check the changes, and commit if you are happy with them. Magic!

A..6 Undoing svn add (and svn delete)

Sometimes we forget that adding items to subversion control is a recursive action, and as consequence end up with a huge import of files. The easiest way out of this is to use the revert sub-command

svn revert item

where item is whatever you added (or item can be empty, and everything in the current directory will be reverted). Note, this will actually revert all uncommitted changes not just whatever you added.

A..7 Resurrecting deleted items

For this the best solution is to use svn copy as

svn copy -r 807 http://svn.example.com/calc/trunk/real.c ./real.c

The added bonus with this is that subversion will also remember the file history.

A..8 How do I make subversion ignore items when issuing svn status

You can also set what files svn should ignore when running svn status in the config file (see Appendix F).

A..9 Can I add a symbolic link to subversion control

Yes, subversion handles symbolic links (in operating systems where these make sense) automatically, just treat them as any other item.


A..10 Creating a branch

The simplest way to create a branch is to make a copy of the current trunk HEAD (or another revision in the tree) by issuing

svn copy http://svn.example.com/calc/trunk $\backslash$
http://svn.example.com/calc/branches/my-calc-branch $\backslash$
-m "Creating a private branch of /calc/trunk."

This will create a shallow copy, meaning that subversion creates links within the repository until files are actually changed. In consequence branches are inexpensive, and you should not be afraid to create branches. You have to check out the new branch to get access to it. The changes needed to the above command when creating a branch from a tag is straightforward.

You can also create branches within your checked out project (see more in the svn book). There are no real branching in subversion, there are different directories with files that share a common history. Branches is an attribute that the users of subversion attach to the branches directory.

A..11 Porting changes between branches

Sometimes you want to copy changes between branches and this is is accomplished by merging different revisions. Issuing

svn merge -r 343:344 http://svn.example.com/calc/trunk

will perform a local update of your branch using the difference between the revision specified. You should review the changes before committing them into your repository branch. If something went wrong or is unsatisfactory, use svn revert. However, revert may not be able to perform well in some cases.

A..12 Merging a stable branch into the main trunk

Assuming we have a branch that only contains change sets from the branch itself, i.e., no change sets have been ported from trunk to the branch. Now we want all changes made to the development branch to be ported into the main trunk. To accomplish this we need an up to date working copy of the main trunk. The procedure is

cd calc/trunk
svn update
At revision 405.
svn merge http://svn.example.com/calc/branches/my-calc-branch
-- Merging r336 through r405 into '.': ...examine the diffs, compile, test, etc...
svn commit -m "Merged my-calc-branch changes into the trunk."
Committed revision 406.

where some output has been removed. Note that only changes committed into the repository are available for porting. At a later point when more development has occurred in the stable branch, we want to port these changes as well. This is equally easy since the repository remembers which change sets have already been merged into the main trunk, and the the procedure is simply

cd calc/trunk
svn update
At revision 513.
svn merge http://svn.example.com/calc/branches/my-calc-branch
-- Merging r406 through r513 into '.': ...examine the diffs, compile, test, etc...
svn commit -m "Merged my-calc-branch changes into the trunk."
Committed revision 514.

A..13 Keeping a feature branch in sync

Having a feature branch, it is recommended to keep it in sync with the trunk, i.e., port changes in trunk into the feature branch.

cd branch-working-copy
svn merge http://svn.example.com/calc/trunk

The repository knows when the branch was created from the trunk and will only merge change sets added to the trunk after the branch was created. After some time there has been some significant development in trunk and you want to port these to the feature branch. This is as easy as before

cd branch-working-copy
svn merge http://svn.example.com/calc/trunk
-- Merging r354 through r501 into '.':

and you do not need to worry that changes will be ported twice. The repository remember which change sets have already been merged to the branch and will not merge these again.

A..14 Merging a feature branch into the main trunk

Assuming that you followed the convention of keeping your feature branch in sync with the trunk, all that is needed is

cd trunk-working-copy
svn update
At revision 1910.
svn merge --reintegrate http://svn.example.com/calc/branches/my-branch
--- Merging differences between repository URLs into '.':

Please note the use of the reintegrate option, which is critical. It tells subversion that your feature branch is a mixture of trunk change sets and branch change sets. With the reintegrate you have asked subversion to carefully find the branch change sets and only port these.

Now when your feature branch has been merged into trunk it is recommended to remove the branch because the branch is no longer usable for further work. It would not be capable of correctly pick up change sets from the trunk via an svn merge, nor can it be properly reintegrated into trunk again. If you need to work further on the feature branch it is better to destroy it and create a new branch.

If you have been a bad boy and as such, out of sync. You must start by porting all changes made to the trunk into your branch and then you are ready to perform the merge into the trunk.

A..15 Removing a branch

When a branch has become obsolete this can be removed with

svn delete http://svn.example.com/calc/branches/my-calc-branch $\backslash$
-m "Removing obsolete branch of calc project."

A deleted branch can be resurrected if needed.

A..16 Creating a tag I

If we want to create a snapshot of the trunk exactly as it looks like in the HEAD revision, just make a copy of it

svn copy http://svn.example.com/calc/trunk $\backslash$
http://svn.example.com/calc/tags/release-1.0 $\backslash$
-m "Tagging the 1.0 release of the 'calc' project."

assuming you followed the guidelines and created a tags directory in you initial import. Use -r if you prefer to specify a revision to tag.

Remember rule 2.1.9; Do not mess with the tags directory. If you need to change a tagged revision of the project, you need to make a branch using the tags structure as template for the branch (see item A.10).

A..17 Creating a tag II

You can create a tag with your current working copy status

ls
my-working-copy/
svn copy my-working-copy http://svn.example.com/calc/tags/mytag

Why is this here? There is one (at least) interesting use for this feature. Sometimes there are situations where you have a bunch of local changes made to your working copy, and you'd like a collaborator to see them. Instead of running svn diff and sending a patch file (which won't capture tree changes), you can instead use svn copy to “upload” your working copy to a private area of the repository. Your collaborator can then either checkout a verbatim copy of your working copy, or use svn merge to receive your exact changes.

A..18 How to list the set of tags in a project

This is straightforward use of the svn list command

svn list http://svn.example.com/calc/tags

Remember rule 2.1.9; Do not mess with the tags directory. If you need to change a tagged revision of the project, you need to make a branch using the tags structure as template for the branch (see item A.10).

A..19 Help, my favourite repository has moved

Sometimes the location of a repository changes, but the contents of the repository stays the same, i.e., the URL to the repository is changed. A repository move is easily fixed with the svn switch command, this will change the URLs in your working copy. No file contents are changed, and your work is untouched and can be committed to the new location after switching to the new URL. This is subversion magic. Here is an example where a repository moved from svn.example.com to new.host.org:

svn switch --relocate http://svn.example.com/calc $\backslash$
svn://new.host.org/repos/calc .

We changed server type and directory path in this example. The Subversion Book warns about spelling errors when changing the URL since it may cause havoc for you, so be careful out there.


A..20 Change trac ticket status through commit log messages

There may be post-commit hooks in the subversion repository that performs specific tasks when changes are committed to the repository. One of these utility programs performs status changes to trac tickets if the log message is properly formatted. The trac-post-commit-hook searches commit messages for text in the form of:
  command #1
  command #1, #2
  command #1 & #2 
  command #1 and #2
where command is one of
  closes, fixes
    The specified issue numbers are closed with the contents of this
    commit message being added to it. 
  references, refs, addresses, re 
    The specified issue numbers are left in their current status, but 
    the contents of this commit message are added to their notes.
closes and fixes are synonyms, and references, refs, addresses, and re are all synonyms. More than one command can be issued in a message. An example message is “Fixes #10 and #12, and refs #13. Changed blah and foo to do this or that.” This message will close tickets 10 and 12, and add a note to ticket 13.

Note, it is important that #number is used, i.e., ticket:number will not work.

Information on where to retrieve and install the trac-post-commit-hook is available in Appendix E.3.