Take the 2-minute tour ×

The situation
I have a Git repo and an SVN repo that both hold the same source code but different commit histories. The Git repo has a lot of small well commented submits... while the SVN repo has a few huge commits with comments like "Lots of stuff". Both series of commits follow the same changes made in the code and are roughly equivalent.

The desired outcome
I would like to switch to using Git-SVN without losing the detailed history from the current Git repo. This should be done by 'grafting' the history from the Git repo onto an SVN branch of the project (branched from the point I really started using Git).

Why would you do that? (history)
A while ago I started to play with Git. I started by setting up a Git repo in a project I had under SVN control. With a little config, I had both Git and SVN working in parallel on the same source code.

This was a great way for me to learn and play with Git, while still having the safety net of SVN. It was a sandbox with real data basically. I didn't have the time to really learn Git but I really wanted to tinker with it. This was actually a pretty good way to learn Git for me.

At first, after doing some edits, I would commit to SVN and then to Git... then play with Git knowing my changes were safely in SVN. Soon I was committing more frequently to Git than SVN... Now, SVN commits have fallen to an annoying chore I have to do sometimes.

When learning the difference between git revert and svn revert I was VERY glad I had been checking in to the SVN repo. I almost lost a few weeks' work assuming that the two worked the same.

I now know the glories of Git-SVN and I am using it happily on several other projects. I fully realized when I started that I might lose my Git repo and have to setup a new one 'properly' using git-svn init... but having played with Git for a while now, I'm sure there is some way of hacking the Git history into SVN.

share|improve this question
add comment

6 Answers

That could be tough to do what you want. You can import a git repo into svn via something like this: http://code.google.com/p/support/wiki/ImportingFromGit, but I think you will have conflicts. You could just recreate your SVN repo from scratch based on your git repo.

For future reference, it probably would've been easier to just use Git as an SVN client:

git-svn clone path/to/your/svn/repo
git-commit -a -m 'my small change'
vi some files to change.txt
git-commit -a -m 'another small change' 
git-svn dcommit # sends your little changes as individual svn commits
share|improve this answer
Unfortunately the linked article starts by cloning the svn repo to create the git repo. As both are created and non-empty in my case it doesn't really help. –  Kev Sep 22 '08 at 21:37
add comment

I think this should be possible in one of two ways... I'll outline them now and try to flesh them out later if I can figure them out. If anyone can see how to flesh a part out or knows why a part won't work... please comment!

1 - In place using git-svn
(The following are pseudo commands THEY ARE NOT REAL - DO NOT USE THEM)

rm .svn
(configure git-svn '/myproject/branch/git-remerge')
git svn sync_versions --svn_revision=123 --hash=ad346f221455
git svn dcommit

2 - Using a separate git-svn repo as a proxy

mkdir ../svn_proxy
cd ../svn_proxy
git svn init
git checkout hash_of_svn_branch_point
git pull ../messy_repo
share|improve this answer
add comment

You may want to checkout Tailor. I used it to convert a git repository into an svn one so that my work could be hosted in our company svn server. It's quite flexible, so it may be able to do what you want.

share|improve this answer
It looks like this would work! In my case I'm really looking to understand git deeper using this as an exercise... so I'm not going to try it... but if anyone else runs in to the same problem I did on something mission-critical... this looks like a killer app! –  Kev Sep 27 '08 at 18:14
add comment

It seems that this is NOT possible. While it is possible to have the current git repo joined to the current svn repo, it does not seem possible to replay the history of the git repo in to the svn repo.

The main problem I had was getting git-svn to 'latch' on to a single svn commit. The answer to this problem seems to be git-svn set-tree. This blog post was most helpful:

This is as far as I could get trying to keep the history in svn:

git branch svn-reconsile HASH_OF_SECOND_COMMIT
git checkout -f svn-reconsile

git svn init file://path/to/repos/myproject/branches/git-import
git svn fetch

git svn set-tree HASH_OF_SECOND_COMMIT

git rebase git-svn

git merge master

git svn dcommit

The problem is that the git svn dcommit will only make one revision in svn... not one for each commit in the master branch.... therefor the history is squashed in svn.

So the easier solution is to simply jump start git-svn using set-tree and be satisfied that the history is still in git even if it's not in svn. This can be done with the following:

git svn fetch


git rebase git-svn

If anyone has any idea how to get around the squashing problem (I have tried --no-squash) please comment! In leu of clever comments I'm just going to accept keeping the git history and grafting to the most recent svn revision using the second code chunk above.

share|improve this answer
add comment

From the git svn repository that you are trying to migrate to, do something like the following:

git remote add old-repo <path-to-old-repo>
git fetch old-repo
# to browse and figure out the hashes, if that helps
gitk --all &

# for each branch you want to graft
git rebase --onto <new git svn branch base> <old-repo branch base> <old-repo branch tip>

# when done
git remote rm old-repo

For your information, you should also be able to do the same thing using git format-patch and git am, but git rebase should be more friendly.

share|improve this answer
add comment

I did a bunch of work on this when dealing with git histories for memcached from a few things. A lot of what I was working on was verifying everyone was properly credited for work.

I built a tool to generate a report showing exactly where trees converged regardless of commit hashes, git histories, authors, committers, etc... Take a look at this example report that we used to see where two unrelated repositories containing the same information converged.

From there, I just did lots of manual grafting and filter-branching after lots of google and mailing list searches to figure out who these people who contributed changes actually were.

share|improve this answer
add comment

Your Answer

