Sunday, March 16, 2008

Forthcoming changes in Bunjalloo

An update on the status of Bunjalloo. I'm fiddling about with options and how to present them at the moment. Last release saw a change in the way I deal with configuration. Up until 0.5.4, the release zip would overwrite the config.ini, search.cfg and allowed cookies file. It was pretty unlikely that many people actually changed these files, since the configurable things have been a bit limited and changing them required a bit of effort, but as options are added it is more and more likely. Well, now it will be possible to change the language and default download location from a configuration screen. The design is typically lo-fi, but seems to work okay.

Next up is to make the list of pages allowed to set cookies editable. The default behaviour of all popular browsers - allow anyone to set any cookie - is not a very wise choice from a privacy point of view. So I've gone the other way and made the list of allowed sites whitelist-based. If you're not on the list, you're not setting cookies. However, in order to add a site to the list one has to use an external editor, which isn't too user friendly. A way to do this from a settings screen is on the list of things to do.

If the release doesn't drag on, I also want to add an automatic updater, as suggested by Sarvesh. This will probably be semi-automatic - i.e. a button with "check for updates" - since the DS network is not the fastest and over zealous checking would be most irritating. This requires adding (at least) unzip support, so would be quite a big addition. It would also mean that zip files could be opened up from within Bunjalloo, which might be interesting.

If I manage all that, which is not likely, I also want to add configurable quick searches. These are searches that are triggered by typing a single letter followed by the search term into the address entry text box. Currently these are hard wired in the search.cfg file (g, y and w for Gogle, Yahoo and Wikipedia), but a system similar to Firefox's quick search wouldn't be too tough to add.

Of course if you would like to see any other features, or help speed up the addition of the above ones, patches are always welcome. I'd be interested to hear from anyone who has tried to compile the source code, and how it went.

Thursday, March 13, 2008

My top 6 git commands.

I've been using git for about 6 months now with my Google Code projects but I am by no means an expert. There's a lot to learn. While the documentation is complete, it can be overwhelming seeing all those options and commands. So here are my 6 git commands that I use quite often when working with subversion repositories.

1. git status

My most commonly used command by a fairly large margin. For a subversion user it can look a bit confusing at first. Why have two classes of changed files? Why not just commit all the changes? Hey, at least it can be in colour! But now that I understand the index and when to stage changes, it's absence in svn is sorely missed.

Don't forget to add this alias - it saves a lot of typing.
git config --global status
Now you can use simply git st.

2. git gui

This is a powerful mix of the status, diff, add and reset commands. By showing the changed files and letting you mix and match which ones to commit, creating meaningful patches and a logical check-in history is a lot easier. It also makes it harder to accidentally check in changes that are just for testing - though not impossible. Did I mention how much I really miss the whole staging area idea when I use subversion?

3. gitk --all

Having branches is nice, but if you can't visualize them it is pointless. This tool makes it dead simple to see what branches you have and, important for git-svn users and those who push to proper git repos, where you can see at a glance where the HEAD is compared to your remote branches.

4. git svn

Usually in the form of git-svn dcommit. I've aliased that one to svnci:
git config --global alias.svnci "svn dcommit"
This makes working with SVN repositories a much nicer experience. Being able to see all the history at a glance, commit changes instantly and "rewrite history" are especially handy.

5. git merge

When I wrote my HOWTO for using git with a Google Code repository, I mentioned that merging between branches was a bad idea. Well, that's not strictly true. At the time I was ignorant to the fact that the merge performs a "fast forward merge" if there are no other changes on the merged-to branch.


Basically, it meant that with git-svn, if you merge a branch into master, and master had not moved on since the other branch was created, it could cause master to lose its upstream svn remote trunk tracking. The solution is to use the --no-ff flag when merging.
git checkout master
git merge --no-ff mytopic
This creates an extra commit on master corresponding to the merge, which can now be dcommit'ed to subversion. Ideally the other branch would also be in subversion, otherwise the merge commit just says "merged branch 'mytopic'", with no real way of knowing what commits went into it.

Of course should you lose your git repository there would be no way to know which revisions of which branches are merged into master (trunk), even if the branches are stored in the svn server. This is more a limitation due to svn than git, as svn has no built in merge tracking. One solution would be to push the git repository to a separate server too, just in case.

6. git rebase

So you've created a local branch that you'd like to "publish" in the subversion repository. Here's how you could go about it using git-rebase and a couple of other tricks. First find the svn revision that the git branch is based on:
sha1 = $( git rev-list --boundary $branch...master | grep ^- | cut -c2- )
That should hopefully give you the commit sha1 of the branch point. Convert it to a svn revision number:
revision = $( git svn find-rev $sha1 )
Now create a branch in the subversion repository from trunk at that revision:
svn cp -r $revision $SVNREPO/trunk $SVNREPO/branches/$branch
If you run git svn rebase --all at this point, you'll have a new remote branch at the same point as the base of your git branch. Something like the image here. The hiccup now is that [branch] is not associated to the remote branch in any way. Here's where we need to rebase:
git rebase --onto remotes/$branch master $branch
This "moves" our local branch on top of the remote branch, keeping master as the parent of both. Running git-svn dcommit now will "push" the local changes on [branch] into the remote subversion branch. Ok, so maybe I don't use this command that often, but it is handy to know what you can use it for.