02
mar

Working on Mono with git-svn

CC by-nd by W. T. L.
CC by-nd by W. T. L.

I won’t go here in depth on how to use git, the official hub has already tutorials to get you started. I’m more interested here in the workflow you can apply and the tools you can use when working on Mono with git-svn (although it can be mostly used in a general way too).

Note: this post is heavily based on the materials written by the accessibility team.

Note²: Prior of everything, your should first read this guide which explains how to setup your git-svn local copy using an existing git mirror. At this point, I expect that you have successfully completed that step.

Mirroring your work

The workflow I will describe here is rather destructive as you are going to end up merging some bits of git history when sending your commit to Subversion. As such, I strongly advise that you have another git mirror of your work somewhere to act as a backup with all your history.

You could either go public with your own server/repo.or.cz/github/gitorious/whatever or simply use a local copy situated e.g. on another drive.

In any case, this repository is not really meant for public consumption (i.e. people directly working on your git tree) as it’s going to be quite unstable with frequent history breaks.

When you are decided on where you want to host your mirror, add a remote to its location with the git remote command :

git remote add name foo@yourdomain.org:mcs.git

When you want to update your remote copy, just issue git push with the remote name and mirror option :

git push --mirror name

Synchronizing with trunk

The first thing to know is actually how to pull Subversion revisions back into your local repository. As with any command that have to deal with Subversion, the common prefix to use is git svn. This action must be done on the master branch so if you are on another one, switch back to master before doing anything else with git checkout.

Here, the command we are interested in is git svn rebase. This command will actually fetch the revisions from trunk, convert them to git commits and replay your local changes (if any) on top of them :

git svn rebase

Making changes

The equivalent of trunk in git is the master branch. This branch should remain clean of any change and should only be used when you are ready to commit your work to Subversion.

In git, branches are everywhere and are the most straightforward way to organize your changes hierarchically. As such, anything you plan to do should be separated in its own branch with a name like feature-xyz. You can also have feature branch that depends on another feature branch, I will talk about these one later and especially how to merge them back.

The command :

git checkout -b feature-xyz

Will switch you to a new branch where you can happily do your stuff.

What works well here is to follow the scheme : code a piece → commit → test → fix → commit. It will especially helps when you have to crawl back through your history at a later point with, for instance, git bissect.

Notice that commit message style at this point don’t matter, use the style that suit you the best because you are the only one who will read them.

During the lifetime of your development branch, it’s likely that some change introduced in Subversion will conflict with what you have done. As such, it’s always a good idea to frequently sync your local copy with Subversion (see above) and then rebase your development branches on top of master.

The git rebase command exactly serves that purpose and allows to rewrite partially or totally the history of a branch. In practise, this is as simple as issuing from the development branch :

git rebase master

As you see, git rebase is powerful tool but it’s also a destructive one in the sense that it rewrite your history. Rewriting history is the sort of thing that make git crazy when you are trying to pull from a repository modified that way. This is why your git backup should be considered unstable and why you have to always use a mirror or a force option with git push.

Merging work and sending it to Subversion

Let’s say your are happy with what you did, now you would like to send all that stuff to Subversion. Normally, your branch should be filled with small commits with message mainly consisting of « Ooops », « Added part foo »  or « Debugging » which you definitely don’t want to see in the Subversion commit.

That’s why we are going to do a clean summary of the change you made, update the ChangeLogs accordingly and then use a pretty automagically generated log message for the Subversion commit.

First of all, switch back to master branch. Then issue the following command :

git merge --squash feature-xyz

What this do is that it takes the most recent version of the branch tree, generate a diff and then apply it to your master tree without committing. If you check with git status, you will see that these change are notified as « Going to be committed ».

That’s when we use our first tool : clng.py.

I suggest making an alias to it or putting it in a PATH directory to be able to invoke it directly from the command line.

As you can notice, the script expects some environment variable to be set. EDITOR tells which editor you want to use to edit ChangeLog (e.g. emacs), CHANGE_LOG_NAME contains the name that should be used in the ChangeLog (e.g. John Doe) and, finally, CHANGE_LOG_EMAIL_ADDRESS contains an email address that will be put in the ChangeLog next to your name (e.g. john.doe@foobar.com).

When you have set up those environment variable properly, then from the root of the repository (i.e. where the .git directory is), just call the script with no parameter which will prompt you to edit the ChangeLog corresponding to the files you have changed. That time, use a meaningful entry.

When all ChangeLog have been edited, you still have the option to fine tune them (if you made a typo for instance). When you are finished, call the following command to validate the ChangeLogs :

git add -u

Here now comes the second script, clm.py, that will gather and pretty print what you added to each ChangeLog. It uses the same environment variables than previously.

Then, simply type git commit and copy&paste the commit message given by the script.

The two last steps are, first, to run again git svn rebase to make sure that no change got in between while we were doing the merge and, finally, launch the dcommit command to issue your commit to Subversion :

git svn dcommit

Damn, I stumbled upon a bug

