Repository setup

To convert from the svn repository, first setup the git repository on the alioth servers as described at Games/VCS/git. Afterwards, do the following on your local machine.

git svn clone --no-metadata \
    svn:// \
    -T /trunk/<package> \
    --branches /branches/<package> \
    --tags /tags/<package> \

Repository Setup notes

Import svn data

After fetching from the svn repository, it's now time to import the contents of the orig source.

$ git symbolic-ref HEAD refs/heads/upstream
$ git rm --cached -r .
$ git commit --allow-empty -m 'initial upstream branch'
$ git checkout -f master
$ git merge upstream
$ gbp import-orig --pristine-tar <path_to_orig_tarball>

Note: Using the --pristine-tar option is optional.

Merge svn branches/tags

Now merge the branches and tags from svn into the master branch.

$ git merge \
      $(find .git/refs/remotes -type f ! -regex '.*trunk$' ! -regex '.*trunk@[0-9]*$' \
      ! -regex '.*\/alioth\/.*' -print0 | \
      xargs -0 -r echo | sed 's|\.git/refs/||g')

Push changes

After this step, push the contents of your local repository.

$ git remote add alioth git+ssh://<username><package>.git
$ git push alioth master
$ git push alioth upstream
$ git push alioth pristine-tar
$ git push alioth --tags

Note: Using a 'pristine-tar' branch is created only if you used the --pristine-tar option above.

This step here is a way to push the tags and branches that were imported from svn (an explanation about this is below). Do this to push all tags and branches that were imported.

$ for REMOTES in `find .git/refs/remotes -type f ! -regex '.*trunk$' \
      ! -regex '.*trunk@[0-9]*$' ! -regex '.*\/alioth\/.*'`; \
      do git push alioth $(echo $REMOTES | sed 's|\.git/refs/||'); done

Editing note : Why perform this last step? git-svn will have created branches for every SVN branch, even deleted ones. Should deleted/abandoned branches always be merged?

Once you have pushed all changes to the shared repository, move the packaging directory from trunk in svn so that no one continues to work on it there.

Move old packaging directory to attic

Move the packaging directory in trunk to the attic section and leave an appropriate message.

$ svn mv svn+ssh://<package> \
      svn+ssh://<package>-svn-save \
      -m "Moving <package> from trunk to attic. Please use git repository instead."

Update .mrconfig

And, finally, add a new section for the new repo in the .mrconfig file from from our SVN trunk:

$ (echo "[<package>]" ; \
echo "checkout = git clone git://<package>.git"; \
echo) >> /path/to/the/SVN/trunk/checkout/.mrconfig
$ svn ci -m "Add <package>'s git repo to the .mrconfig file" /path/to/the/SVN/trunk/checkout/.mrconfig

Cloning and pulling

Anyone pulling from a converted repository will have two steps to perform. The first step is the usual cloning.

$ git clone git+ssh://<username><package>.git

And then the next step involves pulling the "remotes" branches and tags that were pushed.

$ cd <package>
$ git pull origin +refs/remotes/*:refs/remotes/*

Note about tags and branches

Tags and branches are preserved using what's called "git remotes". This means that there are no real git tags and branches visible, but that the SVN trunk, tags and branches are tracked as separate repositories. Downside is that you need to switch to to the remotes individually before you can update them.

All tags and branches are listed under .git/refs/remotes/ and can be checked out, but it is somewhat confusing as all old schemes for using tags and branches are there too...

So to checkout a branch do the following.

$ git checkout remotes/<some_branch>

And for tags.

$ git checkout remotes/tags/<some_tag>


Removing SVN metadata

If you do not initially use --no-metadata (perhaps you want to track the SVN repository for a while, or want to leave it in whilst you debug something) you can remove it later with

$ git filter-branch -f --msg-filter 'sed -e "/^git-svn-id:/d"'

You should not do this for a published repository. See the git-filter-branch(1) man page for more information. In particular for large histories the -d argument might be useful.