James Tauber : Python Subversion Binding

James Saiz

journeyman of some

Python Subversion Binding

Here are some ongoing notes on using the Python bindings to Subversion.

Note that I'm using Subversion 1.3 which handles pools for you. For this reason, what I say below won't work with versions earlier than 1.3.

from svn import fs, repos, core
assert (core.SVN_VER_MAJOR, core.SVN_VER_MINOR) >= (1, 3), "Subversion 1.3 or later required"

General Repository Access

To get a repository object:

repository = repos.open(root_path)

where root_path is the location of the repository on your local filesystem.

The fs module functions take an fs_ptr so you'll want to grab one:

fs_ptr = repos.fs(repository)

You can now get the latest (i.e. youngest) revision number:

youngest_revision_number = fs.youngest_rev(fs_ptr)

It's also possible to get revision-level properties:

property_value = fs.revision_prop(fs_ptr, revision_number, property_name)

Valid property names include "svn:log", "svn:date", "svn:author", etc.

Node Access

To get a node (i.e. file or directory), you first need to get the root of the revision:

root = fs.revision_root(fs_ptr, revision_number)

Then you can get a file stream with:

stream = fs.file_contents(root, path)

where path is the path of the file you want within the repository.

This stream can then be read with:

core.svn_stream_read(stream, length)

and then closed with


Alternatively, the stream can be wrapped as a Python file-like object:


To get a node's properties:

property_dict = fs.node_proplist(root, path)

To get a specific property:

property_value = fs.node_prop(root, path, property_name)


To begin a transaction:

txn = fs.begin_txn(fs_ptr, revision)

where revision is the revision to base the changes off.

You then get the root of the transaction:

txn_root = fs.txn_root(txn)

This can then be read and modified as if it were a revision root (see below).

To abort the transaction:


To commit the transaction:


This will return a pair of values, the second of which will be the new revision number (or None if the commit failed)


Note these all use transaction roots not revision roots.

To create a new (empty) file node:

fs.make_file(txn_root, path)

To delete a node:

fs.delete(txn_root, path)

To change a node's properties:

fs.change_node_prop(txn_root, path, property_name, property_value)

To change a file's content:

stream = fs.apply_text(txt_root, path, None)
core.svn_stream_write(stream, "hello world!\n")

Note that this can be done after an fs.make_file to provide the content for a new file.

Unfortunately, the Stream wrapper object doesn't have a close() method which renders it useless for writing.

Categories: Python subversion

Comments (2)

David Geller on Saturday 18 February, 2006:

What about apply_txdelta for changing files? This is done in the sample putfile.py.


Larry Maccherone on Tuesday 28 February, 2006:

I'm curious why you used these bindings which only work with Python 2.3 and have little to no documentation instead of the pysvn bindings (also on the Tigris site at: http://pysvn.tigris.org/). I just started a project that called for svn bindings and the first documentation I found was your notes above. When I took those as far as they go, I went looking for me. That's when I found pysvn. pysvn supports Python 2.3 and 2.4 and it has decent documentation. I have only just started looking at it but it looks pretty good. Please email me your reply to larry a@t maccherone d.o.t com.

Add a Comment

What is 93+4?
Comments are text only.
The math question is to ensure you are a human!
This page last modified Thursday 09 February, 2006 by James Saiz
Content made available under a Creative Commons Attribution-NonCommercial-ShareAlike license