At my job, I'm currently spearheading a move from an SVN patching model to a Git branching model. This should make it easier to do things like manage releases and streamline development. But we have a lot of finished work that's been queued up for future monthly releases for some time. So I ran into the problem of expediting the move to Git with all of this extra stuff that still needs to get in, that was committed using a different paradigm.

So what's an appropriate way to incorporate these SVN changes, currently sitting in queue in the form of patches, into a Git repository? Some might say a transitional period using git-svn. That's not the direction I plan on taking, because I'm a big believer in creating expertise out of necessity. If someone feels like working on SVN still, they will, and then we'll have disparities in knowledge once Git is fully adopted.

Let's assume we're working with a successful Git branching model.  Let's also assume that your SVN code has gone through a release process and been appropriately tagged. In this case, my Git codebase in master is identical to a previous SVN release. It doesn't have to be, since we'll be merging branches. Here are the steps I've developed to incorporate new changes from a minor SVN release to the up-and-coming Git model.

  1. Branch from master. Usually, when you're working on new code, you'll want to branch from your development branch, but in this case you're taking code that's ostensibly been prepped for release and process-vetted within SVN.
  2. Export your SVN tag to your Git branch. Use the --force option when exporting so SVN won't complain that there are already files in the folder you're exporting to.
  3. Review your changes. It's always a good idea to see what got added and what got modified. Does it look like your new release?
  4. Push this branch forward as a release candidate. You've already tested this, right? Well, test again real quick, just to be safe.
  5. Merge the branch into master, increment the tag, and push to origin.
  6. Merge master into next. This ensures your changes are added to the development branch. People working on branches have the option to rebase them onto the latest HEAD of next or to just merge their changes in later. I'd suggest they merge with the --no-commit option so they can review their changes.

Using this workflow, you can sneak in a few more SVN releases before finally dumping it like a sack of moldy potatoes. Note that you'll only really have one informative commit for all of the changes that you made to increment your tag. If you're running a patching model, there's still a chance of this in SVN if your release is prepared all at once. Because of that, I view the loss in revision history as unfortunate, but acceptable. Ultimately, moving to Git improves your ability to read the logs without all the patching cruft and really get a feel for the changes that took place from commit to commit.