Subversion

From GPWiki

Files:GUITutorial_warn.gif The Game Programming Wiki has moved! Files:GUITutorial_warn.gif

The wiki is now hosted by GameDev.NET at wiki.gamedev.net. All gpwiki.org content has been moved to the new server.

However, the GPWiki forums are still active! Come say hello.

Subversion is a version control system. It is designed to be superior to CVS but have an almost identical interface. This makes it easier for developers to migrate from CVS to Subversion.

Subversion can either be run as an Apache service with the WebDAV/DeltaV protocol or as a standalone server.


Contents

Using Subversion from the command-line

If you dont have subversion on your box you can download it from their website[1].

If you use a Debian GNU\Linux system (Ubuntu included) then just install it with apt-get:

sudo apt-get install subversion

If you're using Windows you can put the svn.exe in your '<Drive>:\<Windows directory>\System32' so you can access it from anywhere in the system. Or, as an alternative, you can put it in any directory included in the PATH environment variable.

When you have subversion installed you will have a binary named 'svn'. When you invoke 'svn help' you will see a list of commands.
You may notice that the subcommands have similar names to that of the Unix environment.
Here is an example:

<version and copyright comes here>
Available subcommands:
   add
   blame (praise, annotate, ann)
   cat
   checkout (co)
   cleanup
   commit (ci)
   copy (cp)
   delete (del, remove, rm)
   diff (di)
   export
   help (?, h)
   import
   info
   list (ls)
   lock
   log
   merge
   mkdir
   move (mv, rename, ren)
   propdel (pdel, pd)
   propedit (pedit, pe)
   propget (pget, pg)
   proplist (plist, pl)
   propset (pset, ps)
   resolved
   revert
   status (stat, st)
   switch (sw)
   unlock
   update (up)
<information>

Here we have the commands to fill our needs. Commands are named for either readability (long) or speed (short). To read more about a certain command simply type 'svn help' or 'svn help <command>'.

Alterations on files/directories in any form is displayed by subversion in the form of:
<FLAGS> <OBJECT>

Where flags can be:

  • 'M': modified
  • 'A': added
  • 'D': deleted
  • 'A+', added then modified.
  • 'K': a lock-identifier exists
  • 'L': the local directory is locked
  • 'C': a conflict with the server-repo exists

Commands which communicate with a server can take additional commands such as:

  --username <uname>
  --password <pword>
  --no-auth-cache

Use the --no-auth-cache to avoid storing information about your username and password.
The username and password is saved by default in a cache so you dont have to specify it everytime you perform a command that requires authentication.

checkout

First we use 'co' or 'checkout' to recieve a fresh copy of a repository (repo).
Usage: 'svn co URL[@REV] [PATH]*'.
If the server requires authentication then it prompts for username and/or password. On Unix systems the environment variable for the current logged in user is used (or is it owner of pid?).

svn co http://some.cool.svn.server.org/repos/someCoolApplication
svn checkout http://some.cool.svn.server.org/repos/someCoolApplication@15 trunk

This will checkout a fresh copy of the latest revision from the 'someCoolApplication' repository from the subversion-server at 'http://some.cool.svn.server.org'.
You can apped '@#' where # is the revision-number you want to check out. PATH can also be used to checkout specific directories in the repository. Multiple PATH's can be used.

When you have your own copy of the repo you can edit the files on your local machine. Subversion has a directory for each directory in the repo named '.svn' where it stores its information. Its hidden when using normal 'ls' so it does'nt get in the way of the structure.

Note that when working with large sources one can checkout a subdirectory in a repo and perform changes only to that directory. This reduces the stress on the server since you only work with the files in that directory.

lock

When working in a group of multiple developers, one may want to have exclusive access to a file or files. This can be allowed with the use of lock.

svn lock someReallyCoolSourceFile.c someReallyCoolHeaderFile.h

Subversion shows us that it has locked the files, if it was a success.

commit

Now we have added a feature that 'someCoolDude32' wanted and we want it to get into the repo.

svn ci someReallyCoolSourceFile.c someReallyCoolHeaderfile.h
svn commit someReallyCoolSourceFile.c someReallyCoolHeaderfile.h
svn ci
svn commit

This transfers the changes we made to the subversion repository. You can ommit the filenames to commit all changes you have made in the current directory (this includes subdirectories). To commit everything you have done to the repo simply go to the repo-root and use 'svn ci'.

