Friday, August 6, 2010

Combine local Git branches with central Subversion repository

Assuming you already heard of Git as SCM alternative for Subversion, you might also know that it includes some integration with Subversion. That provides you the option to start using some Git advantages in your daily work without worrying your local operations department, possibly in a very stealthy way.

After using the gateway for a few months, I discovered and started using another nice Git feature: easy merging and working with a separate development branch. Problem was that we usually have some debug settings enabled in some of the project files, resulting into some kind of "development" build, instead of a "production" build of the program. It is possible to fix this with some extra build configuration parameters outside the project, but using Git offers you another easy solution: just locally fork the code with your own settings.

The "master" branch contains the production code, and the "dvl" branch my modified version. Once the customization is checked into the "dvl" branch, you can synchronize ("pull") the "master" branch based on "dvl" and undo the customization. Now switch back to your development branch is just keep work like you used to do previously. Any moment you can check your workspace using "git status" and your custom patch won't bother you. It also prevents you to push the development setting to the central Subversion repository by accident with the commit all command ("git commit -a").

But how do I push the wanted (!) code changes to our central repository when I'm ready? Well, by injecting one extra step, before directly pushing code from "master" to Subversion: rebase "master" on "dvl" branch. This involves a little extra administration, so the following little shell script fragment helps me out to save typing work:


# move to master branch
git checkout master

# pull changes from dvl and re-apply patch on top
git rebase dvl

# required 2 steps because dcommit would complain about sync
git svn fetch
git svn rebase

# push changes to central SVN repo
git svn dcommit

# switch back to dvl branch
git checkout dvl


One of the drawbacks of this system, is the visibility of the patch and undo steps in the history from the master branch, also propagated to the central Subversion. Maybe history rewriting fixes this, or I could implement some some other workflow, but for the moment I'm not really troubled about that. If anyone as a better alternative, I'd be happy to learn!

Some good links: