Wednesday, January 9, 2013

Using git-svn for projects with many branches

About branches: Git-svn would normally clone all revisions from all branches by default. This is a time-consuming process, so I strongly recommend adding only those branches, that you need for your work.
We don't specify a branches section in our git configuration, instead we are attaching branches as new remotes. That also means, that we can't create or delete branches on a svn server, they have to be created with the corresponding svn commands. 1) Cloning the repository, checking out trunk

First create a directory where you want your git repository to be on your harddrive, than initialize a new git repository. Next you have to edit your git config and add the trunk as svn-remote.

edit .git/config and add: Next you clone the repository. This will check all SVN revisions and start a download for every revision of every file of the trunk, so this will take a while. You end up with a local branch "master" that tracks the svn remote "trunk". Type "git svn info" to show information. 2) Keeping things up to date

You should never work on the master branch, that one is only reflecting the trunk, it's a mirror, so please never change files here. Just update the master to reflect the trunk, that's all. The --ff flag forces a fast-forward.

3) Creating new local branches and rebase

Sometimes, you just want to create a new local branch and work on it. (Perhabs a small bugfix branch, that immediatly gets merged into trunk.) ... do some work … All unit tests are good, and you want to push that branch perhabs directory to svn trunk. But first, we need to rebase. Someone else could have made commits to trunk in the meantime, so you have to apply his changes first, than yours, that means rewriting your local history. .. now you have the choice, you can pick, reword, edit, squash and fix commits … .. it's always recommended to make a dry-run first, so you don't push to the wrong location accidentialy 4) Adding a new svn remote branch

Because we have so many branches, that git would force you to download them all, we just specify the explicit branches we want to track. I recommend that you specify the revision number here, otherwise git will download every revision, starting with 0 first. If your branch was created at revision 100000, you will have to wait a long time. 5) Reintegrating a single commit into trunk

In the most easiest case, you have a branch with just one single commit, so you can just cherry-pick it. Output: As you can see, the first commit is "c56d7da69e96a662aa9aad8cd394a381bad64807", but that one is just the svn copy, we don't want to merge this, so only "2db1182ddc0e85b3a9c468bd7610a58c3bb99d0a" is interessting. Lets change to master, update, run the unit tests and commit. ... run unit tests

6) Reintegrate a branch into trunk Your editor should pop up with something like this in it: Note, that we don't want to merge "0c70bbe", because that would was the svn cp command. Just delete this line. Save the file, and exit. You can even squash commit or edit commit messages. Run the unit tests again. 7) Delete the branch checkout

The following command sequence will delete (locally only) the SVN branch and its history: To remove the branch on the svn server, remove it with svn rm <branchurl>.

8) Converting a local branch into a remote branch

Basically all it amounts to is a rebase, with some svn trickery.

Next you add that branch to your git config.