A git-svn wrapper that keeps git history intact

What is it?

Because I couldn't make git-svn keep my git commits (only the rebased, SVN-like version is kept, so pretty much all commit information is lost), and it was tiresome to keep two branches in sync by hand, I wrote a script to do it for me. It’s called git-mysvn because I couldn’t think of a good name. It started small, but since I decided to make it public, I tried to make it more robust and understandable, and it blew up.

Basically, it manages the history in two forms, the git history (in branch master) and the SVN history (more precisely, the git-svn history). Commits that belong to both histories are “meta-commits”. The script keeps references to the actual git and SVN commits corresponding to the latest meta-commit. These references allows it to fix things up when the SVN and git histories diverge starting from the latest meta-commit.

Features:

Requirements: the script uses git, svn, find, and a standard Unix toolbox (rm, mkdir, touch, cat). The git history must be in the master branch (though it's configurable in the code), and it is advisable to keep it linear, to avoid having to solve conflicts twice.

How to use it

Simply put it somewhere in your PATH, then go to the git repo and do git mysvn init URL-of-the-SVN-repo to initialize things (it will clean all traces of a former SVN remote). Warning: if the SVN repository was not empty, you'll get a warning, telling you to set up the references of the latest meta-commit. You can safely ignore it, unless the last commits in the SVN history are not in the git history (i.e., the SVN tip is ahead of the latest meta-commit). When you're sure everything is fine, run git mysvn commit to push your git history into the SVN repo. If the the master branch contains merge commits with conflicts, you will have to resolve them again while rebasing; when you're done, just execute git mysvn continue.

Afterwards you simply have to keep your work in the master branch, and when you feel like pushing it to the SVN repo, do a git mysvn commit. If there have been commits to the SVN repo in the meantime, they are merged into the git history (on top of the latest meta-commit), then new git commits are rebased on top of them. If there were conflicts during this rebase, resolve them. It leaves everything in a clean state, you can then execute git mysvn commit again.

Some other potentially useful commands:

Download

The script is available here.