KDevelop4 Subversion Support

October 1, 2007 at 12:31 am | Posted in KDevelop | 4 Comments

The last week I fully dived into reworking the Svn support. I know this sounds like waste of time, as Dukju already had quite some parts implemented. However I found the architecture quite weird, with a core-class which was mainly just a ton of methods to create jobs and threads for the various actions. All this somehow looked like procedural programming in an object oriented plugin.

I started by cleaning up filenames and such things and do a few small changes here and there until the point came where I wanted to start removing the need for the core class and making the threads an implementation detail of the svn-jobs. While looking at the existing code and how it did I noticed much, very much plain svn/apr setup code, like allocating memory for an array to store the paths to be comitted and such things.

I tried to separate the code out from the core class and put it into a ThreadWeaver::Job (to make it possible to steer the number of threads started within kdevelop), but at a certain point it became quite obvious that the svn C-API is very hard to use in an object-oriented way without building a OO layer on top of it. At that point I restarted the discussion I had quite some time ago among the kdevelop developers to introduce a new requirement and use RapidSvn’s C++ library.

Luckily this time I was in a better position to convince them and to prove that the code I have now (Just added svn-add action) here are two snippets.

The new code for svn add looks like this:

svn::Client cli(m_ctxt);
foreach( KUrl url, m_locations )
{
try
{
QByteArray ba = url.path().toUtf8();
cli.add( svn::Path( ba.data() ), m_recursive );
}catch( svn::ClientException ce )
{
kDebug(9510) << "Exception while adding file: "
<< url
<< QString::fromUtf8( ce.message() );
m_success = false;
}
}

And this is the equivalent old code.

kDebug(9500) << "SvnAddJob::run()";
apr_pool_t *subpool = svn_pool_create (pool());
for( QList <kurl> ::iterator it = m_wcPaths.begin(); it != m_wcPaths.end(); ++it )
{
KUrl nurl = *it;
nurl.setProtocol( "file" );
svn_error_t *err = svn_client_add2( svn_path_canonicalize( nurl.path().toUtf8(), subpool ),
m_recurse, m_force, ctx(), subpool );
if ( err ){
setErrorMsgExt( err );
svn_pool_destroy( subpool );
return;
}
}
svn_pool_destroy (subpool);

Right, the absolute number of lines isn’t that different, however this is a really simple action, for other things its more visible. Also in the new code you see directly what happens and you don’t have to ignore certain code lines because they just setup some memory pool or set a protocol on a url thats a local path anyway.

One thing I have to investigate still is how much we loose by using svncpp, for example in the above code snippet you can see that the client api also supports the force-flag, while svncpp has no support for that. We could probably extend the svncpp api if really needed.

Blog at WordPress.com. | The Pool Theme.
Entries and comments feeds.

Follow

Get every new post delivered to your Inbox.