Getting Started With Git-Svn

December 11, 2013

Often when working with clients, I do not have the luxury of choosing my tech stack and using preferred tools. One of my recent challenges has been dealing with a Subversion repository for version control. I decided to integrate git-svn into my workflow in order to add a little more sanity to my day. Below are details of the basic setup and some of the questions I encountered during my adventure with git-svn.

Prerequisites

This assumes you have git-svn already installed. To be sure it’s available, run this at the command line:

$ git svn --version
git-svn version 1.8.4.2 (svn 1.6.18)

If not available, you will need to upgrade your version of git.

Clone the repo

To start, we will clone the remote svn repository. This will take as long as you have svn revision history for the entire repo. Adding the -r option will only grab history from a specific revision forward. The -s options indicates my svn repository has the standard layout of trunk, tags, and branches.

$ git svn clone <the_svn_repo> -s

Working with master (a.k.a. trunk)

By default, the master git branch is mapped to svn trunk. The master branch is mapped to the svn trunk.

$ git branch
* master

Make changes to trunk/master:

$ touch some_file
$ git add some_file
$ git commit -m "Adding some_file"

At this point, changes are in your local git svn master branch. To push these changes to the remote svn repository:

$ git svn dcommit
git svn dcommit
Committing to file:///the_svn_repo/trunk ...
	M	some_file
Committed r8
	M	some_file
r8 = 3c16f3e39bc53c536a840060f4cbff2b98cba630 (refs/remotes/trunk)
No changes between e9c6be90d53f7ece289533e2ff559a646a9d1b3b and refs/remotes/trunk
Resetting to the latest refs/remotes/trunk

dcommit pushes the changes from your local git svn branch (in this case master) to the remote branch (in this case trunk). Similar to svn commit.

Working with branches

To see what remote branches you can switch to:

$ git branch -r
branch1
branch2
tags/tag1
trunk

To fix a bug on an existing remote svn branch, create a new local branch based on that remote branch.

$ git checkout -b bugfix branch2

Make your changes to the bugfix branch:

$ touch some_file
$ git add some_file
$ git commit -m "Adding some_file to bugfix branch"

At this point, changes are in your local git svn bugfix branch. To get these changes into the remote branch, dcommit.

$ git svn dcommit
Committing to file:///the_svn_repo/branches/branch2 ...
A some_file
Committed r10
A some_file
r10 = c1f3dbbc1704aaa1406798ee784e9375b4c590c5 (refs/remotes/branch2)
No changes between 82b8c93d98ff9975d6981cd56198a06b93b4e132 and refs/remotes/branch2
Resetting to the latest refs/remotes/branch2

dcommit pushes the changes from your local git svn branch (in this case bugfix) to the remote branch (in this case branch2). Similar to svn commit.

Questions

How do I get updates from the remote svn repository?

This will fetch updates for the current branch and replay your local commits on top. It is similar to svn update.

$ git svn rebase
How do I know what branch I will dcommit to?

Running dcommit with the —dry-run option will pretend to dcommit the changes, but instead print out the diffs that will be committed to svn.

$ git svn dcommit --dry-run
Committing to file:///the_svn_repo/trunk ...
diff-tree 2bb32345fae045037c125d520bbb8b770e5cf5cb~1 2bb32345fae045037c125d520bbb8b770e5cf5cb

The result can then be used to view a diff of the change:

git diff-tree 2bb32345fae045037c125d520bbb8b770e5cf5cb~1 2bb32345fae045037c125d520bbb8b770e5cf5cb -u

Just don’t forget the -u at the end of that command.

How do I get my svn and git-svn ignores configured?

The following will shove all the svn:ignore metadata into the .gitignore file which you can then version control. The .gitignore file will need to be maintained using this command as svn:ignore metadata will occasionally change in the remote svn repo.

git svn show-ignore > .gitignore

This file can then be committed to the repository. If you prefer to not pollute your remote svn repository with git metadata, you can also add .gitignore to the .git/info/exclude file. Each developer using git-svn will need to do this and maintain their own .gitignore file. show-ignore can be slow and painful so committing it is recommended.

That’s It!

… for the moment. Stay tuned for a future post detailing how to “catchup” your branch with master/trunk and “reintegrate” it back into master/trunk.