Contact

admin

About Me · Send mail to the author(s) E-mail · Twitter

At GROSSWEBER we practice what we preach. We offer trainings for modern software technologies like Behavior Driven Development, Clean Code and Git. Our staff is fluent in a variety of languages, including English.

Feed Icon

Tags

Open Source Projects

Archives

Blogs of friends

Now playing [?]

Error retrieving information from external service.
Audioscrobbler/Last.fm

ClustrMap

Importing Subversion Repositories to Google Code

Posted in Tools and Software at Monday, 12 May 2008 15:19 W. Europe Daylight Time

I recently added two of my pet projects to Google Code. I chose Google's Open Source hosting because they  have a very clean UI with integrated issue tracking and also offer native support for Subversion. One of the many aspects that make Subversion a decent choice is the ability to import existing SVN repositories to Google Code. That is, the whole history is uploaded and your soon-to-be open source project doesn't loose valuable undo history. YAGNI? Maybe.

Importing a complete repository to Google Code is well documented, but what if your repository contains several projects and you just want to upload a certain one? Actually Subversion has all you need, there are just a couple of things to prepare. I will provide everything you need here, you may also want to use this excellent write-up (also look here) which I used as a reference. The syntax presented here works on Windows, whereas the author of the above articles was working on a *nix machine, so the command lines differ a bit.

Create your Google Code project and reset the Subversion repository to revision 0

After you created the project on Google Code you can find the "Reset Subversion Repository" link at the bottom of the "Source" tab.

Reset

Prepare your Subversion repository

You need local access to the Subversion server, a Remote Desktop or SSH connection would suffice. I'm assuming your repository is accessible over HTTPS on port 8443. Here are the paths used in the command lines below:

Property Value
SVN repositories root C:\Subversion\
SVN repository containing the project C:\Subversion\projects
Repository URL https://localhost:8443/svn/projects/
Project to import to Google Code https://localhost:8443/svn/projects/foo/Project-FooBar/
Google Code Subversion URL https://project-foobar.googlecode.com/svn/

Dump your repository filtering the project path

First you need to dump the SVN repository containing the project in question. svnadmin dump saves the contents of the repository to the C:\Subversion\project-foobar.dump file on disk. To only take the parts into account we're interested in, use svndumpfilter to exclude everything outside the project path.

Renumbering revisions and dropping empty revisions cleans up the resulting dump and prevents revisions with no changes.

svnadmin dump C:\Subversion\projects\ | svndumpfilter --drop-empty-revs --renumber-revs include /foo/Project-FooBar/ > C:\Subversion\project-foobar.dump

Including (and dropping empty revisions for) prefixes:
   'foo/Project-FooBar'

* Dumped revision 0.
Revision 0 committed as 0.
* Dumped revision 1.
Revision 1 skipped.
...

Create a new repository for the project

Now that you have dump in place, create a new repository for Project-FooBar.

svnadmin create C:\Subversion\project-foobar-import

Create directories needed to load the dump

To make the import process succeed, you have to create the paths that are not included in the dump, i.e. all directories above the path that was included by svndumpfilter. In the our case, this is the /foo directory.

svn mkdir https://localhost:8443/svn/project-foobar-import/foo/ -m "Folder created for import"

Committed revision 1.

Load the filtered dump

It's time to import the dump to the repository just created.

svnadmin load C:\Subversion\project-foobar-import < C:\Subversion\project-foobar.dump

<<< Started new transaction, based on original revision 1
     * adding path : foo/Project-FooBar ... done.
     * adding path : foo/Project-FooBar/trunk ... done.
...

If you didn't create all necessary directories in the last step, you will receive an error message like this:

<<< Started new transaction, based on original revision 1
     * adding path : foo/Project-FooBar ...svnadmin: File not found: transaction '1-1', path 'foo/Project-FooBar'

Move directories such that they follow the standard Subversion directory structure

Your can now have a look at the new repository by pointing your browser to https://localhost:8443/svn/project-foobar-import/ where you only should see Project-FooBar.

The next step moves the project to the root of the repository and aligns the directory structure with Subversion's default directory layout.

svn move https://localhost:8443/svn/project-foobar-import/foo/Project-FooBar/trunk/ https://localhost:8443/svn/project-foobar-import/trunk/ -m "Folder moved"
svn move https://localhost:8443/svn/project-foobar-import/foo/Project-FooBar/tags/ https://localhost:8443/svn/project-foobar-import/tags/ -m "Folder moved"
svn move https://localhost:8443/svn/project-foobar-import/foo/Project-FooBar/branches/ https://localhost:8443/svn/project-foobar-import/branches/ -m "Folder moved"
svn delete https://localhost:8443/svn/project-foobar-import/foo/Project-FooBar/ -m "Folder deleted"

Upload your Subversion repository to Google Code using svnsync

