Git commit message from a text file

Once I need to do many commits and in each commit I have prepared the commit message. It’s very sensible to do this automatically since everything is already set. But wait, does Git provide a way to make it read a commit message from a text file?

After reading the manual page, yes `git help commit`, I could not find any clue on how to do this. Git provides `-m` option to enter the message inline, but I found this to be very limited since I have a paragraph long message. Git also provides `-t` to specify a template file. This is very close to what I need, however I still need to save and close the text editor which still pops up. Nah, I could not automate with this.

Then I realized that I can trick Git by changing the text editor it uses when asking user for the message. We can change the editor by setting the `EDITOR` environment variable. Git will call whatever specified there and give another parameter: the file Git will read for commit message. By default it will be set to `.git/COMMIT_EDITMSG`

So, for example, if I enter `/usr/bin/gedit` to `EDITOR`, Git will execute the following

/usr/bin/gedit .git/COMMIT_EDITMSG

Gedit application will run and Git wait until it closes. Then used whatever written in `.git/COMMIT_EDITMSG` as the commit message. We can also give parameter to Gedit, like adding `–new-window`, that will tell Gedit to open a new window instead of just using what is already opened.

$ EDITOR=”/usr/bin/gedit –new-window” git commit

That said, to make Git read a text file and use it as commit message, we can do a magic by using `cp`! Yes, the one that can create a copy! Let me show you how..

What will Git do if we set the `EDITOR` variable like the following?

$ EDITOR=”cp a-text-file.txt” git commit

Yes, Git will execute `cp a-text-file.txt .git/COMMIT_EDITMSG`, then wait until the execution finishes, and finally use the content of `.git/COMMIT_EDITMSG` as the commit message. In other words, we use what is written in `a-text-file.txt` as the commit message without touching any text editor! Perfect!

PS: This should be also applicable for other applications that use similar method of asking an input.

Tongseng – a TUIO wrapper for Mac OS X multitouch events

Introducing.. Tongseng!

If you happen to have a MacBook or MacBookPro with a multi-touch touchpad in it, get ready to access many TUIO-enabled multi-touch applications right on your Mac =D Instead of using a multi-touch table, you can also use your multi-touch touchpad to control those applications.

Download Tongseng, mount the dmg file, and run Tongseng. Click the Start button to let Tongseng sends all touches on your touchpad to TUIO-enabled multi-touch applications.

So.. have fun!

Using Prefuse through Jython

Prefuse is a very nice visualization toolkit. It is written in Java, it uses Java2D APIs to draw nodes, edges, and other visual items. It also handles events, supports animations, and other things you need to make the visualization become interactive.

The visualization display is implemented on top of JComponent. So it is very easy to embed it on another application, like what I did in LuaDeskSpot (source).

Okay, enough for the introduction. The purpose of this post is I want to show you how to use Prefuse through Jython. Yes, to make Prefuse (er.. Java, actually) scriptable!

  1. First, prepare the Jython installation.

    $ wget
    $ java -jar jython_installer-2.5.0.jar
  2. Create Prefuse jar file. I have made one and you can freely use it.

    $ wget
  3. Set environment variables. The first one is path to Jython installation.

    $ export PATH=$PATH:/path/ke/lokasi/instalasi/jython

    Secondly, set JYTHONPATH so Jython can recognize the Prefuse library.

    $ export JYTHONPATH=$JYTHONPATH:prefuse.jar
  4. Make sure the setup is woking.

    $ jython
    >>> import prefuse

    If you get no error, then good! Prefuse has been set up properly. Then do whatever you want!

  5. I have made a Jython script that calls Prefuse. Check it out at Let’s try to use it as a demo.

    $ wget -O
  6. Now you have a Jython module called igv. It will handle the basic Prefuse initialization things. You just need to do the following to use it.

    $ jython
    >>> from igv import InteractiveGraphVisualization
    >>> ig = InteractiveGraphVisualization()

    That’s for the initialization and now let’s try to add some nodes and edges.

    >>> n1 = ig.add_node("satu")
    >>> n2 = ig.add_node("dua")
    >>> n3 = ig.add_node("tiga")
    >>> ig.add_edge(n1, n2)
    >>> ig.add_edge(n1, n3)
    >>> ig.add_edge(n2, n3)

And this is the obligatory screencast.

Have fun!

um.. yes, this is the translation of my previous blog entry discussing the same thing.

Multitouch browser

I was wondering can I somehow transmit TUIO data to a browser. So I can use javascript and of course HTML and friends to build a (not really) web based multitouch application. I found no available libraries.. well maybe because it is just ridiculous to implement such thing. But hey, it’s fun to have one! So, I decided to give a try.

The first problem is browser speaks HTTP and TUIO uses OSC things over UDP. Actually, creating a TUIO application using Flash also face this kind of problem. But already have a translator that converts TUIO data (which uses OSC over UDP) to XML data that flash accepts which uses TCP connection. So, if I want to have the TUIO data arrived at the browser, I have to transmit it over HTTP.

Beside that, the tracker transmit a data when a touch event happens. In other words, the TUIO data has to be transmitted right into the browser immediately after it is produced. But, as we know, in (ordinary) HTTP connection, browser is the one who initiate connection, not the server. So, how to solve this?

Then.. i remembered Comet! It’s a concept of pushing data to a browser. Exactly fits what I need. Well.. new problem came since I couldn’t found a simple and ready to use library. One requires me to install Jetty. I tried but didn’t know what to do 😀 so I tried to find another solution. Then I stumbled upon a great tutorial that gave me more keywords for google! It was orbited, stomp, and morbidq which all share another keyword: simple 😀

After coding for several.. err.. hours, i guess, finally now I have a working prototype! See the screencast below.

Basically, there is a script that reads TUIO data from tracker. Then it transmit the data to a message queue that supports stomp. Script inside the browser then takes data from the message queue (or the other way around?) and process it. Communication between the message queue and browser is handled by the orbited. I don’t really know what happens inside =D

Well.. just see the code if you want to know more. Check it out at Have fun!

Hierarchycal graph on Tulip

Some variables:

  • input: the input (original) graph
  • orig: the same input graph, but it is made as a sub graph of input.
  • meta: a node that represents a sub graph

Creating a subgraph

Case: Some of nodes in the original graph will be grouped as a sub graph. Those nodes in the original graph will then be replaced with a (meta) node that represents that sub graph.

Precondition: The original graph must not be the root graph. Create a sub graph of it first that contains the same nodes and edges.

Graph* orig = input->getRoot()->addSubGraph();
copy(input, orig);

Subgraph creation

set<node> nodes = [ list of nodes of the original graph (input) that will be subgraph-ed ]
node meta = tlp::createMetaNode(orig, nodes);

Two local properties of the input will be created: viewMetaNode and viewColor.

viewMetaNode property contains mapping from meta node to the sub graph that it represents.

Edges to nodes in the sub graph will changed. They will be pointed to the meta node after the sub graph is created. However, the original information about the edges is saved, so it can be restored later.

Getting created subgraph

GraphProperty* gp = input->getLocalProperty<GraphProperty*>("viewMetaNode");
Graph* subgraph = gp->getNodeValue(meta);

Restoring a sub graph to its “parent”

tlp::openMetaNode(orig, meta)