Before the commit is executed you are asked to give a description about your change or changes so it can be recorded togheter with your changes in the form of a revision. This opens up the default editor on your system. The default editor differs on different systems, can be Vim, mcedit, ed, edit, pico, nano and so on.
If you dont specify any text then subversion will ask you to: cancel commit, perform commit or continue editing log. If the commit should fail then the log will be saved in a file which it will display. In the case of a failure you can perform the commit at a later stage with the an argument pointing to the logfile that was saved. E.g. 'svn ci svn.commit.tmp'..

Subersion displays all the commits and shows a message that it updated the repo to revision X, if succeeded.
You can use the update command to get the log for revision X, since the local revision log will be at revision X - 1.

One thing to know is that subversion uses atomic commits. This means that all changes will be applied to the repo as one change. If the commit failes during the commit then the repo will still be its original state without the partial commit. This is to avoid trashing the repo where one would be force to clean the repo by reversing the revision from X½ to X.

unlock

Now we have implemented the really cool feature that 'someCoolDude32' wanted and we are done working for the day. We now unlock the files so other developers can perform changes to them.

svn unlock someReallyCoolSourceFile.c someReallyCoolHeaderfile.h

That takes care of the basics for editing files, now for some syncronization and control.

update

When you get online the next day and want to syncronize the repo then simply use update:

svn up
svn update

It will checkout the latest revision changes from the current you have and apply them to your local source. If there were no changes since last commit it will display that you already are on revision X.

status

To keep track of what modifications you have done to the source without doing a commit you can use the status command.

svn st
svn status

This shows a list with modifications to the source from the current directory. To see all changes simply use 'svn status' in the repo-root.

remove

Deleting a file and/or directory is simple. Just use the remove command.
If you want to delete something with modifications in it then you have to specify the argument '--force'. '--force' can be used in other circumstances too but should be used with care.
Warning: Certain actions can't be undone!

svn rm someBadNonWorkingSourceFile.c myBinaryFile.exe myObject.o someDirectory/ otherDirectory\ yetAnotherDirectory

You can remove files/directories directly in the repo by giving the full url to the server. E.g. http://repo.org/repo/badFile.c Always commit deletions so the repo has the proper files, otherwise people might edit a file which may be removed later.

move

To move a file/directory use the move command.

svn mv badName.c goodName.c
svn move badName.c goodName.c
svn ren badName.c goodName.c
svn rename badName.c goodName.c

When moving a file/directory the target in question is first deleted and then added in subversion. This avoids the need for 'Move' tracking system. The logs will be used instead. E.g. 'moved X to Y in someDir'.

import

To import from another directory one can use import. 'svn import [PATH] URL'

'svn import [source] -> target'

svn import http://svn.SomeCoolServer.org/repo/myCoolProject
svn import /home/tux/mySourceDir http://localhost/repo/myLocalRepo
svn import /usr/home/bsd/kernel http://svn.kernel.myDevSite.org.com/repo/myNewOperatingSystem/kernel
svn import file:///home/repo/someRepo

One can specify a remote repo-server to import the current directory to.

diff

The beloved diff. This is what makes open-source work. It generates a formated description about what have been changed in the current directory to stdout.

svn diff > pathToFixBadCodeAndAddLittleBunniesToCoreDumps.patch

Simply pipe the output from 'svn diff' to the patchfile (pipes works in Win2k+ as far as i know). Then you have your very own patchfile which you can mail to the owner of the repo so he can apply it. This is a way to avoid people commiting changes directly to the repo.

Common structure

A common structure of a repo is the use of a trunk, tags and branches structure.

  • trunk is used for the latest not-properly-tested additions and features.
  • branches is used for creating new branches for an upcoming release or other reasons for creating a seperate source.
  • tags is used for a stable release. E.g. 1.0 1.2 1.4

Another structure is the stable/unstable. Stable is obvious, its the latest stable version where tag-releases such as 1.0 or 1.2 is released in tarballs instead of seperate sources. Unstable is the trunk where all new additions and features goes.

stable and tags sources usually (and always should) recieve all the needed patches for fixing bugs, security issues, instability issues and so on.

It is also common to start a project outside of subversion until the software in question is ready for multiple users/developers. This is usually the import of version 0.1 or 0.0.1.


External links