Using Git with an SVN repo

Working with Git is a much more pleasurable experience than Subversion once you get used to the differences. Still, SVN has its benefits and it can be tricky to migrate existing repos and users to a new platform.

Luckily Git includes a set of tools that allow you to use Git to manage a working copy of an SVN repository. You work with Git in your project but push up changes to the shared SVN repo. So you get the benefits of working with Git daily without ditching your existing SVN repos.

Why Do This?

On a side note, I started experimenting with git-svn for practical reasons. In WRDS we have a fairly large repository for our web site that’s accessed by developers, data specialists, and non-developer professionals. The repo serves the team well. But it was created initially without the conventional /trunk /branches /tags directory layout.

I’m working on concurrent projects and needed to branch my code to easily switch between working changes. But since Subversion branches are created on the server side it would be tricky to do.

Using git-svn lets me create branches locally in my working directory without affecting the shared SVN repo. In the future, it might be worth the effort to redesign our shared repo. For now though git-svn gets me what I need with minimal disruption.

Basics of git svn

Initial Checkout

Getting started with git-svn is as easy as this command, similar to an svn checkout.

git svn clone http://wharton.unfuddle.com/svn/AllIDoIsWinWinWin

Committing

After that you can run normal Git commands against the working copy.

git status
..
vim WinWinWin.html
vim NoMatterWhat.html
..
git add .
git status
..
git commit -m'Added a file to the project'

Pushing Commits to SVN

The commit command does not commit to the SVN repo the way that an SVN commit would. Instead it works just like Git committing only to your local repository. When you are ready to push your changes back up to the SVN repo you call the following:

git svn dcommit

This pushes up every commit from the Git master code line up to the linked SVN repo as an individual SVN commit.

If you’ve done work in Git only branches and merged them into the master line, only the changes you merged in will be pushed up. Unmerged changes will not be pushed up.

Pulling Updates from SVN

You’ll also need to pull down from SVN to get the latest changes from your teammates. That’s done with this command, similar to svn pull:

git svn rebase

Some Gotchas

The initial pull takes a long time

The git svn clone command polls SVN for each historical commit and creates a local corresponding Git commit. This takes a long time.

Slow on Scorpio-Dev, blazingly fast locally

After the initial pull down, things are really fast. Just like SVN though, Git relies on files for tracking repository history. And just like SVN, Git operations can be very slow over network file shares particularly on Scorpio-Dev.

On a sizeable file share repo, git status can take a few minutes to complete. The same is true for svn status calls though. My advice is to work on your desktop if you can to avoid the lag. If you can’t, you’ll have about the same lag as you would with SVN.

Workflow

All commits you make to the Git master line will go to SVN. Git allows for history rewrites in various forms. So it’s a good practice to create Git only working feature branches in your Git repo, commit away on those as often as you like.

Then when you’re ready to push to SVN squash your changes down into singular commits back to the master or SVN linked branch lines. Then push from those lines back to SVN. This will help keep your master and SVN linked branch history lines clean and linear, just the way SVN likes them.

SVN ignores

This one is important. Git svn does not automatically replicate any svn:ignore properties that you may have setup in your SVN repo. After your first checkout is done, fire off this command:

git svn create-ignore

This will replicate your svn:ignore settings in appropriate .gitignore files. You’ll then want to commit these new files to the Git repo.

SVN branches

Attach the -s switch to your inital clone command if your SVN repo has the conventional /trunk /branches /tags layout. Git will then create any remote SVN branches in your local repo.

You can also override these folder paths if they’re nonstandard or ignore them completely by leaving -s off if you don’t want branches pulled down. See git svn docs for details.

Permission changes flagged

If you start experimenting locally and then copy your Git repo to a remote machine then you might run into file permissions changing on your files unexpectedly. This can cause all files to show up as changed in your Git repo. The following command forces Git to ignore these changes:

git config core.filemode false

Don’t link up to other Git repos

One of the nice features of Git is linking up a local repo to multiple remote repos. If you’re connecting a repo to SVN though don’t connect to other Git repos like a Github or an Unfuddle Git repo. SVN likes its history linear and static. Git is more dynamic and introducing complexity into your history could cause major problems for SVN.

Resources

This entry was posted in Development and tagged , , , , , . Bookmark the permalink. Follow any comments here with the RSS feed for this post.

5 Responses to Using Git with an SVN repo

  1. Adam Tuttle says:

    Great guide, thanks for posting it. I’ve been playing with this a little bit myself, but not as much as you have, I’m sure.

    Would it be worth fleshing out the Workflow section — specifically what you do for squashing commits — a bit so that there is less ambiguity? I would like to see that, and I’m guessing anyone else considering taking the dive would too.

  2. David Konopka says:

    Git workflow is a topic unto itself. There are a few good articles out there that breakdown solutions that work for the authors. It’s definitely something a group should settle on before using Git for revision control.

    For using git svn on your own though, I think you should be ok just using squashed merges to move changes to the master line.

  3. Hector Castro says:

    Another issue I noticed is that if you don’t have your Git configuration e-mail address match your Unfuddle account e-mail address, repository history will look inconsistent (compared to Subversion).

    git config user.email "username@wharton.upenn.edu"
    

    Overall, setting up git-svn has been worth the the effort just for the ability to commit multiple times before pushing centrally.

    @Dave – I like your naming conventions.

  4. Adam Tuttle says:

    Hector, good point. Perhaps even important enough for Dave to assimilate up into the post-proper? In case anyone is not aware, you can have both a global default email address set:

    git config --global user.email "you@yourdomain.com"

    As well as the per-project setting (run the command from Hector’s comment while inside your project folder).

    I generally use my personal email address as my global email setting for personal projects, and will be using per-project config to set my Wharton email address as needed.

  5. Jamie Ly says:

    Thanks Dave, this was a big help! I personally love to use Git, but Learning Lab mostly uses Subversion.

Leave a Reply


University of Pennsylvania Logo
Copyright © 2014 The Wharton School, University of Pennsylvania