<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>experimentalworks</title>
	<atom:link href="http://blog.experimentalworks.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.experimentalworks.net</link>
	<description></description>
	<lastBuildDate>Wed, 05 Dec 2012 00:22:13 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Probing PHP with Systemtap on Linux</title>
		<link>http://blog.experimentalworks.net/2012/12/probing-php-with-systemtap-on-linux/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=probing-php-with-systemtap-on-linux</link>
		<comments>http://blog.experimentalworks.net/2012/12/probing-php-with-systemtap-on-linux/#comments</comments>
		<pubDate>Wed, 05 Dec 2012 00:12:39 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=593</guid>
		<description><![CDATA[DTrace is a dynamic tracing tool build by Sun Microsystems and is available for Solaris, MacOS and FreeBSD. It features a tracing language which can be used to probe certain &#8220;probing&#8221; points in kernel or userland. This can be very useful to gather statistics, etc. Linux comes with a separate solution called systemtap. It also [...]]]></description>
			<content:encoded><![CDATA[<section>
<a href="http://docs.oracle.com/cd/E19253-01/817-6223/index.html">DTrace</a> is a dynamic tracing tool build by Sun Microsystems and is available for Solaris, MacOS and FreeBSD. It features a tracing language which can be used to probe certain &#8220;probing&#8221; points in kernel or userland. This can be very useful to gather statistics, etc. Linux comes with a separate solution called <a href="http://sourceware.org/systemtap/">systemtap</a>. It also features a tracing language and can probe both userland and kernel space. A few Linux distributions such as <a href="https://fedoraproject.org">Fedora</a> enable systemtap in their default kernel.</p>
<p>PHP introduced DTrace support with PHP 5.3, enabling probing points in the PHP executable that can be used to simplify probing of PHP applications without having to the PHP implementation details. We enabled probes on function calls, file compilation, exceptions and errors. But this has always been limited to the operating systems that support DTrace. With the popularity of DTrace, Systemap programmers decided to add a DTrace compatibility layer that allows to use DTrace probes as Systemtap probing points as well.</p>
<p>With my recent commit to the PHP 5.5 branch, we allow DTrace probes to be build on Linux, so people can use Systemtap to probe those userland probes.<br />
</section>
<section>
To compile PHP with userland probes you need to obtain the PHP 5.5 from git:</p>
<pre>
$ git clone git://github.com/php/php-src php-src
$ cd php-src
$ git checkout PHP-5.5
</pre>
</section>
<section>
Now build PHP with DTrace support. First we have to rebuild configure as we build directly from the repository. Make sure your Linux distribution comes with systemtap and uprobes support.</p>
<pre>
$ ./buildconf --force
$ ./configure --disable-all --enable-dtrace
$ make
</pre>
</section>
<section>
After being done with building we can see if we found any probes:</p>
<pre>
$ stap -l 'process.provider("php").mark("*")' -c 'sapi/cli/php -i'
process("sapi/cli/php").provider("php").mark("compile__file__entry")
process("sapi/cli/php").provider("php").mark("compile__file__return")
process("sapi/cli/php").provider("php").mark("error")
process("sapi/cli/php").provider("php").mark("exception__caught")
process("sapi/cli/php").provider("php").mark("exception__thrown")
process("sapi/cli/php").provider("php").mark("execute__entry")
process("sapi/cli/php").provider("php").mark("execute__return")
process("sapi/cli/php").provider("php").mark("function__entry")
process("sapi/cli/php").provider("php").mark("function__return")
process("sapi/cli/php").provider("php").mark("request__shutdown")
process("sapi/cli/php").provider("php").mark("request__startup")
</pre>
</section>
<section>
Let&#8217;s build us a short Systemtap script that counts the function calls of a specific function. we use the function-return and function-entry probes for that:</p>
<pre>
$ cat request.stp
global callcount;
probe process.provider("php").mark("function-entry") {
    callcount[user_string($arg1)] += 1;
}
probe end {
    printf("count : function\n");
    foreach (name in callcount) {
        printf("%5d : %s\n", callcount[name], name);
    }
}
</pre>
<pre>
$ sudo stap -c 'sapi/cli/php test.php' request.stp
count : function
  100 : foo
  101 : bar
</pre>
</section>
<p>So that&#8217;s all. You can use systemtap now to probe your PHP. Hope you come up with some useful scripts. Share them!</p>
 <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=593&amp;md5=2f59bcf4d604749fcce16c2ab1884e81" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2012/12/probing-php-with-systemtap-on-linux/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=dsp&amp;popout=1&amp;url=http%3A%2F%2Fblog.experimentalworks.net%2F2012%2F12%2Fprobing-php-with-systemtap-on-linux%2F&amp;language=en_GB&amp;category=text&amp;title=Probing+PHP+with+Systemtap+on+Linux&amp;description=DTrace+is+a+dynamic+tracing+tool+build+by+Sun+Microsystems+and+is+available+for+Solaris%2C+MacOS+and+FreeBSD.+It+features+a+tracing+language+which+can+be+used+to+probe+certain...&amp;tags=blog" type="text/html" />
	</item>
		<item>
		<title>Bookmarks Revisited Part II: Daily Bookmarking</title>
		<link>http://blog.experimentalworks.net/2012/10/bookmarks-revisited-part-ii-daily-bookmarking/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=bookmarks-revisited-part-ii-daily-bookmarking</link>
		<comments>http://blog.experimentalworks.net/2012/10/bookmarks-revisited-part-ii-daily-bookmarking/#comments</comments>
		<pubDate>Tue, 02 Oct 2012 01:59:17 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=578</guid>
		<description><![CDATA[Over the last years, Mercurial bookmarks have changed and became a mature core feature. We go into detail about the current way bookmarks work and how to use them for daily work.]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a long time since I&#8217;ve written part I of the <a href="http://blog.experimentalworks.net/2010/06/mercurial-bookmarks-revisited-part-i/">bookmarks revisited series</a>. In the last two years, bookmarks changed a lot. They became part <a href="http://mercurial.selenic.com">Mercurial&#8217;s</a> core functionality and a lot of of tools became bookmark aware.</p>
<h4>The current state of bookmarks</h4>
<section>
As of Mercurial 1.8 bookmarks are part of the Mercurials core. You don&#8217;t have to activate the extension anymore. Bookmarks are supported by every major <a href="http://bitbucket.org">Mercurial hosting platform</a>. Commands like <span class="code">hg summary</span> or <span class="code">hd id</span> will display bookmark information. In addition, the push and pull mechanism changed. I will go into details about his Part III of the series.</p>
<p>
It&#8217;s safe to say, due to it&#8217;s exposure, bookmarks became much more mature of the years. It&#8217;s time to take a look at how to use them.
</p>
</section>
<h4>Bookmark semantics</h4>
<section>
Bookmarks are pointers to commits. Think of it as a name for a specific commit. Unlike branches in Mercurial, bookmarks are not recorded in the changeset. They don&#8217;t have a history. If you delete them, they will be gone forever.</p>
<p>
Bookmarks were initially designed for short living branches. I use them as such. It&#8217;s indeed possible to use them in different contexts, but I don&#8217;t do that. Please be aware, although they were initially intended to be similar to git branches, they often aren&#8217;t. They are not branches, they are bookmarks and they should be used like you would use a bookmark in a book. If you advance to the next site, you move the bookmark (or it gets moved).
</p>
<p>
A bookmark can be active. Only one bookmark can be active at any time, but it&#8217;s okay that no bookmark is active. If you have an active bookmark and you commit a new changeset, the bookmark will be moved to the commit. To set a bookmark active you have to update to the bookmark with <span class="code">hg update &lt;name&gt;</span>. To unset, just update to the current revision with <span class="code">hg update .</span>.
</p>
<p>
A bookmark can have a <em>diverged</em> markers. Bookmarks that are diverged will have a @NAME suffix. For example <em>test@default</em>. Diverged bookmarks are created during push and pull and will be described in Part III.
</p>
</section>
<p><span id="more-578"></span></p>
<h4>A start</h4>
<section>
I use bookmarks to keep track of short living heads that I use for feature development. One bookmark keeps track of the upstream repository, they rest are my personal markers. Let&#8217;s start with creating the initial marker that keeps track of upstream. In this example, I show how I work on Mercurial.</p>
<p>
First, we are going to clone the Mercurial repository.</p>
<pre>
$ hg clone http://selenic.com/hg hg
destination directory: hg
requesting all changes
adding changesets
adding manifests
adding file changes
added 17684 changesets with 34643 changes to 2168 files
updating to branch default
996 files updated, 0 files merged, 0 files removed, 0 files unresolved
</pre>
</p>
<p>
The repository is setup to the current tip of the repository. We mark it with the &#8216;upstream&#8217; bookmark. The star in front of the bookmark shows that it is marked as the current bookmark. Most Mercurial commands try to not be very verbose and only write necessary information to your terminal. It&#8217;s okay that creating a new bookmark doesn&#8217;t generate any output.</p>
<pre>
$ hg bookmark upstream
$ hg bookmark
 * upstream                  17683:6d7db5794e8c
</pre>
</p>
<p>
To start out with a new feature, we have to make sure to not accidentally advance the master bookmark if we start to commit now. Either deactivate the current bookmark using <span class="code">hg update .</span> or create the new bookmark for the feature we want to use right away. I am going to work on a feature to warn people if they create a bookmark with an ambiguous name. Therefore I call the branch <em>topic/bm-warn-ambiguous</em>.</p>
<pre>
$ hg bookmark topic/bm-warn-ambiguous
$ hg bookmark
 * topic/bm-warn-ambiguous   17683:6d7db5794e8c
   upstream                  17683:6d7db5794e8c
</pre>
</p>
<p>
We can now go ahead and write our feature. I start out with the initial bits and later use the MQ extension to modify the changeset, so my change evolves slowly. After hacking a few minutes on the initial code, we can go ahead and commit it. As topic/bm-warn-ambiguous is marked as the current bookmark it will be moved automatically during commit.</p>
<pre>
$ vim mercurial/bookmarks.py
$ hg commit -m'bookmarks: warn if bookmark name is ambiguous'
$ hg bookmark
 * topic/bm-warn-ambiguous   17684:d018b3fda542
   upstream                  17683:6d7db5794e8c
</pre>
</p>
</section>
<h4>Using existing bookmarks</h4>
<section>
We can use the existing bookmarks and go back to our initial state what we pulled from the main repository. Just use bookmark the same way you use revisions. You can use it together with any command that requires a revision argument.</p>
<p><pre>
$ hg update upstream
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg bookmark
   topic/bm-warn-ambiguous   17684:d018b3fda542
 * upstream                  17683:6d7db5794e8c
$ hg log -r upstream
changeset:   17683:6d7db5794e8c
bookmark:    upstream
parent:      17681:a41fd730f230
parent:      17682:829919ef894a
user:        Matt Mackall <mpm @selenic.com>
date:        Sat Sep 29 12:28:52 2012 -0500
summary:     merge with stable
</mpm></pre>
</p>
<p>
I am not too happy with the name of the bookmark. topic/ seems a way to long prefix. Let&#8217;s shorten it and rename the existing bookmark. The <span class="code">hg bookmark -m oldname newname</span> can be used to rename existing bookmarks (-m as in move).</p>
<pre>
$ hg bookmark -m  topic/bm-warn-ambiguous t/warn-ambiguous
$ hg bookmark
   t/warn-ambiguous          17684:d018b3fda542
 * upstream                  17683:6d7db5794e8c
</pre>
</p>
<p>
Bookmarks can be deleted with <span class="code">hg bookmark -d name</span></p>
<pre>
$ hg bookmark -d t/warn-ambiguous
$ hg bookmark
 * upstream                  17683:6d7db5794e8c
$ hg bookmark -r 17684 t/warn-ambiguous
$ hg bookmark
   t/warn-ambiguous          17684:d018b3fda542
 * upstream                  17683:6d7db5794e8c
</pre>
</p>
</section>
<h4>Merging</h4>
<section>
Suppose we are done with our nice little feature and want to move it into our main development branch which is tracked by <em>upstream</em>. There are a few behaviors that you might be unfamiliar with. Just go ahead and use <span class="code">hg merge bookmark</span>. Obviously, the bookmark cannot be a descendant of the bookmark to merge. Unlike git there is no way to force the merge. Also Mercurial won&#8217;t update the bookmark. It will just abort and stay were you are. (For git users: This means, Mercurial doesn&#8217;t have the notion of a <em>fast-forward</em> for bookmarks). I am not super happy with this behavior, but it will stay for the moment.</p>
<p>
If you have diverged heads and your merge is successful, you can commit the merge. The current bookmark is updated to the new merge commit. The bookmark that was merged stays and doesn&#8217;t move. Mercurial always sticks to the rule that only the current bookmark moves.</p>
<pre>
$ hg bookmark
  t/warn-ambiguous          17684:d018b3fda542
* upstream                  17685:861d6aeee6aa
$ hg merge t/warn-ambiguous
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg commit -m'Merge'
$ hg bookmark
   t/warn-ambiguous          17684:d018b3fda542
 * upstream                  17686:c6b62c2e15fc
</pre>
</p>
</section>
<h4>Bookmarks and revsets</h4>
<section>
Revset is a query language for revisions and files, build into mercurial. <span class="code">hg help revsets</span> will explain the syntax. It&#8217;s a very powerful language. If you have the time, learn it. It makes your Mercurial experience that much better and will probably make you complain about endless lines of command line options in other VCS.</p>
<p>
The revset language has support for bookmarks. You can use the <span class="code">bookmarks()</span> function to get a set of all revisions that are bookmarked. Use this in combination with the log command to get a detailed list of all bookmarked commits:</p>
<pre>
$ hg log -r 'bookmark()'
changeset:   17683:6d7db5794e8c
bookmark:    upstream
parent:      17681:a41fd730f230
parent:      17682:829919ef894a
user:        Matt Mackall <mpm @selenic.com>
date:        Sat Sep 29 12:28:52 2012 -0500
summary:     merge with stable

changeset:   17684:d018b3fda542
bookmark:    t/warn-ambiguous
tag:         tip
user:        David Soria Parra <dsp @php.net>
date:        Tue Oct 02 03:07:05 2012 +0200
summary:     bookmarks: warn if bookmake name is ambiguous
</dsp></mpm></pre>
</p>
<p>
More complex queries can be done. If you work with bookmarks on different Mercurial branches you can get a list of all bookmarks of a certain branch with <span class="code">hg log -r &#8216;branch(stable) and bookmark()&#8217;</span>. Have fun playing around. Rewards and cat gifs for posting awesome revset queries the comments.
</p>
</section>
<h4>MQ and bookmarks</h4>
<section>
So far we have dealt with basic commands. We committed a changeset, we edited a few bookmarks.</p>
<p>
Bookmarks were designed to work on short living heads. The usual way to work with slowly evolving, unfinished changesets in Mercurial is MQ (also look at Mercurial <a href="http://www.selenic.com/hg/help/phases">phases</a>, a new mechanism to help you with published and drafted commits).
</p>
<p>
MQ is a stack of queues on top of a Mercurial repository. It&#8217;s tightly integrated into Mercurial and uses commits and strip commands to push and pop changes. In my example, I have to continue working on my warn-ambiguous feature. We start by importing the topmost commit into MQ to change the commit. We then edit a new file and use <span class="code">hg qrefresh</span> to update the commit with the new changes.
</p>
<p><strong>WARNING: qrefresh will throw away your current bookmark before Mercurial 2.4</strong> (which is not yet released).</p>
<pre>
$ hg update t/warn-ambiguous
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg qimport -r tip
$ hg bookmark
 * t/warn-ambiguous          17684:d018b3fda542
   upstream                  17683:6d7db5794e8c
$ vim mercurial/bookmarks
$ hg qrefresh
$ hg bookmark
 * t/warn-ambiguous          17684:a5bbed225a3f
   upstream                  17683:6d7db5794e8c
</pre>
<p>
If we want to create a new commit, we use the command <span class="code">hg qnew name</span>. It will create a new patch on top of the patch stack. We use it to draft the tests for our new commit. If we want to go back to the previous commit that is still on the stack, we use <span class="code">hg qpop</span> to &#8220;pop&#8221; the topmost patch (the one with the tests) from the stack. If we want to go back we use <span class="code">hg qpush</span>.
</p>
<p>Note that the bookmarks will move back if you qpop and forward if you qpush, following your current state on the stack. Instead of hg commit we have to use <span class="code">hg qrefresh</span> (only on of mq&#8217;s oddities).</p>
<pre>
$ hg qnew tests
$ vim tests/test-bookmarks.t
$ hg qrefresh
</pre>
<p>
So most parts of MQ are aware of bookmarks. If finalize the MQ patches with <span class="code">hg qfinish -a</span> our bookmark will just stay. The main issue with that workflow is the lack of support in qrefresh, but this is hopefully going to change with the next release. With that, bookmarks are going to be super useful for developing short living branches.
</p>
</section>
<h4>Naming conventions and alias</h4>
<section>
It is useful to have some naming conventions for bookmarks. I personally use the prefix <em>t/&lt;name&gt;</em> to denote short living topic branches. I use <em>release/&lt;version&gt;</em> for release branches. Bookmarks without any prefix are used for upstream bookmarks and bookmarks that were automatically pulled from the remote repository.</p>
<p>
If you use bookmarks daily, you might want to use setup an alias in your global .hgrc. Just add the entry</p>
<pre>
[alias]
bm = bookmark
</pre>
<p>to your <span class="code">~/.hgrc</span> and test if it works with <span class="code">hg bm</span>.
</p>
</section>
<h4>Conclusion</h4>
<p>Bookmarks changed a lot of the last years and most of Mercurials code base is bookmark aware. With the change to qrefresh, it&#8217;s going to be good enough for my workflows. Whats your bookmark story? Also Steve Losh wrote an excellent article about the <a href="http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/">different ways of branching in Mercurial</a> (it has pictures, wwoooo). He also wrote an excellent article about <a href="http://stevelosh.com/blog/2010/08/a-git-users-guide-to-mercurial-queues/">MQ</a>. He wrote a lot of interesting stuff at all, visit his page.</p>
<p>ps: without flattrs, comments or anything like that, there is probably not going to be a part III</p>
 <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=578&amp;md5=05ad4ff58421e20049d9342926cefc1f" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2012/10/bookmarks-revisited-part-ii-daily-bookmarking/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=dsp&amp;popout=1&amp;url=http%3A%2F%2Fblog.experimentalworks.net%2F2012%2F10%2Fbookmarks-revisited-part-ii-daily-bookmarking%2F&amp;language=en_GB&amp;category=text&amp;title=Bookmarks+Revisited+Part+II%3A+Daily+Bookmarking&amp;description=It%26%238217%3Bs+been+a+long+time+since+I%26%238217%3Bve+written+part+I+of+the+bookmarks+revisited+series.+In+the+last+two+years%2C+bookmarks+changed+a+lot.+They+became+part+Mercurial%26%238217%3Bs+core+functionality...&amp;tags=blog" type="text/html" />
	</item>
		<item>
		<title>I should&#8230;</title>
		<link>http://blog.experimentalworks.net/2012/10/i-should/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=i-should</link>
		<comments>http://blog.experimentalworks.net/2012/10/i-should/#comments</comments>
		<pubDate>Mon, 01 Oct 2012 20:04:13 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=575</guid>
		<description><![CDATA[blog more. Open topics: DTrace Part II, Mercurial Bookmarks Part II.]]></description>
			<content:encoded><![CDATA[<p>blog more. Open topics: DTrace Part II, Mercurial Bookmarks Part II.</p>
 <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=575&amp;md5=22fb25678642cf7dfe20389aabf9b4be" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2012/10/i-should/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=dsp&amp;popout=1&amp;url=http%3A%2F%2Fblog.experimentalworks.net%2F2012%2F10%2Fi-should%2F&amp;language=en_GB&amp;category=text&amp;title=I+should%26%238230%3B&amp;description=blog+more.+Open+topics%3A+DTrace+Part+II%2C+Mercurial+Bookmarks+Part+II.&amp;tags=blog" type="text/html" />
	</item>
		<item>
		<title>Language runtimes and backwards compatbility (or why you shouldn&#8217;t write a version control system in Python)</title>
		<link>http://blog.experimentalworks.net/2012/06/language-runtimes-and-backwards-compatbility-or-why-you-shouldnt-write-a-version-control-system-in-python/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=language-runtimes-and-backwards-compatbility-or-why-you-shouldnt-write-a-version-control-system-in-python</link>
		<comments>http://blog.experimentalworks.net/2012/06/language-runtimes-and-backwards-compatbility-or-why-you-shouldnt-write-a-version-control-system-in-python/#comments</comments>
		<pubDate>Mon, 04 Jun 2012 11:02:46 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=546</guid>
		<description><![CDATA[Software projects choose languages based on idioms of the languages. Languages can provide mechanisms and structures to support object orientation or functional programming. Less time is spent thinking about backwards compatibility of programming language runtimes. While this is usually a non-issue for short living software like websites or software in tightly controlled environment, it becomes [...]]]></description>
			<content:encoded><![CDATA[<p><i>Software projects choose languages based on idioms of the languages. Languages can provide mechanisms and structures to support object orientation or functional programming. Less time is spent thinking about backwards compatibility of programming language runtimes. While this is usually a non-issue for short living software like websites or software in tightly controlled environment, it becomes an issue for software projects that need to guarantee backwards-compatibility for years. For example: a version control system.</i></p>
<p>The Mercurial project aims to support Python 2.4 to Python 2.7. It does not support Python 3. Why? Python 3 is a drastic change. Unicode is the default string type, classes removed, etc. The impact of the changes are similar to the change from PHP 4 to PHP 5. Most software projects have adopted these language changes, but for projects that need to support LTS operating systems like RHEL or Solaris 9/10, it can be become an issue. You could drop Python 2.X support and tell existing users of your software to look for something else &#8211; a no-go for a version control system.  You could simply not support Python 3 at someday, but Python 2.7 already reached it&#8217;s EOL. It&#8217;s just a matter time until distribution stop shipping Python 2.X. LTS operating systems might still not have Python 3 and rely on Python 2. Writing software that needs to be backwards-compatbile for 8 years can be a problem.</p>
<p><strong>The source of the problem</strong></p>
<p>Why is this a not an issue for Java or C, but for Python, PHP and Ruby?  Java and C compile to bytecode that is guaranteed to be stable. C compiles to machinecode. A processor architecture won&#8217;t change anymore. If it&#8217;s a x86 processor, it will support x86 machinecode. It won&#8217;t change with the next software update.  If your code needs to support old C code that modern compilers don&#8217;t understand anymore, use an old one. Java is similar in that regard. The JVM runtime has a defined set of instructions, which won&#8217;t be changed anymore. It doesnt matter which Java compiler you use, in the end it will produce bytecode that will run on any JVM.  Sure you still might have problems supporting multiple versions of a library, but at least the JVM will always run your compiled code.</p>
<p>Python and PHP compile to bytecode as well, similar Java. There is, however, one exception: They do it in memory and the VM to interprete the bytecode is bundled with the compiler. This is were the backwards compatibility problem comes in play. You cannot run Python bytecode compiled on Python 3 with a Python 2 interpreter. You cannot compile with PHP 5 and run it on PHP 4.  Either the interpreter simply fails to your old code, or your VM implementation is not guaranteed to be stable. That means in Python and PHP the underlying machine that you compile might change with the next update. Let&#8217;s compare this to the x86 world. Your next software update might change the x86 instruction set? You would have to recompile all your C code and maybe some of the old C code cannot be compiled with modern C compilers and old C compilers might not be able to get compiled on the new instruction set. Sounds painful, particularly if you really care about backwards-compatibility.</p>
<p><strong>Sidenote</strong></p>
<p>I think that Python, PHP and others did an architectual mistake. They bundled the VM and runtime with the compiler. Thus your language version defines your runtime and the underlying machinecode.  If you write a new language, write down a minimum instruction set that you will always support and separate your VM from your compiler. Always support that instruction set. This can lead to interesting problems. The implementation of Java Generics is a good example. Nobody thought about generics when defining the insturctions set. Therefore the bytecode was not designed to retain information about the generic type. Thats why the Java compiler needs to check the generic type information and than transform it, so that the resulting bytecode is compatible with old JVM versions.  This is known as type erasure.  Python and PHP developer would probably just introduce new bytecodes, not caring about BC. (Well PHP devs would just pretend that PHP is a web language and web projects shouldn&#8217;t care about BC at all ;)).</p>
<p><strong>Conclusion</strong><br />
If you seriously care about backward-compatibility for LTS systems that are 8 years old, choose a language which separates the VM from the compiler. Languages like Java (probably C#) do this. Java developer won&#8217;t define behavior that requires a new opcode. PHP and Python are wonderful programming languages, but personally I am not sure if it is wise to write something like a VCS in such a language.  </p>
<p><em>Long story short: Language choice matters for BC. If you write your own language, please separate your VM from your compiler. Better (as johannes pointed out) compile to an existing VM like JVM, CLR or LLVM</em></p>
 <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=546&amp;md5=7b09221ab9dfad011298dd62dd17a6ea" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2012/06/language-runtimes-and-backwards-compatbility-or-why-you-shouldnt-write-a-version-control-system-in-python/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=dsp&amp;popout=1&amp;url=http%3A%2F%2Fblog.experimentalworks.net%2F2012%2F06%2Flanguage-runtimes-and-backwards-compatbility-or-why-you-shouldnt-write-a-version-control-system-in-python%2F&amp;language=en_GB&amp;category=text&amp;title=Language+runtimes+and+backwards+compatbility+%28or+why+you+shouldn%26%238217%3Bt+write+a+version+control+system+in+Python%29&amp;description=Software+projects+choose+languages+based+on+idioms+of+the+languages.+Languages+can+provide+mechanisms+and+structures+to+support+object+orientation+or+functional+programming.+Less+time+is+spent+thinking+about+backwards...&amp;tags=blog" type="text/html" />
	</item>
		<item>
		<title>Xorg: Different options for different keyboards</title>
		<link>http://blog.experimentalworks.net/2012/05/xorg-different-options-for-different-keyboards/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=xorg-different-options-for-different-keyboards</link>
		<comments>http://blog.experimentalworks.net/2012/05/xorg-different-options-for-different-keyboards/#comments</comments>
		<pubDate>Thu, 24 May 2012 07:32:14 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=539</guid>
		<description><![CDATA[So I have this esoteric problem that I have 2 totally different keyboards. The Happy Hacking Pro 2 (HHK) and the Realforce 103U. The happy hacking has a special, SUN inspired layout with the control key where standard keyboards usually have their caps. My Realforce 103U has a standard US layout. I am big fan [...]]]></description>
			<content:encoded><![CDATA[<p>So I have this esoteric problem that I have 2 totally different keyboards. The <a href="http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard">Happy Hacking Pro 2</a> (HHK) and the <a href="http://elitekeyboards.com/products.php?sub=topre_keyboards,realforce&#038;pid=rf_se0200">Realforce 103U</a>. The happy hacking has a special, SUN inspired layout with the control key where standard keyboards usually have their caps. My Realforce 103U has a standard US layout. I am big fan of the old SUN layout and cannot type on keyboards that have the CTRL key on the usual position.</p>
<p><strong>The problem:</strong> If I plug in my Realforce, I want to have the CAPS remapped to CTRL. If I plug in my Happy Hacking, it should stay the way it is!<br />
<strong>Solution:</strong> Xorg Udev Matching</p>
<p>So in recent Xorg versions you can use udev matchings to select the options for a particular keyboard. On my Fedora 16, I added the following file:</p>
<pre>
$ vim /etc/xorg.conf.d/01-realforce.conf
Section "InputClass"                                                                                             
  Identifier	"Realforce"                                          
  MatchProduct 	"Realforce 103U"
  Option	"XkbLayout"	"us,de"                                              
  Option	"XkbOptions"	"grp:menu_toggle,ctrl:swapcaps"
EndSection
</pre>
<p>Done. If I plug in my Realforce I have the ctrl and caps key swapped!</p>
<p>Bonus: As the win key on my HHK is right of the alt key I better switch ALT and WIN on my Realforce, too:</p>
<pre>
Option "XkbOptions" "grp:menu_toggle,ctrl:swapcaps,altwin:swap_lalt_lwin"
</pre>
 <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=539&amp;md5=6859ee17ea66fc47216dad5488c2c8e0" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2012/05/xorg-different-options-for-different-keyboards/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=dsp&amp;popout=1&amp;url=http%3A%2F%2Fblog.experimentalworks.net%2F2012%2F05%2Fxorg-different-options-for-different-keyboards%2F&amp;language=en_GB&amp;category=text&amp;title=Xorg%3A+Different+options+for+different+keyboards&amp;description=So+I+have+this+esoteric+problem+that+I+have+2+totally+different+keyboards.+The+Happy+Hacking+Pro+2+%28HHK%29+and+the+Realforce+103U.+The+happy+hacking+has+a+special%2C+SUN...&amp;tags=blog" type="text/html" />
	</item>
		<item>
		<title>Canonical Way to Build PHP 5.4 on Solaris 11</title>
		<link>http://blog.experimentalworks.net/2012/05/canonical-way-to-build-php-5-4-on-solaris-11/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=canonical-way-to-build-php-5-4-on-solaris-11</link>
		<comments>http://blog.experimentalworks.net/2012/05/canonical-way-to-build-php-5-4-on-solaris-11/#comments</comments>
		<pubDate>Tue, 15 May 2012 15:09:40 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[solaris php]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=529</guid>
		<description><![CDATA[You need gnu-coreutils installed. $ wget -O php.tar.bz2 http://us.php.net/get/php-5.4.3.tar.bz2/from/this/mirror $ tar xvjf php.tar.bz2 $ cd php-5.4.3 $ ./configure \ --with-apxs2=/usr/apache2/2.2/bin/apxs \ --prefix=/usr/php/5.4 \ [other options] $ gsed -ibak 's,\-mt,,' Makefile $ gsed -i.bak 's,\-i \-a \-n php5 libphp5\.la,-i -n php5 libphp5.la,' Makefile $ make -j4 $ sudo make install $ vim /etc/apache2/2.2/conf.d/php5.2.conf ..change stuff to [...]]]></description>
			<content:encoded><![CDATA[<p><code><br />
You need gnu-coreutils installed.<br />
$ wget -O php.tar.bz2 http://us.php.net/get/php-5.4.3.tar.bz2/from/this/mirror<br />
$ tar xvjf php.tar.bz2<br />
$ cd php-5.4.3<br />
$ ./configure \<br />
      --with-apxs2=/usr/apache2/2.2/bin/apxs \<br />
      --prefix=/usr/php/5.4 \<br />
      [other options]<br />
$ gsed -ibak 's,\-mt,,' Makefile<br />
$ gsed -i.bak 's,\-i \-a \-n php5 libphp5\.la,-i -n php5 libphp5.la,' Makefile<br />
$ make -j4<br />
$ sudo make install<br />
$ vim /etc/apache2/2.2/conf.d/php5.2.conf<br />
..change stuff to libphp5.la..<br />
$ svcadm restart apache22<br />
</code><br />
Worked for me so far.</p>
 <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=529&amp;md5=5a33d35ecb7ce817bfc8aedc3475f232" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2012/05/canonical-way-to-build-php-5-4-on-solaris-11/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=dsp&amp;popout=1&amp;url=http%3A%2F%2Fblog.experimentalworks.net%2F2012%2F05%2Fcanonical-way-to-build-php-5-4-on-solaris-11%2F&amp;language=en_GB&amp;category=text&amp;title=Canonical+Way+to+Build+PHP+5.4+on+Solaris+11&amp;description=You+need+gnu-coreutils+installed.+%24+wget+-O+php.tar.bz2+http%3A%2F%2Fus.php.net%2Fget%2Fphp-5.4.3.tar.bz2%2Ffrom%2Fthis%2Fmirror+%24+tar+xvjf+php.tar.bz2+%24+cd+php-5.4.3+%24+.%2Fconfigure+%5C+--with-apxs2%3D%2Fusr%2Fapache2%2F2.2%2Fbin%2Fapxs+%5C+--prefix%3D%2Fusr%2Fphp%2F5.4+%5C+%5Bother+options%5D+%24+gsed+-ibak+%27s%2C%5C-mt%2C%2C%27+Makefile...&amp;tags=solaris+php%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Removing a directory from a git repository the fast way</title>
		<link>http://blog.experimentalworks.net/2012/01/removing-a-directory-from-a-git-repository-the-fast-way/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=removing-a-directory-from-a-git-repository-the-fast-way</link>
		<comments>http://blog.experimentalworks.net/2012/01/removing-a-directory-from-a-git-repository-the-fast-way/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 14:58:46 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=526</guid>
		<description><![CDATA[Note to myself: To remove a directory from an existing git repository there are various ways to do it. The obvious way is $ git filter-branch --tree-filter 'rm -rf directory/' Which is just fine for smaller repositories but can take a long time on large repositories with a lot of large files in that directory. [...]]]></description>
			<content:encoded><![CDATA[<p>Note to myself:<br />
To remove a directory from an existing git repository there are various ways to do it. The obvious way is<br />
<code><br />
$ git filter-branch --tree-filter 'rm -rf directory/'<br />
</code></p>
<p>Which is just fine for smaller repositories but can take a long time on large repositories with a lot of large files in that directory.<br />
The faster way is to manipulate only the index:<br />
<code><br />
git filter-branch --index-filter 'git ls-files -- DIRECTORY | xargs git update-index --remove' --tag-name-filter cat --prune-empty -f -- --all;<br />
</code></p>
<ul>
<li><em>git ls-files</em> will give you a list of files in the DIRECTORY</li>
<li><em>git update-index</em> will remove those files from the index</li>
<li>And the tag filter is there to include tags</li>
<li>&#8211;prune-empty tells filter-branch to ignore empty commits.</li>
</ul>
<p>Done.</p>
 <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=526&amp;md5=a2b84e5105562290b6f6eb0268a0fa8a" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2012/01/removing-a-directory-from-a-git-repository-the-fast-way/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=dsp&amp;popout=1&amp;url=http%3A%2F%2Fblog.experimentalworks.net%2F2012%2F01%2Fremoving-a-directory-from-a-git-repository-the-fast-way%2F&amp;language=en_GB&amp;category=text&amp;title=Removing+a+directory+from+a+git+repository+the+fast+way&amp;description=Note+to+myself%3A+To+remove+a+directory+from+an+existing+git+repository+there+are+various+ways+to+do+it.+The+obvious+way+is+%24+git+filter-branch+--tree-filter+%27rm+-rf+directory%2F%27...&amp;tags=blog" type="text/html" />
	</item>
		<item>
		<title>Random thoughts about contributions</title>
		<link>http://blog.experimentalworks.net/2011/09/random-thoughts-about-contributions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=random-thoughts-about-contributions</link>
		<comments>http://blog.experimentalworks.net/2011/09/random-thoughts-about-contributions/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 13:50:15 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[community]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=520</guid>
		<description><![CDATA[The PHP community announced that they will be switching to Git. This lead to some discussion on Twitter, wether it is good to go directly to Github or use git.php.net as the gateway to ensure control over ACLs. People were argueing that github encourages people to contribute and that the PHP community is stuck in [...]]]></description>
			<content:encoded><![CDATA[<p>The PHP community announced that they will be switching to Git. This lead to some discussion on Twitter, wether it is good to go directly to Github or use git.php.net as the gateway to ensure control over ACLs. People were argueing that github encourages people to contribute and that the PHP community is stuck in the 90s if they don&#8217;t switch completly over to Git.</p>
<p>So my 2 cents:</p>
<p>What really makes people contribute:</p>
<ol>
<li>A nice and encouraging community</li>
<li>Respect the work of others</li>
<li>Don&#8217;t take everything for granted</li>
</ol>
<p>What doesn&#8217;t encourage people:</p>
<ol>
<li>Continous rants about how to do things or not</li>
<li>Telling people what they do is totally wrong</li>
<li>Not contribute yourself</li>
</ol>
<p>Open Source Projects are community driven. There is a place for discussion, but note that Open Source Communities are open, so people will come in and start ranting about things. If you are serious about a certain problem and want to solve it, contribute! If you want things to change, contribute! If you want to have your opinion heard, contribute! But do not try to squeeze argumentations in 140 characters and think everyone will follow you, just because it&#8217;s you.</p>
<p>Personally I&#8217;m getting tired of this, making me either not to contribute anymore (and you guys are stuck with SVN :)) or just ignore people.</p>
 <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=520&amp;md5=d03fafe691b218ab6ef24a7b38d4f383" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2011/09/random-thoughts-about-contributions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=dsp&amp;popout=1&amp;url=http%3A%2F%2Fblog.experimentalworks.net%2F2011%2F09%2Frandom-thoughts-about-contributions%2F&amp;language=en_GB&amp;category=text&amp;title=Random+thoughts+about+contributions&amp;description=The+PHP+community+announced+that+they+will+be+switching+to+Git.+This+lead+to+some+discussion+on+Twitter%2C+wether+it+is+good+to+go+directly+to+Github+or+use+git.php.net...&amp;tags=community%2Cblog" type="text/html" />
	</item>
		<item>
		<title>How to run clojure.test in Slime and Swank</title>
		<link>http://blog.experimentalworks.net/2011/01/how-to-run-clojure-test-in-slime-and-swank/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-run-clojure-test-in-slime-and-swank</link>
		<comments>http://blog.experimentalworks.net/2011/01/how-to-run-clojure-test-in-slime-and-swank/#comments</comments>
		<pubDate>Sat, 08 Jan 2011 17:51:20 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[slime]]></category>
		<category><![CDATA[swank]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=492</guid>
		<description><![CDATA[$ lein swank In emacs use M-x slime-connect to connect to swank. user&#62; (use 'clojure.test) nil user&#62; (use :reload 'geocommit.test.services) (run-test 'geocommit.test.services) {:type :summary, :test 3, :pass 9, :fail 0, :error 0}]]></description>
			<content:encoded><![CDATA[<pre>
$ lein swank
</pre>
<pre>
In emacs use M-x slime-connect to connect to swank.
</pre>
<pre>
user&gt; (use 'clojure.test)
nil
user&gt; (use :reload 'geocommit.test.services) (run-test 'geocommit.test.services)
{:type :summary, :test 3, :pass 9, :fail 0, :error 0}
</pre>
 <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=492&amp;md5=e12018c671ff5ee06bffd448c914cba2" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2011/01/how-to-run-clojure-test-in-slime-and-swank/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=dsp&amp;popout=1&amp;url=http%3A%2F%2Fblog.experimentalworks.net%2F2011%2F01%2Fhow-to-run-clojure-test-in-slime-and-swank%2F&amp;language=en_GB&amp;category=text&amp;title=How+to+run+clojure.test+in+Slime+and+Swank&amp;description=%24+lein+swank+In+emacs+use+M-x+slime-connect+to+connect+to+swank.+user%26gt%3B+%28use+%27clojure.test%29+nil+user%26gt%3B+%28use+%3Areload+%27geocommit.test.services%29+%28run-test+%27geocommit.test.services%29+%7B%3Atype+%3Asummary%2C+%3Atest+3%2C+%3Apass+9%2C+%3Afail+0%2C...&amp;tags=clojure%2Cemacs%2Cslime%2Cswank%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Locate your commits or how to use geocommit.</title>
		<link>http://blog.experimentalworks.net/2011/01/locate-your-commits-or-how-to-use-geocommit/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=locate-your-commits-or-how-to-use-geocommit</link>
		<comments>http://blog.experimentalworks.net/2011/01/locate-your-commits-or-how-to-use-geocommit/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 14:48:30 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Entropia]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=478</guid>
		<description><![CDATA[This blog post will show you how to use geocommit in your projects. It shows how to install the Chrome and Firefox extensions to add support for geocommit to github.com and bitbucket.org]]></description>
			<content:encoded><![CDATA[<p>We recently launched <a href="http://geocommit.com">geocommit.com</a>. Geocommit is a service to add geolocation data to your commits. You only need a working WiFi connection. <em>No GPS module is required</em>.</p>
<p>This blogpost gives you an example how to use geocommit and the geocommit.com services. I&#8217;ll show how to use geocommits in your <a href="http://git-scm.org">Git</a> or <a href="http://mercurial.selenic.com">mercurial</a> project. How to make <a href="http://github.com">github</a> and <a href="http://bitbucket.org">bitbucket</a> more beautiful with our Chrome and Firefox extensions and how to get a fancy map of your geocommits.</p>
<h3>What is geocommit</h3>
<p>First of all, geocommit is a text format to attach geolocation data to version control system commits. The geocommit <a href="http://geocommit.com">website</a> has detailed information about the geocommit format.<br />
Second, geocommit is a <em>service</em> to store and analyse your geocommit data. We offer a set of tools and a webservice to make geocommit cool. The Git implementation <em>git geo</em> runs on Mac OS X and Linux. The Mercurial implementation <em>hg-geo</em> runs only under Linux. Mac OS support is under way.</p>
<h3>Git &#038; Geocommit</h3>
<p>To start with geocommit, install <a href="http://github.com/peritus/geocommit">git geo</a>:</p>
<pre>
<b>$ pip install geocommit</b>
</pre>
<p>Go to a project directory and enable geocommit support:</p>
<pre>
$ cd myproject.git
<b>$ git geo setup</b>
geocommit setup
Installing geocommit hook in /home/dsp/awesomeproject/.git/hooks/post-rewrite
Installing geocommit hook in /home/dsp/awesomeproject/.git/hooks/post-merge
Installing geocommit hook in /home/dsp/awesomeproject/.git/hooks/post-commit
</pre>
<p>This will enable geocommit support in your project. If you commit something with git commit, git geo will try to get your current location and add a geocommit. If no WiFi connection is enabled, no geocommit will be created.</p>
<p>Check your geocommits:</p>
<pre>
<b>$ git log --show-notes='geocommit'</b>
commit 5a34e6ebc8cb5c2a394ca26505c1d375095161c4
Merge: 25cf72d 828af6e
Author: David Soria Parra <dsp @php.net>
Date:   Tue Jan 4 14:00:55 2011 +0100

    Merge branch 'master' of https://github.com/jezdez/geocommit

Notes (geocommit):
    geocommit (1.0)
    lat: 48.1211828
    long: 11.4853565
    hacc: 39.0
    src: nmg
</dsp></pre>
<p>Let&#8217;s push our geocommits to github:</p>
<pre>
<b>$ git geo push</b>
</pre>
<p><em>git geo push</em> accepts the same options as git push. It pulls geocommits first, merges them and then pushes geocommits and the given branch to the remote repository.<br />
That&#8217;s everything you need. Easy, isn&#8217;t it? So let&#8217;s see how to enable geocommits on Mercurial and then talk about the Chrome and Firefox extensions.</p>
<hr />
<strong>Deep dive</strong><br />
git geo stores geocommits in git notes. We use the namespace <em>geocommit</em> for that. Git notes have some cool properties. They are metadata and don&#8217;t change the commit hash. Therefore they can be added to a commit at anytime. They are displayed on github and can be deleted without any problem. You also can decide yourself when to push geocommits or not. You can delete already pushed geocommits without breaking the repository or changing any commit sha1. The drawback is that it is hard to deal with git notes from time to time. git notes is a new feature in git and not yet fully supported. We have to write a script to merge git notes as git notes merge is not available before git 1.7.7. </p>
<hr />
<h3>Mercurial &#038; geocommit</h3>
<p>You can add support for geocommits to Mercurial by installing the <a href="http://bitbucket.org/segv/hg-geo">hg-geo</a> extension. Clone the extension and enable it in your hgrc:</p>
<pre>
<b>$ hg clone http://bitbucket.org/segv/hg-geo</b>
$ echo "[extensions]\ngeo=/path/to/hg-geo/geo.py"
$ hg help geo
</pre>
<p>The extension will add an additional line to every commit that you do.</p>
<pre>
<b>$ hg commit</b>
<b>$ hg log -v</b>
changeset:   9:236a0f4c3d2e
tag:         tip
user:        David Soria Parra <dsp @php.net>
date:        Sun Jan 02 03:01:04 2011 +0100
files:       .hgtags
description:
Added tag v1.0.0 for changeset 3079e3ff3083

geocommit(1.0): lat 48.1211306, long 11.4853251, hacc 30.0, src nmg;
</dsp></pre>
<p>Now push your geocommits to <a href="http://bitbucket.org">bitbucket</a>.</p>
<pre>
<b>$ hg push</b>
</pre>
<hr />
<strong>Deep dive</strong><br />
As Mercurial doesn&#8217;t have a way to store metadata, we are adding the geocommit data to the commit message itself. The obvious advantage is that you can use hg-geo with plain Mercurial. You do not need to enable hg-geo on the remote site to push geocommits (like Mercurial bookmarks). The disadvantage is that we modify the commit message and therefore the commit hash. There is no easy way to delete geocommits once they are created.</p>
<hr />
<h3>bitbucket.org and github.com</h3>
<p>We can push geocommits easily now. But how to use them? We can install the Firefox or Chrome extension. This will display a map next to your commit!</p>
<p><strong>Firefox</strong><br />
To install the geocommit extension for Firefox you need Greasemonkey. Greasemonkey is a well know and supported extension that enables user scripts to safely modify the displayed website.</p>
<p>Install Greasemonkey from <a href="https://addons.mozilla.org/de/firefox/addon/748/>addons.mozilla.org and then install the geocommit script from <a href="http://userscripts.org/scripts/show/93129">userscripts.org</a>. You can then browse bitbucket.org or github.com and see a map of your geocommit:</p>
<p><a href="http://blog.experimentalworks.net/wp-content/uploads/2011/01/bb.png"><img src="http://blog.experimentalworks.net/wp-content/uploads/2011/01/bb-300x160.png" alt="bitbucket with geocommit support" title="bitbucket with geocommit support" width="300" height="160" class="alignnone size-medium wp-image-493" /></a></p>
<p><a href="http://blog.experimentalworks.net/wp-content/uploads/2011/01/gh.png"><img src="http://blog.experimentalworks.net/wp-content/uploads/2011/01/gh-300x130.png" alt="github with geocommit support" title="github with geocommit support" width="300" height="130" class="alignnone size-medium wp-image-494" /></a></p>
<p><strong>Chrome</strong><br />
On Chrome install the plugin from<br />
<a href="https://chrome.google.com/extensions/detail/mchakdojblmfdjnhbdopinejdffjjgga">chrome.google.com</a></p>
<h3>Post Hook</h3>
<p>We offer a post hook that you can use with github.com and bitbucket.org. Your commits will be tracked by gecommit.com and we will create a global and a project specific map as well as provide further analytics as soon as possible.</p>
<p><strong>github.com</strong><br />
To install the hook go to th eadmin section of your repository and select <em>Service Hooks</em>.<br />
<a href="http://blog.experimentalworks.net/wp-content/uploads/2011/01/gh-hook1.png"><img src="http://blog.experimentalworks.net/wp-content/uploads/2011/01/gh-hook1-300x113.png" alt="" title="gh-hook1" width="300" height="113" class="alignnone size-medium wp-image-499" /></a></p>
<p>Add <em>http://hook.geocommit.com/api/github</em> as a POST service hook.<br />
<a href="http://blog.experimentalworks.net/wp-content/uploads/2011/01/gh-hook2.png"><img src="http://blog.experimentalworks.net/wp-content/uploads/2011/01/gh-hook2-300x131.png" alt="" title="gh-hook2" width="300" height="131" class="alignnone size-medium wp-image-500" /></a></p>
<p><strong>on bitbucket.org</strong><br />
Go to the admin seciton of your repository and select <em>Services</em><br />
<a href="http://blog.experimentalworks.net/wp-content/uploads/2011/01/bb-hook1.png"><img src="http://blog.experimentalworks.net/wp-content/uploads/2011/01/bb-hook1-300x117.png" alt="" title="bb-hook1" width="300" height="117" class="alignnone size-medium wp-image-502" /></a></p>
<p>Add <em>http://hook.geocommit.com/api/bitbucket</em> as a POST service hook<br />
<a href="http://blog.experimentalworks.net/wp-content/uploads/2011/01/bb-hook21.png"><img src="http://blog.experimentalworks.net/wp-content/uploads/2011/01/bb-hook21-300x140.png" alt="" title="bb-hook2" width="300" height="140" class="alignnone size-medium wp-image-504" /></a></p>
<p>Thats about it. Browse <a href="http://www.geocommit.com/full.html">www.geocommit.com/full.html</a> to checkout your commits on our map.</p>
<p>Questions?!<br />
Enjoy!</p>
 <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=478&amp;md5=b0683e17a20690f1777df225416c7de9" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2011/01/locate-your-commits-or-how-to-use-geocommit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=dsp&amp;popout=1&amp;url=http%3A%2F%2Fblog.experimentalworks.net%2F2011%2F01%2Flocate-your-commits-or-how-to-use-geocommit%2F&amp;language=en_GB&amp;category=text&amp;title=Locate+your+commits+or+how+to+use+geocommit.&amp;description=We+recently+launched+geocommit.com.+Geocommit+is+a+service+to+add+geolocation+data+to+your+commits.+You+only+need+a+working+WiFi+connection.+No+GPS+module+is+required.+This+blogpost+gives...&amp;tags=blog" type="text/html" />
	</item>
	</channel>
</rss>
