So Gnome has finally switched over to Subversion.
This is a really good news and a big improvement over our old CVS,
for a bunch of reasons.
So far so good. But I'm one of those who prefer git over SVN, simply because
it has some advantages that makes it fit better to the way I like to work. For
instance it has a full local history and branching is very cheap, not to say
it's very fast and easily scriptable. In two words, I love it.
And what's great with Subversion is that there is a lot of interoperability
layers between it and others SCM. In particular, since git 1.4.4 there is
git-svn,
that can fetch from and commit to a Subversion repository, in a very
pleasant way. So, here are a few hints on how to use git when you want to write
some code for the Gnome project.
Note: git 1.4.4 is probably not available in
your distro yet, so you are likely to have to compile it by yourself. No panic,
it's not hard at all. I've also requested
a backport
for Edgy.
Small overview of git-svn
So let's start with the beginning: how to checkout your favourite project,
for instance gedit. First you have to create a directory and initialise it as
a git repository.
$ mkdir gedit
$ cd gedit
$ git-svn init svn+ssh://svn.gnome.org/svn/gedit/trunk
Then you need to fetch the history from the repository. If you are not
interested in the whole history, I suggest you to do this way, otherwise you
can just skip the first one in the following commands.
$ git-svn fetch -r5000
$ git-svn fetch
$ git checkout -b work remotes/git-svn
$ git repack -d
The first command fetches a given revision (here, the 5000th one), so your
history will start at that revision. If you don't do it, you will just end up
downloading every single revision of the project, from the first one. The
third command will create a work branch (you shouldn't commit anything on the
remote branch). The last command will repack the local repository, ie compress
it, to make it smaller. After that, the whole gedit history is about 31MB big.
As a comparision, the SVN checkout weights 47MB.
Update: You can also ignore the files set in the svnignore property:
$ (echo; git-svn show-ignore) >> .git/info/exclude
Later, to update your git repository, you need to run
git-svn fetch again, and fast-forward your working branch using
git rebase, which is recomended over git merge, in
order to keep the history as linear as possible.
When you have made some changes on your work branch, you have to commit it
locally to git, then mirror the commit into SVN using
git-svn dcommit. This will actually send every single new commit
of your current branch into the SVN repository, so be careful. Then update your
local repository as usual, in order to take the changes into account. Note that
the commit messages in SVN will be the same as the ones in git.
This works pretty well, the only drawback I've seen yet is that git
rebase does not like edited Changelogs. I've also tried a
few strange commands to send several commits at once (like git-svn
commit-diff, but I won't explain those further here since if you need
to, you should definitely prettify your patches in git itself and use
git-svn dcommit.