Sunday, 10 February 2013

Moving source control from svn to git

Ok, git tricked me here by having a clone operation that isn't really a clone. In my book the result of a clone should be identical to the original. In the git world that's not quite true - the clone doesn't have branches like the original. Sure it has the branches tucked away somewhere inside the .git folder, and you can check them out from the remote and track them as a local branch if you need to, but if you list the branches available to you you'll find just master. Now, if you take it one step further and clone the first clone you made, the second clone seems to have no visibility of the branches at all...

Now, in general use, the no-branches-in-a-clone workflow makes a lot of sense - you don't want to know about someone elses branches by default, it would just get too messy. However when you want to clone a repository to move it to a new server (or in my case to move it from svn to git), the git clone operation is a problem.

Fortunately the solution is to run a fairly simple script to checkout each remote branch and track it as a local branch.

for remote in `git branch -r | grep -v trunk `; do git checkout -b $remote $remote ; done

I'm working in a repository that came from svn - hence the 'trunk' check. If you are pulling from git, replace the grep -v trunk with grep -v master.

To do the actual pull from svn to git is pretty simple using the git svn command

git svn clone "svn://server/repository"  "repository" -T trunk -b branches [-t tags]

Once you've done that, do the remote branch checkout script above to track all the remote branches. Note that it's best to access your svn repository via a network protocol (svn:// https:// svn+ssh://) rather than a raw svn repository on a local path - this is because git svn only understands really old svn repository formats, so will fail with repositories made by a recent version of svn.

I'm using gitolite to host my git repositiories on my linux box - that seems to expect raw or 'bare' git repositories. I used the standard gitolite methods to add a new repository, then deleted the newrepo.git folder that got created and copied the .git folder into its place. Fix the ownership/rights on the new folder if necessary (chown -R git.git newrepo.git ; chwon -R 700 newrepo.git) and you're done.

No comments: