My blog has been moved to ariya.ofilabs.com.

Sunday, April 27, 2008

SpeedCrunch and git

I have shown before how to use git to manage your code hosted in Google Code Project Hosting and how to synchronize it (automatically) with a public git repository hosted in github. SpeedCrunch, your lovely desktop calculator, is an example of all this.

Flash back first. Due to an increasing demand, some time ago we (=Johan and I) decided that we should provide public Subversion repository for SpeedCrunch. Google Code was new but quickly became the popular choice, so Johan pulled the plug and imported the then latest version of the code. This happened 840 days ago. Fast forward to today. As of now, you can also get SpeedCrunch source code from github, it is available from http://github.com/ariya/speedcrunch/. It means you need as short as:

git clone git://github.com/ariya/speedcrunch.git

and voila! You get all commits since the first time the code was imported. For fun, try git log e3cddb :-). For practical reasons, right now I only push master and 0.10 branches, which correspond to the trunk and branches/0.10 in its Google Code subversion repository. The .git directory weighs at around 5 MB.

Of course, if you decide to fix bugs and make changes, just push your SpeedCrunch repository somewhere and (if Helder, the current maintainer, has no objection), I can merge into my github repository (if necessary, I would even cherry pick your changes). Think you can do better? Go ahead, sign up for github if you haven't done so (it's free!), then you can "fork" the repository easily. Just click on the button labeled fork. When you are happy with your own tree, use the pull request button (in your github repository) to notify me and we'll see what would happen.

Note: this public git repository is by no means the official one, as the official repository is still hosted in Google Code. It is fully synchronized, though. And by using git, I hope this can spark more contributions in term of new features, bug fixes, translations, etc.

Don't you just love choices?

Tuesday, April 22, 2008

vim color gallery

From vim tip 693: the lovely vim color scheme test. There are even nice preview pages, e.g. for C/C++ highlighting.

If your choice of color scheme is not shipped with your vim, don't panic. Just click on the color scheme name, download the .vim file and save it to your vimfiles/colors directory (e.g. for typical Windows users: C:\Program Files\Vim\vimfiles\colors).

Wednesday, April 16, 2008

dancing between github and subversion repository

As the next logical step after I wrote about easily using git to work with the subversion repository in Google Code Project Hosting, here is an idea to make your git repository available and still keep it synchronized (in both directions). The use case for my previous blog post is when your partners in crime still stick with subversion but you prefer to use git. Here it is extended further: some (not all) of your contributors start to realize how beautiful git is, try to use it, can't get rid of it and finally decide it to use only git from now on. It would be a crime to ask them to sync to the subversion repository themselves, hence the following dancing. Basically it works like this. In a Unix/Windows machine, do the usual cloning of a remote subversion repository and then push it to github. Your new git fans then clone the fresh git repository. It is amazingly simple, obvious and fast to do it this way.

First of all, register at github. You don't need anything except an email address.

Next, prepare your SSH key which will be used for authentication, this can be carried out in one minute, just follow the instructions. Go back to your account page, copy your public key and paste it there in the SSH Public Keys area. Then, use ssh-agent trick to skip typing your password every single time.

Tip: if you are on a Windows box and your msysgit does not come with the ssh-keygen tool, use the famous PuTTY (known as the terminal emulation with SSH support). In the package, there is a tool called PuTTYgen (PuTTY Key Generator). Simply launch this tool. Click on Generate button and move your mouse randomly for a few second. After that, type in a secret password in the Key passphrase and Confirm passphrase fields. Click the button Save public key and name the file as id_rsa.pub. Choose menu Conversion, Export OpenSSH key and name the file as id_rsa (without any extension). After that, navigate to your user directory, this is typically C:\Document and Settings\Username. Create a new directory named .ssh, if it does not exist yet. Move both id_rsa and id_rsa.pub to this .ssh directory. Now you are set. File id_rsa.pub contains your public key, so copy and paste it into your SSH Key in the github account page.

Now here comes the fun part: create a new repository. Just fill out a few fields and it is ready. Couldn't be simpler, could it?

At this stage, go to your local git working directory (i.e. the one cloned from a subversion repository) and do the following:

