Working with SVN

From Armagetron

Don't you worry, working with subversion is, for everyday operation, just the same as working with CVS. In fact, rule 1 is that command line users get by pretty well by just replacing the cvs command with svn. Once you have a checkout that is.

ArmagetronAd SVN Repository:

This repository contains the main armagetronad module. Click here to browse the repository with your browser.

This page propbably can't replace reading the Subversion Book, but it should get you started.


Most of this requires that you have a working copy checked out; see below how to get one.

For Windows Users

Use TortoiseSVN. When any documentation says "do svn <command>", look for the command in your right-click context menu. SVN properties (commands: "svn propget/propset/propedit") aren't in the Tortoise submenu, they're hidden in the generic "Properties" menu item at the bottom.

For Former CVS Users

"cvs update" becomes "svn update". It accepts a -r argument to fetch a specific revision just like in CVS. Note that in SVN, revisions are global.

"cvs commit" becomes "svn commit". In CVS, you've been told to always do "cvs update; cvs commit" together because your commit would fail whenever you were not up to date; that does not apply to svn. Commit and update as you see fit. You can pass your commit message with -m, if you like.

To see which files you have modified, you'd do "cvs -n update". That becomes "svn status" and doesn't require connecting to the remote repository.

To revert files, you'd have done "cvs update -C". This becomes "svn revert", again working without network action.

If an update or merge produces a conflict, it's not enough to edit the files and resolve the conflict. You have to tell Subversion afterwards that you did this with "svn resolved <filename>" before it lets you commit again.

In CVS, you would switch a checkout from the trunk to a branch, conserving your local changes, with "cvs update -r b0_2_8". In SVN, assuming you have the whole project checked out, you do

svn switch

For New Users

(only covering the basics here)

Get a checkout as described below. If you want to get up to date with what the other developers have been doing, call "svn update". Edit the files in the checkout as you'd do on a local project, but stay away from the .svn subdirectories. They contain Subversion's status information. Before you update, you may want to review the changes you're about to get with "svn log -r BASE:HEAD".

If the update touches a file you have been modifiying locally, sometimes there are conflicts. They're marked with "C" in the output of "svn update". Before you can do anything, you have to resolve the conflict. Open the file in an editor; you'll see something like

<<<<<<< .mine
<your local version>
<the other developer's version>
>>>>>>> .r2

You then have to look really hard at the two versions, remember what you tried to do here, determine what the other developer tried to do, and come up with a single version that does both. Afterwards, you have to call "svn resolved <filename>" to tell svn that the conflict was resolved.

When it is time to publish your work, do "svn status" to see which files you touched. If you know you only worked on a single task since your last commit and none of the changed files indicated by "svn status" look strange, simply do "svn commit", and enter an appropriate commit message describing your change either in the editor that pops up or via the "-m <message>" command line switch. If you did several things, do for every thing "svn commit <list of files of thing>", again with an appropriate commit message. If you can't remember what you did or if you want to check, do "svn diff <list of files to check>". Windows users have it easier here, they just commit and get a nice dialog where they can select the files to commit, and a doubleclick gives them the diff.


The basic command to get a checkout is

svn co<path> <target>

