Here’s how I use Git to work on projects that use Subversion for version control. The basic idea is to use the Git master branch to track the Subversion trunk. All my coding happens on Git branches. That way I can use Git to easily work on multiple different features or bugfixes at once, with all the usual git benefits of disconnected operation, speed and flexibility. Then I commit to SVN when my work is ready.
So the basic workflow is to work in Git branches. To make sure the Git master and the Subversion trunk are in sync, I follow two basic rules. First, the only ways the Git master changes are:
- an update from SVN trunk
- a merge from another Git branch
Second, the only time I ever use SVN to commit or update is when I am on a clean Git master.
Here are the detailed steps I use.
Starting off
> git checkout master
> svn update
Updated to revision 435
> git commit -a
> git tag svn-435
Now master is up to date with the SVN trunk.
Working on code
> git checkout -B niftyFeature
Create a branch to work on a feature. This overwrites any existing niftyFeature branch.
(hack)
> git commit .
(hack)
> git commit .
(hack)
> git commit .
Getting ready to commit to SVN
> git checkout master
> svn update
Updated to revision 439
There will be no conflicts since Git’s master branch just tracks the SVN trunk.
> git add --all
> git commit -m"Update to SVN revision 439"
> git tag svn-439
The tag can be useful for diffing later on.
Now comes the scary part.
> git rebase master niftyFeature
That rebase essentially merges your work into the latest from the SVN trunk. Git rebase seems to work better than svn merge, but even so, you might have to resolve conflicts in the normal Git way.
The rebase also switches to the niftyFeature branch.
(test)
If there are problems:
(hack)
> git commit .
Committing to SVN
> git checkout master
> git merge niftyFeature
This is a no-fail fast-forward merge thanks to the previous rebase.
> svn commit
Committed revision 440
The SVN commit may update SVN keywords if you’re using them. To avoid confusing Git, commit these changes too:
> git commit -a -m"Update SVN keywords"
> git tag svn-440
I suppose this workflow is nothing but an ad hoc, informally-specified, bug-ridden, slow implementation of half of git-svn. I already know Subversion and am learning Git, and my goal was to practise my Git rather than learn a third set of commands (git-svn). I plan to use SVN a lot less in the future, so this way I will only have to forget one set of commands, not two.
Bonus tip: Backups
You can clone your repository to another location on your file system. A good choice might be your Dropbox folder or similar. This makes it trivial to keep your entire repository backed up.
> git clone --bare . /dropbox/projectName.git
> git remote add backup /dropbox/projectName.git
> git push backup
Making it a bare repository avoids problems with pushing. Then whenever you feel like backing up (i.e. all the time), just do this again:
> git push backup
I’ve created a little shell script to make the “check in to SVN” part quicker — it automatically puts the SVN revision number in the comment and tag. Get the Gist.