Importing a git repository into subversion
2009-07-06 14:26:46
So, I've had this project that's been in svn for a while, but then a year ago I forked it and worked on it in git. Much smoother anyway :P.
But now I wanted to put it back to svn (into another repository) while preserving the history.
I found these hints, but neither worked out:
- http://markpasc.livejournal.com/186297.html
- http://its.arubything.com/2009/1/4/commit-a-linear-git-history-to-subversion
- http://stackoverflow.com/questions/457694/how-to-commit-a-git-repo-to-an-empty-repo-svn-server
- http://wiki.apache.org/general/GitAtApache
So with the help of our local git hero himself it came to a happy ending:
$ git svn clone https://svnrepo.example.org/repo/whatever [ -r XX]
$ git fetch ~/code/repo.git mybranch
$ git checkout FETCH_HEAD
$ git branch tomergeTEMP
$ git checkout master
$ git rev-list --reverse FETCH_HEAD | head -n 1
-> de53700000000000000000000000000000000000
$ git rev-list --reverse HEAD | head -n 1
-> 2a74500000000000000000000000000000000000
$ echo de53700000000000000000000000000000000000 2a74500000000000000000000000000000000000 > .git/info/grafts
$ git rebase tomergeTEMP
$ git svn dcommit --dry-run
$ git svn dcommit
To elaborate a bit:
- clone the svn repository. empty one (with trunk/branches/tags created is perfect)
- fetch the branch mybranch from a git repo
- check out FETCH_HEAD
- branch it to a temporary name
- get back to master (master of the new repo that was cloned)
now the interesting part. with grafts you can merge history lines, it needs 2 commit sha-1 values.
- get the first one
- get the second one
- put them into .git/info/grafts (format "X Y", value one, single space, value two)
- do a rebase from the temporary branch
- dry-run to check you have several diff-tree ... lines (one for each commit in the git repo)
- really commit to svn if the last step looked reasonable. This will take a while, as it does one svn commit per git commit
update: just found a helpful thread on stackoverflow:
Create a file .git/info/grafts and put the two sha's on a single line there. The first is the first git commit, then a space, then the last svn commit. This tells git that the git commit is not parentless, but has in fact the last svn commit as parent.
About
Life's a bitch, life's a whore. Nothing less, nothing more.