Git tip: Changing your mind: Push pending changes to a (not-yet existing) new branch

February 15th, 2012 by Alexander Kirk | Comments 1 Comment »

It happens quite often to me that I start committing things and only afterwards decide I should have created a new branch.

So git status says something like:

Your branch is ahead of 'origin/master' by 4 commits.


but I don't want to push to origin/master but rather create a new branch. (Of course this works for any other branch, not named master)

So you can use this sequence of commands:

git checkout -b newbranch
git push origin newbranch
git checkout master
git reset --hard origin/master

Explanation: This…

1. creates a new branch pointing to the current changes (and switches to it)

2. pushes this new branch including the changes to the server

3. switches back to the branch master
4. and undoes the changes that were made locally

The important thing to know is that the changes remain in the repository because a branch is merely a pointer to a commit.

Afterwards you can continue to commit to master, for example:

(screenshots done with a fork of gitx)

hckr news

January 26th, 2012 by Alexander Kirk | Comments 1 Comment »

Just wanted to point you all to Wayne Larsen's alternate interface to Hackernews, called hckr news.

I really like the clean and fast interface, compared to the everlasting old interface on the original page (even though you can of course use User CSS to pep it up a little).

Wayne also created browser extensions that do a little more good to the old Hacker News interface. He also included my Collasible Threads bookmarklet. Thanks!

Use an authenticated feed in Google Reader

January 3rd, 2012 by Alexander Kirk | Comments Comments Off

You currently can't subscribe to an authenticated feed (for example in Basecamp) in Google Reader.

If you want to do it nonetheless you can use this script of mine which will talk to the server that needs authentication, passing through all the headers (so that also cookies and "not modified" requests will come through): download authenticated-feed-passthru.php


<?php
// change this url
$url = "https://username:password@proj.basecamphq.com/projects/123/feed/recent_items_rss";

$ch = curl_init($url);

if (isset($_SERVER['REQUEST_METHOD']) && strtolower($_SERVER['REQUEST_METHOD']) == 'post') {
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST);
}

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, true);

$headers = array();
foreach ($_SERVER as $name => $value) {
    if (substr($name, 0, 5) != 'HTTP_') continue;
    if ($name == "HTTP_HOST") continue;
    $headers[] = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))) . ": " . $value;
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

list($header, $contents) = preg_split('/([\r\n][\r\n])\\1/', curl_exec($ch), 2);
curl_close($ch);

foreach (preg_split('/[\r\n]+/', $header) as $header) {
    header($header);
}

echo $contents;

If you don't mind giving away your credentials you can also use Free My Feed.

New Feature for HN Collapsible Threads: Collapse Whole Thread

December 6th, 2011 by Alexander Kirk | Comments Comments Off

I have added a feature to the HN Collapsible Threads bookmarklet that enables you to close a whole thread from any point within the thread:

This is useful when you are reading a thread and decided that you are having enough of it and want to move on to the next thread. Before you had to scroll all the way up to the top post and collapse that one.

Drag this to your bookmarks bar: collapsible threads

Install Greasemonkey script

preg_match, UTF-8 and whitespace

October 1st, 2011 by Alexander Kirk | Comments Comments Off

Just a quick note, be careful when using the whitespace character \s in preg_match when operating with UTF-8 strings.

Suppose you have a string containing a dagger symbol. When you try to strip all whitespace from the string like this, you will end up with an invalid UTF-8 character:

$ php -r 'echo preg_replace("#\s#", "", "†");' | xxd
0000000: e280

(On a side note: xxd displays all bytes in hexadecimal representation. The resulting string here consists of two bytes e2 and 80)

\s stripped away the a0 byte. I was unaware that this character was included in the whitespace list, but actually it represents the non-breaking space.

So actually use the u (PCRE8) modifier as it will be aware of the a0 "belonging" to the dagger:

$ php -r 'echo preg_replace("#\s#u", "", "†");' | xxd
0000000: e280 a0

By the way, trim() doesn't strip non-breaking spaces and can therefore safely be used for UTF-8 strings. (If you still want to trim non-breaking spaces with trim, read this comment on PHP.net)