It’s quite usual that during development time, you will notice several bugs in the code that is already on Subversion. Of course you would like to commit the fix right away because it’s an easy enough one. Only problem is that you are, most of time, stuck in the middle of something else with several changes in your working tree that haven’t been committed yet !

Enter git stash. This command will create a temporary branch were all your current changes are committed and then clean your working tree. That way you can painlessly switch back to your bug fixing branch, make some commits to solve the problem, and then push the fix to trunk with the same procedure as described above.

Now, it would be nice if what you were doing before take advantage of that fix (maybe it’s even a prerequisite). Good news is that you can use the same trick as in the sync section with git rebase to make your branch starts from the commit you just created.

Working with a Subversion branch

When you commit a fix, you probably want it to also live in the current stable branch of your software (Mono in our case). That require two things. First, you have to tell git-svn where the branch live and, second, you have to backport the fix.

Normally when you clone the repository in the guide above, you also get all the remote branches with it. If that’s the case then all is good and you can work from that point. If you don’t have the remote branch you are interested in, two options. Either you use git fetch to retrieve all the missing symbols (can take a good deal of time) or you directly put in the config the path of the branch you are interested in. Here is for instance the section to setup your Mono 2.6 branch :

[svn-remote "mono-2.6"]
url = svn+ssh://jlaval@mono-cvs.ximian.com/source

fetch = branches/mono-2-6/mcs:refs/remotes/git-svn/mono-2-6

[svn-remote "mono-2.6"]
  url = svn+ssh://foo@mono-cvs.ximian.com/source
  fetch = branches/mono-2-6/mcs:refs/remotes/git-svn/mono-2-6

[branch "mono-2.6"]
  remote = .
  merge = refs/remotes/git-svn/mono-2-6

The only step remaining is to duplicate the change you made to trunk to this maintenance branch which can be easily achieved with the git cherry-pick command. After the (eventual) conflicts are resolved, just issue git svn dcommit to validate this change.

Merging branch of branch

Sometimes, it happens that you are developing two things at the same time and that one of it is based on the second which translate by the fact that one of the branch depends on the other branch.

In that case, you are certainly going to end up committing the first branch first, continue a bit polishing the second one and ultimately commit it too. Problem is that, when the first branch get committed, the second one should in turn follows trunk/master happening.

Fortunately, git rebase comes again to the rescue with the onto switch. Simply merge and commit the first branch as described in the section above and then, from the second development branch, issue :

git rebase --onto master

It will move your second branch to depend on master which should happen flawlessly since the first changes are now mainline.

Conclusion

This post is of course far from exhaustive and if you have any more tip, share it in the comments.


free blog themes
21
jan

A FOSDEM talk primer

(Shamelessly inspired from Stéphane)

Since image processing is both trendy and a good candidate for parallel optimizations, I took the time to implement a little program that compute a part of the Mandelbrot set (a well known fractal) in a fancy way :

Lolipop

Now for the facts & numbers :

Sequential generation : 26.5s
Parallel generation : 13.7s
Effective speedup : 2 times faster (dual core computer)
# changes between sequential and parallel : 3 lines

Oh, and this was done using the ParallelFx bundled with Mono 2.6 that you can already use today in your applications.

More informations and tips on Sunday 7th @ FOSDEM in Mono room. Don’t miss it !

PS: Also, don’t forget Mono Hackaday on Monday February 8th.


free blog themes
11
déc

Mono happening @ FOSDEM

Mono room

fosdem_brain

So if you weren’t aware of it yet, Mono is going to have its own dedicated room at FOSDEM. In order to spread Mono awesomeness, submit talks here before the 20th. You can even decide yourself how much time you are going to use so don’t hesitate to speak about a cool software you are working on, a nice hack you have done or a how-to on a library for instance.

Mono Hackaday

banner

As a side event, there will also be a Mono Hackaday the day after FOSDEM, i.e. Monday 8th, at Hacker Space Brussels (HSB) with all the vital hacker facilities (location details here). Everyone is welcome to drop by from 10am to 19pm. There is no precise goal for the hackaday, it’s just enjoying your normal and random hacking with other Mono fellows.

Conclusion

Anyway, in all case :

FOSDEM, the Free and Open Source Software Developers' European Meeting

See you there (and bring your Rupert too) !


free blog themes
28
oct

WiFi power saving & kernel 2.6.31

As of Linux kernel 2.6.31 (currently available on Arch Linux for instance), due to a change in the iwl* drivers, the sysfs entries that were managing power saving on related WiFi chips was removed due to some power management-related bugs.

As such, it’s impossible to manually set powersaving either using sysfs or via a command like iwconfig power.

Worst part is that the drivers aren’t even correctly advertising themselves to mac80211 (the underlying layer of the WiFi stack) as able to handle power saving operations thus preventing any event to be propagated back to the driver. You can find more information about the problem on the following thread.

Of course this sucks quite a bit for people who cares about their battery life and who don’t want to wait for 2.6.32 kernel. That’s why we decided to try up compat-wireless.

Compat-wireless is a set of scripts that allows you to install the freshest drivers from the linux-wireless project (list of driver here) in a safe fashion i.e. without messing up your distribution supplied modules and without need for a kernel recompilation. These new modules are also very easy to uninstall and everything is made to prevent you from nuking too much your system.

Turns out that in recent revision of the drivers (>= 2009-10-28), powersave is back in a sort of automated fashion and blocking powersave operations are now limited to the faulty driver/chipset : iwl4965. So if you either use iwlagn or iwl3945 (lsmod will tell you) chances are good that you will get back your nice powertop output (it did for a friend and I).

As for installing the beast, the instructions on the official website starting from here are simple and straightforward.

Of course, if you were using iwl4965 your are still left out. However, if power saving weren’t breaking up your driver on earlier kernel version, you can simply comment out the .broken_powersave = true configuration statement in iwl-4965.c (line 2282 or so) under drivers/net/wireless/iwlwifi/.


free blog themes
06
oct

Wicd support patch for Banshee

Shameless plug to tell I’m alive :-) .

If you are using Wicd and usually stare at Banshee trying to download cover art or post to last.fm while you are disconnected, the following patch add just the support to fix this.

Here is the associated bug report to get the patch integrated.

In other news, school restarted with its bunch of new responsibilities, limiting significantly free hacking time.


free blog themes
16
août

How to get the max out of your PLinq query

Here are some tips you should follow if you want to get the maximum performance out of a Linq query parallelized with PLinq (at least with upcoming Mono version) :

  • Use an indexed data structure as your source like an array, a list or anything which implements the generic IList<T> interface.

    You can also use ParallelEnumerable.Repeat and ParallelEnumerable.Range as input. Notice the ‘Parallel’ word in front as it’s not the same as Enumerable.(Range|Repeat)

  • Never use an ordering operator like OrderBy and never assume that the query should be ordered.

    The overloads of some operator that provide an index integer are also to avoid.

  • As a general rule, try to stick to the general scheme of Select-Where-Aggregate with any number of Select and Where (like the famous MapReduce).

    The syntactic sugar operators based on Aggregate like Min, Max, Average, etc… can also be used.

  • If you can manage it in your code, use the ForAll method with an action delegate instead of iterating over the query with foreach

  • Of course, forbid any synchronization (locks, semaphore, …) inside the operator selectors/predicates. The purest your lambdas are, the better.

  • The functions used with operators should be predictive and stable i.e. not depend on something uncertain time-wise like a network call and should yield approximately the same execution time with each input.

    Sure, this is not always possible but if it is, it does prevent the engine from having to repeatedly balance the query execution itself.

The PLinq MSDN page contains some additional tricks and explanations if you are interested.


free blog themes
15
août

« Fundamentalist Functional Programming »

Erik Meijer, guru at MS Research, has recently given a talk at OSCON 2009 introducing functional programming in a funny way. Highly recommended if you have always wondered what all fuss about side effects and purity is about.

Check it out : http://blip.tv/file/2402061/

He even cite Mono around 4:30 (btw Erik, Mono has supported C# 3.0 for quite a long time now ;-) ).

To conclude, « Go purify yourself because you are all sinners » :-) .


free blog themes
27
juil

Follow-up on OpenVG support for Moonligh

Interested by the stuff I demonstrated some weeks ago ?

Check out the following message on Moonlight mailing-list for instructions on how to get the same thing.

Just to make you salivate :



BubbleMark running at ~50 fps without too much visual glitches
(direct link : http://www.youtube.com/watch?v=Ekfb6jCyDmM)


free blog themes
16
juil

Joining the Moonlight fun

Watching my teammate hacking on moonlight was sure to detain on me someday. So when Alan talked about making Moonlight run on top of OpenVG I got pretty hooked.

Two hacking days later, I actually got something to « work ». At the moment it’s quite rough, hacky and it probably kills kitteh too (be careful, it makes shana angry, you wouldn’t like that).

Basically, what I did is to plug the OpenVG layer inside Moonlight custom version of cairo (using that code as a base) and then tweaked Moonlight to use the new surface (together with some changes in how drawing and caching is done internally).

Following is a screencast of the thing running Bubble Mark :



(Direct link : http://www.youtube.com/watch?v=dywInr08ySg)

As you can see there are a lot of drawing issues remaining but the basic stuff is here. The code is not terribly faster (+10 fps or so) but that may come either from a bug in my graphic card driver (it already does the bizarre thing of slowing down after some time) or an other part of Moonlight.

It will definitely be better when OpenVG becomes more widespread, has more optimized implementations and can actually run on its own rather than on top of OpenGL (I’m eager to try that on top of Gallium3D when it will be ready).

As for inclusion in the mainline tree, I don’t know. I mostly did the thing for fun as a proof-of-concept and it’s certainly far too crappy to ever get integrated as is, but maybe someone will step up and do it correctly later :-) .


free blog themes
12
juil

Obviously,

Talk is cheap. Show me the code.
— Torvalds, Linus


free blog themes