I’ve been using SVN for several years now, since late 2005 or early 2006, and its done me well since then. But a new darling has entered my life and its name is Git. I like git for some very specific reasons: It’s stupid easy to work with and as good or better then SVN for reliability. Also it helps that my preferred IDE, Komodo, recognizes and works with Git as well.
That said, I use google code for hosting my public projects and it only supports SVN and HG. So one night I read up on git and noticed that it had a plugin/support for bridging to a SVN managed repo. So began my journey.
!Note – I am using a client side credentials manager, if access to your repo requires authentication credentials you will need to supply them where appropriate.
Bridging a new Git Repo to a new directory in SVN
Now I’ve got a fresh/empty svn directory
Now I’ve got a local git repo that has most of the information I need for the bridge, to verify everything is hunky dory so far:
$git svn fetch #r26 = a47a908ea96bec2d737f6646c47418778ce6ad32 (git-svn)
Final steps, the graft
Some tutorials out there say you should run git svn rebase or such, but doing so has gone poorly for me with results like
$ git svn rebase fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree. Use '--' to separate paths from revisions log --no-color --first-parent --pretty=medium HEAD: command returned error: 128
I believe the problem relates to lining up your local Git repository with the remote SVN repository. Unfortunately I was somewhat stuck in trying to figure out how the hell to fix this problem for a long time. Fortunately Google search is the modern day version of a genie, it can grant you the information you seek, but first you have to know what to ask. Which led me to finding this blog post.
I am not doing things “exactly” like the aforementioned blog, but close enough that I can get a similar result.
$ git show-ref 2a41e85e0dc264cfdb6c04b59547a3093c02f64f refs/heads/master a47a908ea96bec2d737f6646c47418778ce6ad32 refs/remotes/git-svn $ git log --pretty=oneline master 2a41e85e0dc264cfdb6c04b59547a3093c02f64f Initial import, copied from ping project $ echo "2a41e85e0dc264cfdb6c04b59547a3093c02f64f a47a908ea96bec2d737f6646c47418778ce6ad32" >> .git/info/grafts
Since I am doing things a little odd/differently, there is no “trunk” branch available. But the idea is close enough to duplicate. I’ve already made some add/commit’s to my local Git repo but there isn’t a logical way to tell git/git-svn that this local commit also belongs to my remote SVN remote. A more human friendly version of git show-ref is
$ git branch -a * master remotes/git-svn
So the concatenation of the two internal reference’s into .git/info/graft helps git-svn understand that the two separate repositories belong to each other. Sometimes it’s nice when a configuration structure does what it’s called.
That said, on to the next obvious step, actually pushing changes from a local Git repo to SVN.
What’s going on here?
As I am still learning the finer points of Git, it was important to me to understand what exactly .git/info/grafts does. So turning to my favorite resource for arbitrary questions… I found an answer on Stack overflow: What are git info grafts for? And a more official answer in the Git Wiki http://git.wiki.kernel.org/index.php/GraftPoint