From Svn to Gitolite


Today I’d like to describe how to migrate from Svn to Git, minding existing infrastructure. One of the most common Subversion servers configurations is Linux server with Apache and mod_dav_svn module serving one or more Subversion repositories. Each Subversion repository may contain one or more projects. Of course, I will use SubGit to make migration smooth, i.e. without a need to force users to make a switch from Subversion to Git overnight.

For Git, I’ve chosen Gitolite as a Git management tool, as it is relatively easy to install and lot of documentation resources.


Here is the first picture. In blue initial configuration is shown and in gray are what we will gradually build in this post. This sample migration takes place on Ubuntu Linux server:

Initial Setup

Step 1: Install Gitolite and create ‘Git’ user

To install Gitolite I’m using “install as root” method from Gitolite documentation. Few migration-specific additions are marked with the bold font.

On your workstation:

  • copy your ~/.ssh/ file to /tmp/ on the server. (The name of this file determines your gitolite username, so if you leave it as, your gitolite username will be id_rsa, which may not be what you want).

On your server, as root:

git clone git://
# defaults to being the same as:
# gitolite/src/gl-system-install /usr/local/bin /var/gitolite/conf /var/gitolite/hooks

# to upgrade gitolite, repeat the above commands. Make sure you use the
# same arguments for the last command each time.

# Git user should be in the same group as your Apache user:
useradd git -g www-data -m -s /bin/bash

# switch to the hosting user
su - git

# (now as git)
gl-setup /tmp/

# when prompted edit the following values in /home/git/.gitolite.rc file:
$REPO_UMASK = 0002; # default is 0077
$GL_GITCONFIG_KEYS = "core.sharedRepository"; # default is ""

# Change repositories directory permissions to let Apache user
# read it contents:
chmod ug+rx /home/git/repositories

On your workstation:

git clone git@server:gitolite-admin

Gitolite Installed

Step 2: Create Git repositories with Gitolite

Create empty Git repository for each of your Subversion project. In this post I assume that there are three Subversion projects in a single Subversion repository (p1, p2, p3) each with a standard trunk/branches/tags layout. You may have different distribution as well as different layout.

On your workstation, edit gitolite-admin/conf/gitolite.conf file:

repo    gitolite-admin
        RW+     =   alex
repo    testing
        RW+     =   @all

repo    p1
        RW+     =   alex
        config core.sharedRepository = true
repo    p2
        RW+     =   alex
        config core.sharedRepository = true
repo    p3
        RW+     =   alex
        config core.sharedRepository = true

Add more access rules if necessary, commit and push your change:

git add conf/gitolite.conf
git commit -m "repositories added"
git push

Git Repositories Created

Step 3: Set up smooth Svn to Git migration

On server download and install SubGit. Use either debian package distribution or zip archive.

sudo dpkg -i subgit_1.0.0-EAP-902_all.deb



To set up migration, as www-data user, run:

$ sudo -u www-data subgit configure /var/svn/repos
SubGit version 1.0.0-EAP ('Miai') build #902
This is an EAP build, which you may not like to use in production environment.

Detecting paths eligible for translation...
Subversion to Git mapping has been configured in '/var/svn/repos':
/p1 : /var/svn/repos/git/p1.git
/p2 : /var/svn/repos/git/p2.git
/p3 : /var/svn/repos/git/p3.git


Adjust '/var/svn/repos/conf/subgit.conf' file
and then run
subgit install "/var/svn/repos"
to complete SubGit installation.

SubGit has detected Subversion projects and created default configuration. Now I will edit SubGit configuration file at /var/svn/repos/conf/subgit.conf to specify our Gitolite repositories locations instead of default ones and to mark repository as shared:

        # shared option must be set to 'true', 
        # as long as apache and gitolite are ran 
        # by different users (i.e. www-data and git)
        shared = true
        # authors.txt consists of mapping lines:
        # svnUser=gitUser<>
        # this file is optional
        authorsFile = conf/authors.txt
[git "p1"]
        translationRoot = p1
        repository = /home/git/repositories/p1.git
[git "p2"]
        translationRoot = p2
        repository = /home/git/repositories/p2.git
[git "p3"]
        translationRoot = p3
        repository = /home/git/repositories/p3.git

As soon as you’re happy with configuration, enable migration:

$ sudo -u www-data subgit install /var/svn/repos
SubGit version 1.0.0-EAP ('Miai') build #902

That’s all, Gitolite and smooth Svn To Git migration is now configured!

Smooth Svn to Git migration

Commit changes to Subversion and Git users will pull them into their Git clones, push commits to Git repository and Subversion users will receive them. Try it :)

In case you have any questions or suggestions, please feel free to contact me at

5 thoughts on “From Svn to Gitolite

  1. Pingback: Blog bookmarks 02/08/2012 « My Diigo bookmarks

  2. Great article! How would you modify this process if your git server is on a different machine?

    We have a legacy SVN server on one machine and I have git and gitolite on another. How do I tie them together with subgit without moving one or the other to the same physical machine (that may happen, but not right now).


    • Hello Dan,

      Right now it is not possible with SubGit, but there are ways to do that in general.
      I think we may implement it for SubGit 2.0.

  3. If you want to rock GIT over HTTP(S) as well (why limit to SSH? :) )

    ServerName repos.domain.tld
    DocumentRoot /home/subgit/public_html

    Options None
    AllowOverride none
    Order allow,deny
    Allow from all

    # Optional for added security
    SuexecUserGroup subgit subgit

    RewriteEngine On

    RewriteCond %{QUERY_STRING} service=git-receive-pack [OR,NC]
    RewriteCond %{REQUEST_URI} ^.*/git-receive-pack$ [NC]
    RewriteRule .* – [E=AUTHREQUIRED:yes]

    # Per project
    ScriptAliasMatch “(?x)^/((HEAD | info/refs | objects/(info/[^/]+ | [0-9a-f]{2}/[0-9a-f]{38} | pack/pack-[0-9a-f]{40}\.(pack|idx)) | git-(upload|receive)-pack))$” /home/subgit/bin/$1

    # For multiple projects
    #ScriptAliasMatch “(?x)^/(.*/(HEAD | info/refs | objects/(info/[^/]+ | [0-9a-f]{2}/[0-9a-f]{38} | pack/pack-[0-9a-f]{40}\.(pack|idx)) | git-(upload|receive)-pack))$” /home/subgit/bin/$1

    Order Allow,Deny
    Deny from env=AUTHREQUIRED
    Allow from all
    Satisfy Any
    AuthType Basic
    AuthBasicProvider file
    AuthUserFile /usr/local/apache/passwd/passwords
    Require valid-user

    SSLEngine On
    SSLCertificateFile /etc/ssl/certs/domain.crt
    SSLCertificateKeyFile /etc/ssl/private/domain.key

    $cat /home/subgit/bin/

    export GIT_PROJECT_ROOT=”/home/subgit/repos”
    export GITOLITE_HTTP_HOME=”/home/subgit”
    export GIT_HTTP_EXPORT_ALL=1

    exec /usr/local/bin/gitolite-shell

  4. This looks like what I want to do, however the instructions don’t seem to match what is currently available in gitolite. I’m guessing these instructions are for an older version of gitolite. Could you direct me to updated information for this setup?

Leave a Reply

Your email address will not be published. Required fields are marked *