All set. The last step is to upload your Subversion repository to Google Code using the documented command line below.

svnsync init https://project-foobar.googlecode.com/svn/ https://localhost:8443/svn/project-foobar-import/
Copied properties for revision 0.

svnsync sync https://project-foobar.googlecode.com/svn/
Committed revision 1.
Copied properties for revision 1.
...

The whole import process will take a little bit, depending on the size of your repository. It took me about 40 minutes for a repository with about 100 revisions, time to grab a cup of coffee.

The script

Of course you can script the whole process:

@rem Create dump
svnadmin dump C:\Subversion\projects\ | svndumpfilter --drop-empty-revs --renumber-revs include /foo/Project-FooBar/ > C:\Subversion\project-foobar.dump

@rem Create repository for import
svnadmin create C:\Subversion\project-foobar-import

@rem Create directories needed for the import to succeed
svn mkdir https://localhost:8443/svn/project-foobar-import/foo/ -m "Folder created for import"

@rem Load dump
svnadmin load C:\Subversion\project-foobar-import < C:\Subversion\project-foobar.dump

@rem Move folders around
svn move https://localhost:8443/svn/project-foobar-import/foo/Project-FooBar/trunk/ https://localhost:8443/svn/project-foobar-import/trunk/ -m "Folder moved"
svn move https://localhost:8443/svn/project-foobar-import/foo/Project-FooBar/tags/ https://localhost:8443/svn/project-foobar-import/tags/ -m "Folder moved"
svn move https://localhost:8443/svn/project-foobar-import/foo/Project-FooBar/branches/ https://localhost:8443/svn/project-foobar-import/branches/ -m "Folder moved"

svn delete https://localhost:8443/svn/project-foobar-import/foo/Project-FooBar/ -m "Folder deleted"

@rem Sync with Google Code
svnsync init https://project-foobar.googlecode.com/svn/ https://localhost:8443/svn/project-foobar-import/
svnsync sync https://project-foobar.googlecode.com/svn/

Introducing Graffiti-UserGroups for Graffiti CMS

Posted in DNUG Leipzig | Graffiti CMS at Tuesday, 06 May 2008 19:22 W. Europe Daylight Time

It's been a while: Sometime last August the SharePoint hosting contract for the .NET User Group Leipzig ran out and since then we basically didn't have an online presence. Our .NET Summercamp 2007 conference and a couple of smaller User Group events took away their share of spare time so I didn't find time to create our new home page. Over the last couple of months I evaluated several Content Management Systems for our to-be-developed homepage and what can I say, I was a bit disappointed. One CMS to remain unnamed showed very buggy behavior when setting up basic navigation elements and DotNetNuke had some scary CSS to override for custom layouts and uses tables all over the place.

Two months ago I came across telligent's Graffiti CMS. Delightful! They really appear to be driven by their "Content Made Simple" concept. Not only do they have a nice Ajax-y administration UI, Graffiti also provides an extremely simple and efficient extensibility model. The NVelocity template engine is also very easy to grasp. (NVelocity is part of my beloved Castle project.)

I started implementing some macros for the User Group events, and soon it became clear that this might be something other User Groups might want to use as well. Thus, the open-source Graffiti-UserGroups project was born.

Basically we wanted to provide a list of recent and archived events with custom metadata and enable attendee registration. Speaking of metadata, this includes:

Event Detail

  • Start and end dates
    • and time, optionally
  • Speaker
  • Location
    • A default location should be set if no location was entered.
  • Maximum number of attendees (due to space limitations)
    • Again, a default maximum should be set if no value was given.
  • Registration recipient e-mail address
    • A default address should be used if no e-mail address was given. We sometimes host events in cooperation with the local Microsoft Student Partners (MSPs) so the address can change for MSP events.

This enables some neat use cases:

  • Registration for one or more events using a web form without needing to write an e-mail.
  • Automatic e-mails to the attendee and the event organizer.
  • The notion of waiting lists for events that are booked up.
  • iCalendar item downloads for Outlook that are created based on the metadata above.

Registration Page

All functionality can be implemented using Graffiti's extensibility points, a plug-in in this case. A plug-in can subscribe to certain events in the application, jump in and modify data (see default values above). Another extensibility point which is heavily used in Graffiti-UserGroups is the notion of custom "Chalk" macros compiled into .NET assemblies. For example, there's a set of macros to display and format event data without the need to write complex "standard" Chalk statements.

An extra bonus for the Graffiti-UserGroups newbie is the Demo Site Setup Wizard which configures your Graffiti site, including sample posts and a registration page. (Also see the video below where I demo the initial setup which is finished in minutes.)

Demo Site Setup Wizard

To make a long story short(er) I've recorded a screencast that shows you how to set up the demo site quickly on your local machine.

Click to watch video

Don't forget to take a look at the new .NET User Group Leipzig homepage to see the macros in action. Also check out the source code on Google Code!