Edges connections will be restored.


  1. The copy function (taken from GrouseFlocks):
    void copy (Graph *src, Graph *dest) {
      StableIterator <node> nodes (src->getNodes());
      while (nodes.hasNext()) dest->addNode (;
      StableIterator <edge> edges (src->getEdges());
      while (edges.hasNext()) dest->addEdge (;
    }//end copyFeature
  2. Edges in a directed graph are handled nicely. Might be a problem if you only expect at most one edge for every pair of nodes (simple graph)
  3. Sub graphs can contain other sub graphs
  4. Opening a sub graph inside another sub graph may lead into a problem. Open the outer subgraph first to avoid unexpected problem.

A bug in Widget’s Window picker

Yesterday, I experienced a segmentation fault in my application. After done a series of debugging that also made me compile the OpenSceneGraph (ver 2.6.1) in Debug mode, I figured out that the segmentation fault was caused from a method call from a NULL object.

The bug was in pickAtXY method of WindowManager class that is declared in WindowManager.cpp. The problematic code was like this.

    (!win || win->getVisibilityMode() == Window::VM_PARTIAL) &&
        !win->isPointerXYWithinVisible(x, y)
) continue;

Spot the problem? What if win is NULL? It should proceed to continue immediately and don’t make any call to its method. But in the above code, a NULL win would still make its isPointerXYWithinVisible() called.

The fix should be trivial. But before I made my own modification, I decided to look at the latest version of OpenSceneGraph (2.8.0 rc3) and, guess what, it is already fixed! So I only had to copy the bug-free version and pasted it to the ver 2.6.1 code that I use. The new code is like the following.

    !win ||
        (win->getVisibilityMode() == Window::VM_PARTIAL && !win->isPointerXYWithinVisible(x, y))
) {

Just swapping some parentheses and the bug is gone!

You know what, this is why I like working with Free or Open Source software. You can see the actual code that ticks you off and make changes if necessary.

Tulip plugin problem on MacOS X

So, you thought that you have failed compiling Tulip on MacOS X? The plugins can’t get loaded? Can’t find the dylib files?

Look again! Check files inside the lib directory. Let me show you mine.

[email protected] ~/apps/tulip-3.1.0/lib
$ file *
libtulip:                    symbolic link to `libtulip-3.1'
libtulip-3.1:                Mach-O dynamically linked shared library i386
libtulip-ogl:                symbolic link to `libtulip-ogl-3.1'
libtulip-ogl-3.1:            Mach-O dynamically linked shared library i386             ASCII English text
libtulip-pluginsmanager:     symbolic link to `libtulip-pluginsmanager-3.1'
libtulip-pluginsmanager-3.1: Mach-O dynamically linked shared library i386  ASCII English text, with very long lines
libtulip-qt4:                symbolic link to `libtulip-qt4-3.1'
libtulip-qt4-3.1:            Mach-O dynamically linked shared library i386             ASCII English text, with very long lines                 ASCII English text
tlp:                         directory

Files that have “Mach-O dynamically linked shared library i386” as their description are surely interesting. Why don’t they have a .dylib extension? You can find a similar “phenomenon” inside the tlp directory which contains Tulip plugins. Where is the extension gone?

Since Tulip checks for .dylib extension on MacOS X, it would not be able to load the plugins. Because they are simply not there. No files with that extension. The application loads very fast since no plugins found. And you also can’t do much since Tulip is (probably) nothing without plugins.

I don’t know why the configuration scripts or the compiler or the linker or whatever it is don’t create shared libraries with .dylib extension. But as a workaround, I found a simple solution to make Tulip recognize the libraries. Just by simply adding the extension!

One simple command and all is done.

$ ls *-3.1 *-3.1.0 | while read file; do ln -s $file $file.dylib; done

Run that inside the lib, lib/tlp, lib/tlp/glyph, and lib/tlp/view directories. Maybe inside lib/tlp/designer too. Don’t worry when it tells “No such file or directory”.

And.. now you have it.

Compiling OpenSceneGraph on Windows

.. now, I’m using MinGW/MSYS (what’s the difference btw?) instead of Visual Studio. Apparently, those two can’t cope each other and since I’m gonna use Eclipse with MinGW/MSYS, I have to compile the OpenSceneGraph (OSG) with MinGW/MSYS too.

The good news is, OSG uses CMake. It helps a lot when dealing with many build system on many platforms (as long as it supports of course).

  1. First, prepare the ammunition. Download CMake, MinGW/MSYS, OSG, and also OSG’s required 3rdParty libraries. Installing CMake should be straight forward. But maybe not the case for MinGW and MSYS. I already forgot how to install it, so just ask Google for this one =D

  2. Extract the OSG somewhere, for example C:OpenSceneGraph-2.6.1OpenSceneGraph-2.6.1. I have it extracted there already, so I just use it. Also don’t forget to extract the 3rdParty bundle into C:OpenSceneGraph-2.6.13rdParty.

  3. Open CMake, point the source code directory to that directory, and also set the build directory if you don’t want to mess the source directory like me.

  4. Click the configure button and select MSYS Makefiles for the generator.

  5. CMake will then do the initial configuration. Adjust some configurations to fit your needs, such as CMAKE_INSTALL_PREFIX if you want to change the OSG installation directory.

    In my case, I also have to turn off the BUILD_OSG_PLUGINS option because it needs some other libraries which I don’t know. Since I just want to get the OSG compiled, it is easier for me to turn this one off rather than finding the libraries.

  6. Click the configure button again.. and maybe again.. until the OK button can get clicked.

  7. Finish the CMake by clicking the OK button. It will generate the requested build system.

  8. Open the MSYS console. Go to the OSG build directory and let the two left “magic commands” do their job. The “configure” part is already done by CMake.

    $ make

    and finally..

    $ make install
  9. Let your fingers crossed, grab some tea or coffee, and wait until the compilation ends (hopefully).

Then.. let the coding continues.. =)

Find the source code at