git remote add origin git@github.com:joesixpack/coolproject.git
git push origin master

by substituting joesixpack and coolproject with your github login name and the freshly created git repository. Wait a couple of seconds (or minutes), then basically your git repository, which is a clone of the remote subversion repository, is successfully pushed to github. Well done!

To keep both repositories synchronized, you can run a cron job that does the following:

git checkout master
git svn rebase
git svn dcommit
git push origin master

If you have branch(es) in the subversion repository, you still can do that. Just add few more commands and substitute master with your branch(es) name.

Tip: If accidently you push your local branch to github and now you want to remove it, use:

git push repository :heads/branchname

OK. So far so good. Now of course you do not work on a single machine, e.g. you may do the above steps in a Linux server but you would like to work on your Windows laptop. At this moment, you need to prepare another SSH key or just use the same key (e.g. copy the previous id_rsa and id_rsa.pub). Then it is a no-brainer to clone your repository:

git clone git@github.com:joesixpack/coolproject.git

Note: don't be surprised with the amazing speed of doing a git clone. Essentially, you get the whole repository (which contains the full history of the project) in a short period time, probably comparable to the time needed to check out from the subversion repository (which however gives you only some part of the changes history).

Awesome. In just few minutes, you have a git repository which can be synchronized with a remote repository (e.g. in Google Code project hosting). In addition, you can push this repository to github. And still, you can clone the repository in another machine for your pleasure. Now if you want other people to clone your repository, just tell them to do:

git clone git://github.com/joesixpack/coolproject.git
cd coolproject

Once they send patches to you or push their branches, you can do the merge into your git repository and push it to github. Due to the said cron job, the subversion repository (e.g. in Google Code) will get the changes as well. Every now and then, when other contributors commit some changes to the subversion repository, the changes will be also propagated to github. Both parties are happy.

Happy gitting!

Sunday, April 13, 2008

Quick Start: using git (for Windows) with Google Code Project Hosting

Ideally everyone uses git, because just as Linus once wrote: Centralized works. It is just inferior.

And like what I expressed before, the project hosting feature of Google Code is a nice choice (much better than SourceForge) for doing collaborative works on open source projects. You have a project page, a wiki, a download space, an issue tracker, integrated statistics and mailing-list features, and of course a repository. However, up to now only subversion repository is offered. Likely because of the 80% folks reason.

That is surely not the end of the world. You can try to polish your growing git skills with that subversion repository by using git-svn. The idea is that you use git and then, once a while, you place the code in the subversion repository. This has several extra advantages than doing git only. First, there is a backup done by Google to your repository. In addition, other developers that know only how to use friendly GUI tools, e.g. TortoiseSVN, can get the code easily. And if they are the project members and contribute some code (through Subversion because that is what those poor guys are using), you can still merge their changes without pain to your master working branch. Also, your code is searchable with Google Code Search and this gives more exposure and promotes code sharing and reuse.

This short instruction is mainly targeted to "average" Windows developers who wants to use work offline using git and still are not afraid to use command-line, but not for the usual hard-core Linux geeks (who can easily recall the manpage of git even if you suddenly wake them in the middle of the night). For the latter, there are many posts that already cover it. Just so that you are aware, what is written below is not a replacement for the git-svn manual. In addition, suitably adjusted, it should also work with other types of subversion repositories beside Google Code Project Hosting's one, e.g. your company internal repository.

To get git, visit the msysgit project (which is, unsurprisingly, hosted on google code). Download the latest version that also includes git-svn, e.g. Git-preview20080301.exe at the time I write this. After that, double click the .exe file to install it. You will be presented with the installation wizard, just accept the default and continue clicking the Next button a couple of times until you finish. Usually it means you'll get git on C:\Program Files\Git and also you can right-click on Windows Explorer window to start doing some git magic from that active folder.

To initialize the git repository, from Windows Explorer folder tree, right click on a folder and choose the menu item Git Bash here. A console will open, here where you have type in the following:

git svn clone -s --username=joe.sixpack https://coolproject.googlecode.com/svn git

Of course, substitute joe.sixpack and coolproject with your Google Code user name and project name. The following message will show up:

