Retroactive svn import into git


Here is my problem:

  1. I used Subversion for some time, until I switched to Git. Some more time elapsed.
  2. There was no import of the history from Subversion to Git. It was a strict checkout, delete of the .svn dirs, then git init. Not a smart move.
  3. Now, thousands of git commits later, I find a backup of the Subversion repo made at the time the first git commit occurred. Aha!

I would like to roll back the git repo to day 0, properly import the svn repo, then reapply all git changes, thus correcting what was not done the first time.

Has anyone attempted this? How would I go about doing this? It sounds like the mother of all rebases.

Best Solution

Sounds like a job for git grafts. The documentation for this is a bit sketchy, but basically what you want to do is this:

  1. Get a git-svn copy of of the svn in your repo. Easiest way to do this is to git svn clone in, then fetch the the svn clone in your existing repository
  2. Figure out which base commit should follow the svn commit. So you probably have a git root somewhere ("Last SVN version") which should follow the last actual SVN version. This is the head of git-svn clone you just fetched
  3. 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.
  4. You can now check with gitk/gitx/whatever that the two repositories are connected
  5. To make the change permanent, run git filter-branch. You'll probably want to read its manpage first.

You can do step 3 for all your branches too of course. Problem with jpalecek's approach is that the rebase will flatten your history, so if you had any merges, the rebase will lose them. The filter-branch approach keeps your history intact.