Skip to content

From Unfuddle (svn) to git

I've blogged about converting a Subversion repository to git a couple times. While it was a tedious process at first, I've made my peace with it and now cannot count the code repositories I have migrated successfully anymore. The migration usually works, except for when I deal with our old provider unfuddle.

For some reason, sometimes it didn't work right away and I had to re-run git svn clone a couple of times to get it right.

git svn clone

Here's a snippet to make it work for you:

$ git svn clone --authors-file=./authors.txt --no-metadata \
--prefix=svn/company_repositoryname/ \
--tags=tags \       
--trunk=trunk \
--branches=branches \ \

Make sure to replace the company and the company_repositoryname part in above scripts.

For some reason, I was never able to get prefix and all that completely right from the start. That is, until now — needless to say the above works. And for the sake of documenting and not re-learning each time (e.g. today, as a migrate another Subversion repository to git (Github :-)), here's my documentary blog post.

Tags and branches

Tags and branches are slightly different concepts in Subversion and git.

In Subversion, we usually ran pre-processing on tags before we deployed them (because doing this in a branch was a huge pita due to size of the repository and the overall joy of merging commits in Subversion. So in the end, a tag we created in Subversion, is not a tag in git because we modified the tag — which makes it a branch.

So as a follow up to my prior snippet to convert a repostitory, I've used this script to convert the branches it created to proper tags in git:


branches=(`git branch -r`)

for branch in "${branches[@]}"
    case $branch in
        echo "$tag from $branch, remote: $remote"
        git checkout -b "tag-$tag" $remote && git tag -a $tag -m "SVN tag: $tag"
        echo "Skipping: $branch"

Again, you will have to adjust company_repositoryname in this piece. :-)

Once the script completes, I verify the tags with git tag -l and delete the branches with git branch -D foo.

If all looks ok and the tests confirm this, I add an origin, push branches and also git push --tags.


That's all — happy migrating. Just in case: the code is BSD licensed, which means, you can do whatever you want with it.

FreeBSD + softupdates + no space left on device

One of my older hosting servers runs into space issues constantly. And most of the time it's a 24 GB log file (error_log) from a really old Joomla-based website.

Why it gets so huge? Well, when I tail the logfile, I see messages about functions being deprecated in PHP, warnings, notices and a whole lot more literally racing by. I'm not sure if Joomla changed in recent years, but most of the code-base is a great example of how PHP applications should not be build. Part of the problem in this particular case is that the system is hacked together and no one wants to update it. I'd argue another short-coming of the system since extensions actually require you to edit files and upgrade paths are not very clear.

Since it's a friend who's running the website, I haven't been very pressing on him to move to something more updated.

No space left on device

The usual quick fix is:

rm error_log && touch error_log && chown www:www error_log

Nice, and easy.

The only problem is that the system will usually take a while until recognizes that there is free space indeed.


FreeBSD recommends soft-updates — they have a lot of advantages. The only disadvantage is that e.g. the inodes will claim the address space until the write is completed. In case of a log file, this is usually when the process writing it is shut down.

Here's a system with soft-updates enabled:

server# mount
/dev/ad8s1a on / (ufs, local)
devfs on /dev (devfs, local)
/dev/ad8s1e on /tmp (ufs, local, soft-updates)
/dev/ad8s1g on /usr (ufs, local, soft-updates)
/dev/ad8s1d on /var (ufs, local, soft-updates)
/dev/ad8s1f on /web (ufs, local, soft-updates)
procfs on /proc (procfs, local)

The fix to making the system recognize the space is simple:

  1. Restart your webserver, e.g.: /usr/local/etc/apache restart
  2. Or run sync.


I hope I never ever forget this. Ever.