Initialized empty Git repository in .git/
Authentication realm:  Google Code Subversion Repository
Password for 'joe.sixpack':

and then just enter the generated Google Code password for the subversion repository. If everything is fine, all the revisions in the remote Subversion repository of your project are being pulled to your local git repository. This may take a while, especially if your repository has years of history.

Note: On Windows, git-svn performance is just so-so. Maybe this will be improved in the future version. If suddenly you see git-svn fails at some point with the following error message:

 Cannot commit config file!
 config svn-remote.svn.branches-maxRev 116: command returned error: 4

then just retype your last clone command as git-svn would happily continue from where it stops (i.e. no need to pull from revision 1 again).

Now what you get is a subfolder called git (the last argument in the clone command that you typed before) which is your working folder and which contains the git repository (evidenced by a subfolder .git inside it). Switch to this git folder and you are ready for the subsequent steps.

To compact your git repository, run:

git gc

In principle, you need to do this only once a while. Here it is a good idea to do it because you just imported your whole subversion repository.

Tip: Because git repository is very compact, don't bother with disk space when you do the initial step of cloning. This is usually a point that is always repeated by your nearest git evangelist. To give an example, after cloning over 1300 revisions of SpeedCrunch source code, my git repository is only around 7 MB. On the other hand, a single subversion checkout (including all the branches) is already 51 MB. Mind you, that 7 MB contains all changes that have been committed during the history of the project vs 51 MB which is associated only with few subversion revisions only (trunk and several branches).

To start using git for your brand new cool feature, usually it is best to create a new branch for that particular feature. First, check all the branches that you might have using:

git branch -a
which gives something like:
* master
  0.6
  0.7
  0.8
  0.9
  tags/0.7
  tags/0.7-beta2
  tags/0.8
  tags/0.8-alpha
  tags/0.9
  trunk

where the star sign (*) indicates the current branch. The branch called master is created for you automatically, it is basically the local git branch to track the trunk version of the remote subversion repository.

Now create a new branch, e.g. joe/feature1, from master with the command:

git checkout -b joe/feature1 master

The name joe/feature1 is arbitrary. It won't be visible to the outside world because it is your local branch. So feel free use a naming scheme that suits you.

Time to have fun! In this branch, implement the feature that you love and do some coding there. Once you are happy, just commit it (to this branch) using:

git commit -a

Continue hacking on it until you are satisfied. Make as many commits as you like. The sky is the limit.

Finally, when you think the feature is rock-solid, to merge back your changes to master, do the following:

git checkout master
git merge joe/feature1

which means switching back again to the master branch and the apply all the changes that have been done in joe/feature1 branch. Simple and lovely, isn't it?

Now, what about the poor souls that still need to check out or update the code through the subversion repository in Google Code? Well, you still can push your changes there. To synchronize the remote subversion repository with your git master you need to do:

git svn dcommit

The other way around is perfectly possible as well. If your collaborators change something in the remote subversion repository, to keep your git master up to date just use:

git svn rebase

That is all. For more advanced techniques, refer to the git-svn manual. Don't forget to polish your git skills by reading the manual and tutorials as well as (of course) doing a lot of practices.

Tip: An alternative to the very first stage of cloning is just to populate the new git repository only with some latest revisions of remote Subversion repository. Use the following commands:

git svn init -s --username=joe.sixpack https://coolproject.googlecode.com/svn
git svn fetch -r 1300:HEAD
git gc

which will just give all the changes starting from revision 1300 to the last one (HEAD). This is of course not really recommended because you won't get access to the whole history of your Subversion repository, but it is still useful if your project is very large and you do not care with all those changes made in its prehistoric time. If you use this init+fetch method instead of clone, there is no subfolder created. Your working folder (and git repository) is where you did the init and fetch. Now you can continue the usual steps of creating a local branch, implementing your feature, synchronizing, and so on.

Don't you just love git?

Tuesday, April 01, 2008

I think I'm moving but I got nowhere

Fortunately, that is not what happens to me (anymore). I moved to Oslo a week ago. It is nice to come back to the place I have shortly visited months ago.

From now on, I am working for Trolltech, the best company to work for :-)