Finally here you can see the ASCII characters matched by \s when using the u modifier.

$ php -r '$i = 0; while (++$i < 256) echo preg_replace("#[^\s]#", "", chr($i));' | xxd
0000000: 090a 0c0d 2085 a0
$ php -r '$i = 0; while (++$i < 256) echo preg_replace("#[^\s]#u", "", chr($i));' | xxd
0000000: 090a 0c0d 20

Functions operating just on the ASCII characters (with a byte code below 128) are generally safe, as the multi-byte characters of UTF-8 have a leading bit of one (and are therefore above 128).

Restoring single objects in mongodb

May 31st, 2011 by Alexander Kirk | Comments Comments Off

Today I had the need to restore single objects from a mongodb installation. mongodb offers two tools for this mongodump and mongorestore, both of which seem to be designed to only dump and restore whole collections.

So I'll demonstrate the workflow just to restore a bunch of objects. Maybe it's a clumsy way, but we'll improve this over time.

So, we have an existing backup, done with mongodump (for example through a daily, over-night backup). This consists of several .bson files, one for each collection.

  1. Restore a whole collection to a new database: mongorestore -d newdb collection.bson
  2. Open this database: mongo newdb
  3. Find the items you want to restore through a query, for example: db.collection.find({"_id": {"$gte": ObjectId("4da4231c747359d16c370000")}});
  4. Back on the command line again, just dump these lines to a new bson file: mongodump -d newdb -c collection -q '{"_id": {"$gte": ObjectId("4da4231c747359d16c370000")}}'
  5. Now you can finally import just those objects into your existing collection: mongorestore -d realdb collection.bson

Safari Extension: Clean URLs

March 30th, 2011 by Alexander Kirk | Comments Comments Off

I have been picking up and developing a fork of Grant Heaslip's Safari extension URL clenser which removes all sorts of un-necessary junk for the URL so that you can easily pass on a clean URL to someone else. Things being removed include:

  • Google Analytics parameters (utm_source=, utm_medium, etc.)
  • Youtube related parameters (feature=)
  • Partner tracking stuff for NYTimes, Macword, CNN, CBC Canada and The Star

You can download my version here: url_cleanser.safariextz

trac Report for Feature Voting

January 27th, 2011 by Alexander Kirk | Comments Comments Off

I use trac for quite a few projects of mine. Recently I tried to find a plugin for deciding which features to implement next. Usually trac hacks has something in store for that, but not this time.

I wanted to be able to create a ticket and then collect user feedback as comments for the feature, with each piece of feedback being a vote for that feature, like this:

After searching for a bit I came up with a solution by using just a report with a nicely constructed SQL query.

SELECT p.value AS __color__,
   t.type AS `type`, id AS ticket, count(tc.ticket) as votes, summary, component, version, milestone,
   t.time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, ticket_change tc, enum p
  WHERE t.status <> 'closed'
AND tc.ticket = t.id and tc.field = 'comment' and tc.newvalue like '%#vote%'
AND p.name = t.priority AND p.type = 'priority'
GROUP BY id, summary, component, version, milestone, t.type, owner, t.time,
  changetime, description, reporter, p.value, status
HAVING count(tc.ticket) >= 1
 ORDER BY votes DESC, milestone, t.type, t.time

So just by including "#vote" in a comment, it would count towards the number of votes. You can change this text to anything you want, of course. For example like this:

I hope this can be useful for someone else, too.

iOS 2011 Alarm Clock Bug

January 11th, 2011 by Alexander Kirk | Comments Comments Off

Just to add to the speculation about the causes of the 2011 alarm clock bug of iOS where the one-time alarms would not activate on January 1 and January 2, 2011.

My guess is that the code that sets off the alarm takes day, month and year into account when checking whether the alarm should go off. But instead of using the "normal" year, an ISO-8601 year could have been used. This type of year is calculated by the number of the week (with Monday as the first day of the week), thus for the week 52 (from December 27, 2010 to January 2, 2011) the respective year remains 2010.

When setting the date to January 1, 2012, the alarm doesn't go off as well (week 52 of 2011). This adds to my theory and also means that this hasn't been a one-time issue and requires a bug fix by Apple.