Where <path> is a yet to be specified subpath in our repository (you usually don't fetch the whole thing) and <target> is the name of the directory where the checkout will reside in. In SVN, branches and tags are managed simply as different paths in the repository. So your choice of <path> determines which branch or which tag and which module you're getting.


Subject to change with notice, <path> is organized like this for core modules:

<path> = armagetronad/<brag>/<module>

<brag> stands for "branch or tag" and is either "trunk" for the trunk, "branches/<branch name>" for branches and "tags/<tag name>" for tags. Branch and tag names don't have the same restrictions as in CVS (no dot, start with letter), so a typical branch name would be 0.2.8, a typical tag name Note that is both name of a tag for version and of the branch leading to that version.

<module> is the module name. It's just "armagetronad" for the core source and "<former cvs name - armagetronad>" for the auxiliary modules armagetronad_build* and armagetronad_winlibs.

Common examples: To get the trunk sources, you would do

svn co armagetronad

To get the release building module on its side to make a release, you do

svn co build

To get the same for one of the earlier branches, you do

svn co armagetronad
svn co build

Sounds complicated and cumbersome for many modules? Just check out everything from the trunk with

svn co trunk

Whether you choose the name of the checkout to be the same as the last bit of the repository path is entirely up to you, but it's a good idea if you want to avoid confusion. You can do so by just leaving the second argument out.

Selecting branches is still cumbersome that way. That's why we're pondering to introduce

Workspaces (proposal)

Workspaces are parts of the repository that use a special subversion feature called externals to give you the checkouts you need for a specific task. You'll be able to get your workspace with

svn co<os>/<branch> <target>

or, if you want all workspaces,

svn co<os> workspaces

<os> is your operating system type, either "unix" or "windows". OS X probably counts as "unix". The workspaces will contain only those modules needed; the unix workspace will be missing the visualc, code::blocks and winlibs directories, and the windows workspace the build and build_eclipse modules.

<branch> is a symbolic branch name. We won't be making workspaces for every branch, only for those actually in use. <branch> can be one of "trunk" for the trunk, "bugfix" for the branch leading to the very next release, and "stable" for the branch leading to one of the releases after that one.

We'll be updating the workspaces to always point to the branches that meet the description. "trunk" will always be the trunk. Right now, "stable" would point to 0.2.8, and "bugfix" to, but that one is still managed in CVS, so "bugfix" will point to 0.2.8 as well. Changes to the structore will be announced; uncommitted changes to externals get lost silently if the repository path gets updated.

There are simple rules which change should be done in which of the workspaces:

  • changes that are absolutely super-surely improvements in the short and long term go to "bugfix". Critical bugfixes, security fixes or zero risk bugfixes (adding NULL pointer checks, removing obsolete documentation) are the most common candidates.
  • changes that are likely to be improvements in the middle term (think four weeks) and long term, but may have small startup difficulties go to "stable". All bugfixes that don't qualify for "bugfix" go here, as well as small features that were forgotten in the roadmap of a release series (anticipating Luke's protest here).
  • Everything that is likely to be a long term improvement goes to "trunk". This is the default place for new features.
  • Everything where it is not sure whether it is an improvement or not should go into an experimental branch that may or may not be merged back into the trunk. Workspaces for those are created on demand.

Name alternatives instead of trunk/stable/bugfix:

  • trunk/branch/twig (following the tree metaphor)
  • trunk/next/upcoming (depicting the release they're leading to)
  • long/mid/short (for longterm, midterm and shortterm quality focus)
  • gas/liquid/solid (states of matter representing the stability, easily extended to "plasma" for experimental stuff)
  • alpha/beta/gamma (the classics, extended to gamma for release candidate quality)

Test workspaces have been committed in the original armagetron SVN repository. Get them as described above, replacing "armagetronad" with "armagetron". The two workspace names are "gas" and "liquid", pointing to the trunk and 0.2.8, respectively.


Merging one branch to another is done by checking out the branch that will be the target of the merge first. You need to know the revision number the branch that's supposed to be merged was created or merged the last time first, find it out via svn log or CIA. Then you need to execute the following command:

svn merge -r <last merged revision number>:HEAD <local path of the checkout>

This will merge the changes into the working copy of the target branch, you have to resolve conflicts if they exist and then you can commit the branch. You can use the output of svn log -r <revisionlastmerged>:HEAD as part of the commit message.

Private space (proposal)

We'll have a section in the repository reserved for private use; personalized copies of workspaces can go there, or branches where only one or two developers work on. The sub-category path would be "private/<user name>".

If a branch becomes more mainstream, it can be moved in with the main project.

At some point, private branches in the repository may be available to non-developers on request.


Your commits don't appear in "svn log" until you do "svn update". This is important for alpha builds. Always update before you make an alpha, or the ChangeLog will not reflect your latest changes, and the revision that the alpha will carry (later publicily in the version, for now as a fingerprint file) will be wrong.