Using Git for Rockbox Version Control
Why Git ?
Currently, the Rockbox source code repository is held in subversion, which the project started to use around January 2007, so the question "Why Git?" is probably quite a good one. The debate surrounding this subject came up on the 4th of June 2007, after a number of the Rockbox IRC dwellers watched a presentation given by Linus Torvalds around usage of git. There were a number of good points made around the topic, and I actually ended up emailing the git-users mailing list with some questions that we came up with. To my complete surprise, some of those points were answered by Linus himself, and he didn't call me an idiot for asking them - so I was doubly pleased
IRC log of git debate
Mailing list question and answer session
I intend to sum up most (if not all) of what was said above later on in this article, but I thought I'd post the links to the originals for those that are keen to see if I'm para-phrasing or just plain lying about what was said
No, really - Why Git ?
Okay, so I sort of skipped answering that in the first paragraph! Perhaps a better way of asking it is "What does Git offer that Subversion doesn't?" - at least that doesn't allow me the cheesy answer of "Because!".
There is one very large difference between Subversion and Git, and that is the overall implementation philosophy. Subversion is a centralised repository - in that we have one server (svn.rockbox.org) which is the "Master" copy of everything that comprises the Rockbox source code. Developers "check out" a copy of that repository to their local machines, make changes to it, and then - when they're happy, the submit those changes (commit) them back to the central server. Git's approach is known as a "distributed" approach. Technically, there is no central repository (although this is possible to set up), everyone's copy of the repository COULD be the master. All changes made to your git repository are made locally, and other people will not get a copy of those changes until they decide to "pull" them from you.
That's the broad philosophy difference. There are also some technical differences which make git an attractive choice for the determined and enthusiastic developer. First and foremost amongst these is something called "Branching and merging". This is something which nearly all version control systems claim to offer, but which a lot fail to do very well. CVS, for example (which Rockbox used to use) is bad at both of them. Subversion makes the claim that "Branching is way faster than in CVS" - which may or may not be true, but they fail to tell you that the merging part is still pretty much as bad as CVS's implementation. (Note to the reader: Those are quotes para-phrased from Linus's speech, not my personal opinion - I've never tried doing this under either CVS or Subversion personally, so don't shoot me if I'm wrong). In Git, branching and merging are extremely quick and easy (and I have
tried this personally, so I can confirm it's true!).
So why the fuss over this "Branching and Merging"? What does it mean?
Branching is something that helps developers when they want to start work on a new feature for their code tree. The idea is that you leave the "Trunk" (the main repository) part of the code alone, take a copy of it ("branch" it), make some changes, and only commit your new feature changes back to this branch. This means that while your new code is in flux, and liable to not work very well - the main repository is unaffected by it, and people can continue to work on bug fixes there safe in the knowledge that whatever they're looking as is not as a result of new untested code. At some point in the future, when your new feature is completed and ready to roll, you "merge" this branch back into the trunk, and the main code repository now has the new feature, fully working (hopefully) all in one hit.
Currently this sort of work is a bit of a pain with subversion. A developer working on a new feature must keep his own copy of the subversion repository out of step with the main one until he's happy it's all working. He may have multiple copies of the repository for multiple features, and there's no easy way to bring all these seperate changes back into step in a clean way.
Git's implementation of this feature is very good - branching is "cheap", you can have lots and lots of them all off the one repository, and merging them back in again is also a relatively painless task (completely painless if there are no conflicts between a new feature and something that's changed in the main trunk).
If Rockbox were to move to git, with repositories all over the place - it then becomes possible for git repository owners to "Cherry Pick" a certain feature from a given repository elsewhere. This means you can take things you like, and ignore things you don't. This might end proving to be a popular choice for users of "Unsupported builds", who could then maintain their own tree full of all the patches they like, and leaving out the ones they don't.
So would Rockbox really benefit from a change to git ?
Possibly. There were some favourable noises made by some of the developers, and some who were less keen on the idea. At the moment Subversion does
work for the way Rockbox is developed and most people who use it are happy enough. Anyone who is used to their own way of managing multiple changes to their local subversion tree have already worked out their own system for doing it, and most of those are happy to continue with this method.
Me personally, I start to see git as a very useful change - particularly
for our Google Summer of Code people. We have students, and we have mentors that are supposed to be helping them. Most of the mentors are also current developers. This means the mentor has got a copy of Rockbox's subversion repository as it stands, and possibly one which includes the changes their student has made, and possibly yet another with their own changes. If we were using git, this rather messy (IMHO) approach would be a whole lot neater, since the students could maintain their own repository while they were implementing their project, the mentor could sync this with a branch in their own repository, keep the main trunk clean, and also have their own branches for things that they themselves are working on.
Ultimately it will depend on if enough people see these as real advantages over "just nice to haves".
Using git with the SVN repository
First, to understand the basic principles of git in comparison to those of SVN, the SVN Crash Course
is a good reference.
What follows was written for git-svn version 188.8.131.52. It might not be accurate for other versions.
To get the official SVN repo, N being the revision you want to start your history with, run
$ mkdir rockbox ; cd rockbox
$ git svn clone -rN svn://svn.rockbox.org/rockbox/trunk .
$ git svn rebase
Or if you want the whole history :
$ git svn clone svn://svn.rockbox.org/rockbox/trunk .
Once this is done, compress your local git repo :
$ git repack -d
If there are new commits in the SVN repo, you'll want to get them in your master branch :
$ git svn rebase
To commit work you've done on your git repo to the SVN repo, run
$ git svn dcommit
Since git does not have the concept of properties, you should add the following to your $HOME/.subversion/config to have some properties automatically set on svn dcommit (otherwise you need to set them separately on new files with a separate SVN checkout).
enable-auto-props = yes
*.c = svn:eol-style=LF
*.s = svn:eol-style=LF
*.S = svn:eol-style=LF
*.cpp = svn:eol-style=LF
*.h = svn:eol-style=LF
*.ui = svn:eol-style=LF
*.sh = svn:eol-style=LF
*.pl = svn:eol-style=LF
*.pm = svn:eol-style=LF
*.py = svn:eol-style=LF
*.txt = svn:eol-style=LF
*.cfg = svn:eol-style=LF
*.wps = svn:eol-style=LF
*.sbs = svn:eol-style=LF
*.vbs = svn:eol-style=LF # should this be CRLF?)
*.png = svn:mime-type=image/png
*.jpg = svn:mime-type=image/jpeg
*.bmp = svn:mime-type=image/bmp
*.svg = svn:mime-type=image/svg
Makefile = svn:eol-style=LF
The public Rockbox git repository
There is a mirror of Rockbox's SVN repository available at git://svn.rockbox.org/rockbox-old. You can easily clone it and then turn it into a git-svn repository. Here's how to do it :
$ git clone git://git.rockbox.org/rockbox-old
or if you are behind a restrictive firewall:
$ git clone http://git.rockbox.org/rockbox-old
$ cd rockbox
$ git update-ref refs/remotes/git-svn origin/master
$ git svn init svn://svn.rockbox.org/rockbox/trunk
$ git svn fetch
Now you have a local copy of the full Rockbox history and you can use
git svn rebase
to keep track of the latest SVN updates and
git svn dcommit
to commit your changes.
Copyright © by the contributing authors.