Title Junk: Solve it with Javascript

December 21st, 2010 by Alexander Kirk | Comments Comments Off

There is some back and forth by John Gruber and others, about HTML <title> tags, with Gruber complaining (and rightly so) that for SEO reasons the titles are filled up with junk having little to do with the real page content.

The writers of cam.ly suggest to use the SEO title in the HTML and have something proper be displayed in Google by using an OpenSearch description. But this still doesn't solve the problem of bloated window titles and bookmarks.

So my solution to that: use JavaScript. If you want to satisfy your readers with a good title and present a nice title to Google, simply set the title to something nice after the page has loaded with JavaScript:


document.title = "Title Junk: Solve it with JavaScript";

Everyone happy. Except those who have JavaScript disabled maybe.

I have also created a tiny WordPress plugin that does just that: title-junk.zip

Discussion on Hacker News

Colorillo: Draw on an LED Wall

July 22nd, 2010 by Alexander Kirk | Comments Comments Off

Colorillo currently powers a collaborative drawing event in Vienna: At Adria Wien there is a temporary LED wall on which you can draw with the help of Colorillo.

Take your mobile phone (iPhone or Android, also iPod Touch, iPad or Laptop works) out of your pocket, enter the URL that you find there, and on your screen you will see what's on the LED wall. Then you can paint on that. Of course with the technology of Colorillo, multiple people can draw at the same time.

The resolution is a little limited, as the LED wall had been built by hand by students of architecture, so in my experience it's a little more like splash painting with colors, but we'll see how it turns out tonight.

Tonight (July 22, 2010) at 8:30pm there is a special drawing event with John Megill of FM4 as a DJ. If you're around, come by! It will be fun!

The whole event is hosted by the Ärzte ohne Grenzen (Doctors without borders) beach that has been set up for the duration of the AIDS conference that is being held in Vienna this year.

You can also join the event on Facebook and check out more info at the Colorillo blog post.

Reddit-like Collapsible Threads for Hacker News

February 16th, 2010 by Alexander Kirk | Comments 6 Comments »

I enjoy consuming and participating at Hacker News by Y Combinator resp. Paul Graham.

One thing that needs improvement is the reading comments there. At times it happens that the first comment develops into a huge thread, and then the second top-level comment (which might also be well worth reading) disappears somewhere down into the page.

Collapsible Threads at Hacker News through a bookmarkletReddit has combatted this common problem by making threads easily collapsible. I think it is worth having this also on Hacker News, so I implemented it and wrapped it into a bookmarklet so that you can use this functionality on-demand at Hacker News.

Drag this to your bookmarks bar: collapsible threads

As soon as it is available in your bookmarks bar, go to Hacker News and click on it when viewing a comments page. Next to each thread a symbol [+] will appear. Click it to collapse the thread and it will change to a [-]. Click that to expand the thread again.

I have licensed the source code under an MIT License. Click here to view the source code of hackernews-collapsible-threads.js. (Actually for caching reasons the bookmarklet currently loads hackernews-collapsible-threads-v6.js which is actually just the same)

The Hacker News HTML source code seems quite fragile in the sense that the comments section of a page can't be identified in a really unique way (for example it does not have an HTML id attribute), so it might break when the layout of the page changes. This is why the bookmarklet is actually only a loader for the script on my server. I have tuned the HTTP headers in a way that your browser should properly cache the script so that the speed of my server should not affect the loading of the bookmarklet.

Enjoy :)

If you use Hackernews on another URL than news.ycombinator.com or hackerne.ws, use this bookmarklet: collapsible threads (no domain check)

Update March 18, 2011: Paul Biggar has contributed a greasemonkey script that also works on Firefox 4. I have adapted it so that it also works (which basically involved copying the jQuery script above mine) in Safari and Chrome (using NinjaKit).

Install Greasemonkey script

Install Paul Biggar's Greasemonkey script

Update November 22, 2011: Eemeli Aro has sent me a little CSS tweak so that the lines don't move around when collapsing. The code downloadable from above contains his code. Thank you!