<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en" xml:base="http://nerderati.com/wp-atom.php">
	<title type="text">Nerderati</title>
	<subtitle type="text">You're probably not nerdy enough.</subtitle>

	<updated>2012-10-20T20:22:06Z</updated>

	<link rel="alternate" type="text/html" href="http://nerderati.com" />
	<id>http://nerderati.com/feed/atom/</id>
	

	<generator uri="http://wordpress.org/" version="3.1.1">WordPress</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/nerderati" /><feedburner:info uri="nerderati" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
		<author>
			<name>jperras</name>
						<uri>http://nerderati.com</uri>
					</author>
		<title type="html"><![CDATA[Simplify Your Life With an SSH Config File]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nerderati/~3/qr-ttNxseCg/" />
		<id>http://nerderati.com/?p=550</id>
		<updated>2012-10-20T18:57:51Z</updated>
		<published>2011-03-17T20:15:08Z</published>
		<category scheme="http://nerderati.com" term="Programming" /><category scheme="http://nerderati.com" term="development" /><category scheme="http://nerderati.com" term="sysadmin" />		<summary type="html"><![CDATA[If you&#8217;re anything like me, you probably log in and out of a half dozen remote servers (or these days, local virtual machines) on a daily basis. And if you&#8217;re even more like me, you have trouble remembering all of the various usernames, remote addresses and command line options for things like specifying a non-standard [...]]]></summary>
		<content type="html" xml:base="http://nerderati.com/2011/03/simplify-your-life-with-an-ssh-config-file/">&lt;p&gt;If you&amp;#8217;re anything like me, you probably log in and out of a half dozen remote servers (or these days, local virtual machines) on a daily basis. And if you&amp;#8217;re even &lt;em&gt;more&lt;/em&gt; like me, you have trouble remembering all of the various usernames, remote addresses and command line options for things like specifying a non-standard connection port or forwarding local ports to the remote machine.&lt;/p&gt;
&lt;h3&gt;Shell Aliases&lt;/h3&gt;
&lt;p&gt;Let&amp;#8217;s say that you have a remote server named &lt;code class="codecolorer bash blackboard"&gt;&lt;span class="bash"&gt;dev.example.com&lt;/span&gt;&lt;/code&gt;, which has &lt;em&gt;not&lt;/em&gt; been set up with public/private keys for password-less logins. The username to the remote account is &lt;em&gt;fooey&lt;/em&gt;, and to reduce the number of scripted login attempts, you&amp;#8217;ve decided to change the default SSH port to 2200 from the normal default of 22. This means that a typical command would look like:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ssh&lt;/span&gt; fooey&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;dev.example.com &lt;span style="color: #660033;"&gt;-p&lt;/span&gt; &lt;span style="color: #000000;"&gt;22000&lt;/span&gt;&lt;br /&gt;
password: &lt;span style="color: #000000; font-weight: bold;"&gt;*************&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Not too bad.&lt;/p&gt;
&lt;p&gt;We can make things simpler and more secure by using a public/private key pair; I highly recommend using &lt;a href="http://linux.die.net/man/1/ssh-copy-id"&gt;ssh-copy-id&lt;/a&gt; for moving your public keys around. It will save you quite a few folder/file permission headaches.&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ssh&lt;/span&gt; fooey&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;dev.example.com &lt;span style="color: #660033;"&gt;-p&lt;/span&gt; &lt;span style="color: #000000;"&gt;22000&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# Assuming your keys are properly setup...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now this doesn&amp;#8217;t seem all that bad. To cut down on the verbosity you could create a simple alias in your shell as well:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ &lt;span style="color: #7a0874; font-weight: bold;"&gt;alias&lt;/span&gt; &lt;span style="color: #007800;"&gt;dev&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;'ssh fooey@dev.example.com -p 22000'&lt;/span&gt;&lt;br /&gt;
$ &lt;span style="color: #666666; font-style: italic;"&gt;# To connect:&lt;/span&gt;&lt;br /&gt;
$ dev&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This works surprisingly well: Every new server you need to connect to, just add an alias to your &lt;code class="codecolorer bash blackboard"&gt;&lt;span class="bash"&gt;.bashrc&lt;/span&gt;&lt;/code&gt; (or &lt;code class="codecolorer bash blackboard"&gt;&lt;span class="bash"&gt;.zshrc&lt;/span&gt;&lt;/code&gt; if you hang with the cool kids), and voilà.&lt;/p&gt;
&lt;h3&gt;~/.ssh/config&lt;/h3&gt;
&lt;p&gt;However, there&amp;#8217;s a much more elegant and flexible solution to this problem. Enter the SSH config file:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# contents of $HOME/.ssh/config&lt;/span&gt;&lt;br /&gt;
Host dev&lt;br /&gt;
&amp;nbsp; &amp;nbsp; HostName dev.example.com&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Port &lt;span style="color: #000000;"&gt;22000&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; User fooey&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This means that I can simply &lt;code class="codecolorer bash blackboard"&gt;&lt;span class="bash"&gt;&amp;nbsp;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ssh&lt;/span&gt; dev&lt;/span&gt;&lt;/code&gt;, and the options will be read from the configuration file. Easy peasy. Let&amp;#8217;s see what else we can do with just a few simple configuration directives.&lt;/p&gt;
&lt;p&gt;Personally, I use quite a few public/private keypairs for the various servers and services that I use, to ensure that in the event of having one of my keys compromised the dammage is as restricted as possible. For example, I have a key that I use uniquely for my &lt;a href="https://github.com/jperras"&gt;github&lt;/a&gt; account. Let&amp;#8217;s set it up so that that particular private key is used for all my github-related operations:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;Host dev&lt;br /&gt;
&amp;nbsp; &amp;nbsp; HostName dev.example.com&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Port &lt;span style="color: #000000;"&gt;22000&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; User fooey&lt;br /&gt;
&lt;br /&gt;
Host github.com&lt;br /&gt;
&amp;nbsp; &amp;nbsp; IdentityFile ~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.ssh&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;github.key&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The use of &lt;code class="codecolorer bash blackboard"&gt;&lt;span class="bash"&gt;IdentityFile&lt;/span&gt;&lt;/code&gt; allows me to specify exactly which private key I wish to use for authentification with the given host. You can, of course, simply specify this as a command line option for &amp;#8220;normal&amp;#8221; connections:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;&amp;nbsp;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ssh&lt;/span&gt; &lt;span style="color: #660033;"&gt;-i&lt;/span&gt; ~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.ssh&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;blah.key username&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;host.com&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;but the use of a config file with &lt;code class="codecolorer text blackboard"&gt;&lt;span class="text"&gt;IdentityFile&lt;/span&gt;&lt;/code&gt; is &lt;a href="https://git.wiki.kernel.org/index.php/GitTips#How_to_pass_ssh_options_in_git.3F"&gt;pretty much your only option&lt;/a&gt; if you want to specify which identity to use for any git commands. This also opens up the very interesting concept of further segmenting your github keys on something like a per-project or per-organization basis:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;Host github-project1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; User &lt;span style="color: #c20cb9; font-weight: bold;"&gt;git&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; HostName github.com&lt;br /&gt;
&amp;nbsp; &amp;nbsp; IdentityFile ~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.ssh&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;github.project1.key&lt;br /&gt;
&lt;br /&gt;
Host github-org&lt;br /&gt;
&amp;nbsp; &amp;nbsp; User &lt;span style="color: #c20cb9; font-weight: bold;"&gt;git&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; HostName github.com&lt;br /&gt;
&amp;nbsp; &amp;nbsp; IdentityFile ~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.ssh&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;github.org.key&lt;br /&gt;
&lt;br /&gt;
Host github.com&lt;br /&gt;
&amp;nbsp; &amp;nbsp; User &lt;span style="color: #c20cb9; font-weight: bold;"&gt;git&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; IdentityFile ~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.ssh&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;github.key&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Which means that if I want to clone a repository using my organization credentials, I would use the following:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;git&lt;/span&gt; clone &lt;span style="color: #c20cb9; font-weight: bold;"&gt;git&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;github-org:orgname&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;some_repository.git&lt;/div&gt;&lt;/div&gt;
&lt;h3&gt;Going further&lt;/h3&gt;
&lt;p&gt;As any security-conscious developer would do, I set up firewalls on all of my servers and make them as restrictive as possible; in many cases, this means that the only ports that I leave open are 80/443 (for webservers), and port 22 for SSH (or whatever I might have remapped it to for obfuscation purposes). On the surface, this seems to prevent me from using things like a desktop MySQL GUI client, which expect port 3306 to be open and accessible on the remote server in question. The informed reader will note, however, that a simple local port forward can save you:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ssh&lt;/span&gt; &lt;span style="color: #660033;"&gt;-f&lt;/span&gt; &lt;span style="color: #660033;"&gt;-N&lt;/span&gt; &lt;span style="color: #660033;"&gt;-L&lt;/span&gt; &lt;span style="color: #000000;"&gt;9906&lt;/span&gt;:127.0.0.1:&lt;span style="color: #000000;"&gt;3306&lt;/span&gt; coolio&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;database.example.com&lt;br /&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# -f puts ssh in background &lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# -N makes it not execute a remote command&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This will forward all local port &lt;code class="codecolorer text blackboard"&gt;&lt;span class="text"&gt;9906&lt;/span&gt;&lt;/code&gt; traffic to port 3306 on the remote &lt;code class="codecolorer text blackboard"&gt;&lt;span class="text"&gt;dev.example.com&lt;/span&gt;&lt;/code&gt; server, letting me point my desktop GUI to localhost (127.0.0.1:9906) and have it behave exactly as if I had exposed port 3306 on the remote server and connected directly to it.&lt;/p&gt;
&lt;p&gt;Now I don&amp;#8217;t know about you, but remembering that sequence of flags and options for &lt;a href="http://linux.die.net/man/1/ssh"&gt;SSH&lt;/a&gt; can be a complete pain. Luckily, our config file can help alleviate that:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;Host tunnel&lt;br /&gt;
&amp;nbsp; &amp;nbsp; HostName database.example.com&lt;br /&gt;
&amp;nbsp; &amp;nbsp; IdentityFile ~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.ssh&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;coolio.example.key&lt;br /&gt;
&amp;nbsp; &amp;nbsp; LocalForward &lt;span style="color: #000000;"&gt;9906&lt;/span&gt; 127.0.0.1:&lt;span style="color: #000000;"&gt;3306&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; User coolio&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Which means I can simply do:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ssh&lt;/span&gt; &lt;span style="color: #660033;"&gt;-f&lt;/span&gt; &lt;span style="color: #660033;"&gt;-N&lt;/span&gt; tunnel&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And my local port forwarding will be enabled using all of the configuration directives I set up for the &lt;code class="codecolorer text blackboard"&gt;&lt;span class="text"&gt;tunnel&lt;/span&gt;&lt;/code&gt; host. Slick.&lt;/p&gt;
&lt;h3&gt;Homework&lt;/h3&gt;
&lt;p&gt;There are quite a few configuration options that you can specify in &lt;code class="codecolorer text blackboard"&gt;&lt;span class="text"&gt;~/.ssh/config&lt;/span&gt;&lt;/code&gt;, and I highly suggest consulting the online &lt;a href="http://linux.die.net/man/5/ssh_config"&gt;documentation&lt;/a&gt; or the &lt;em&gt;ssh_config&lt;/em&gt; man page. Some interesting/useful things that you can do include: change the default number of connection attempts, specify local environment variables to be passed to the remote server upon connection, and even the use of * and ? wildcards for matching hosts. &lt;/p&gt;
&lt;p&gt;I hope that some of this is useful to a few of you. Leave a note in the comments if you have any cool tricks for the SSH config file; I&amp;#8217;m always on the lookout for fun hacks.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/nerderati/~4/qr-ttNxseCg" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://nerderati.com/2011/03/simplify-your-life-with-an-ssh-config-file/#comments" thr:count="37" />
		<link rel="replies" type="application/atom+xml" href="http://nerderati.com/2011/03/simplify-your-life-with-an-ssh-config-file/feed/atom/" thr:count="37" />
		<thr:total>37</thr:total>
	<feedburner:origLink>http://nerderati.com/2011/03/simplify-your-life-with-an-ssh-config-file/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>jperras</name>
						<uri>http://nerderati.com</uri>
					</author>
		<title type="html"><![CDATA[Ideas of March]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nerderati/~3/mB0yCP6j65A/" />
		<id>http://nerderati.com/?p=531</id>
		<updated>2011-03-18T02:11:48Z</updated>
		<published>2011-03-15T15:43:11Z</published>
		<category scheme="http://nerderati.com" term="Blogging" /><category scheme="http://nerderati.com" term="blog" /><category scheme="http://nerderati.com" term="tech" /><category scheme="http://nerderati.com" term="twitter" />		<summary type="html"><![CDATA[Today my friend <a href="http://shiflett.org/">Chris</a> posted an article with the intent of <a href="http://shiflett.org/blog/2011/mar/ideas-of-march">starting a blog revival</a>, and this is one movement that I intend to participate in.]]></summary>
		<content type="html" xml:base="http://nerderati.com/2011/03/ideas-of-march/">&lt;p&gt;Four years ago when I started using a &lt;a href="http://twitter.com/jperras"&gt;micro-blogging&lt;/a&gt; service, I revelled in the sheer simplicity and low barrier to communicating my thoughts. Blogging, in that era, seemed like a historical vestige on the verge of being consumed and overtaken by the rapid fire, real-time tweets of my peers. I jumped on that bandwagon, and never looked back. Until now.&lt;/p&gt;
&lt;p&gt;Like my friend &lt;a href="http://shiflett.org/blog/2011/mar/ideas-of-march"&gt;Chris&lt;/a&gt; (&lt;a href="http://allinthehead.com/retro/354/ideas-of-march"&gt;and&lt;/a&gt; &lt;a href="http://jontangerine.com/log/2011/03/ides-of-march"&gt;many&lt;/a&gt; &lt;a href="http://blog.jasonlotito.com/programming/ideas-of-march/"&gt;others&lt;/a&gt;), I am reminded of the time when we used to have productive and lengthy discussions in and around blog posts. Moreover, I am reminded of the fact that when I truly need to find some snippet of information or tutorial on a particular web-related topic, the solution is rarely found in multiples of one hundred forty characters.&lt;/p&gt;
&lt;p&gt;Now, I&amp;#8217;m not ditching Twitter. Micro-blogging does serve a very important role (and I was reminded of this during the recent tsunami/earthquake in Japan) in the effective transmission of near real-time information, but I &lt;em&gt;miss&lt;/em&gt; the asynchronous nature of blogs and the less ephemeral nature of the community that surrounds them. It&amp;#8217;s about time that I do something to remedy that.&lt;/p&gt;
&lt;p&gt;For the rest of the month of March, I will be &lt;a href="http://nerderati.com"&gt;posting at least two articles&lt;/a&gt; per week on various different tech-related topics, with the intent on starting a habit of regular, informative blogging, and I hope that you will join me in this endeavour. I hope and believe that the long term rewards will far outweigh the short term investment in time and effort.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s try and move the conversations we have from being limited by the bits and bytes of tweets to sentences and paragraphs.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/nerderati/~4/mB0yCP6j65A" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://nerderati.com/2011/03/ideas-of-march/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://nerderati.com/2011/03/ideas-of-march/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	<feedburner:origLink>http://nerderati.com/2011/03/ideas-of-march/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>jperras</name>
						<uri>http://nerderati.com</uri>
					</author>
		<title type="html"><![CDATA[Code Your Art Out: If Non-Profits and Tech Had Babies]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nerderati/~3/QZKXqenr_LU/" />
		<id>http://nerderati.com/?p=515</id>
		<updated>2011-03-11T21:23:12Z</updated>
		<published>2011-03-11T21:19:21Z</published>
		<category scheme="http://nerderati.com" term="Programming" />		<summary type="html"><![CDATA[Ever since I had the pleasure of keynoting at Make Web Not War: For The Web in 2010, I&#8217;ve been eagerly awaiting the announcement of the 2011 edition, which was announced just a few days ago. The title of this year&#8217;s competition is Code Your Art Out, and the theme is that of &#8220;helping non-profits [...]]]></summary>
		<content type="html" xml:base="http://nerderati.com/2011/03/code-your-art-out-if-non-profits-and-tech-had-babies/">&lt;p&gt;Ever since I had the pleasure of keynoting at &lt;a href="http://www.webnotwar.ca/ftw/"&gt;Make Web Not War: For The Web&lt;/a&gt; in 2010, I&amp;#8217;ve been eagerly awaiting the announcement of the 2011 edition, which was announced just a few days ago.&lt;/p&gt;
&lt;p&gt;The title of this year&amp;#8217;s competition is &lt;em&gt;Code Your Art Out&lt;/em&gt;, and the theme is that of &amp;#8220;helping non-profits harness the power of technology in order to better serve its communities and members&amp;#8221;. Oddly enough, this is a topic that I have discussed many times over the years with &lt;a href="http://twitter.com/katiestardust"&gt;@katiestardust&lt;/a&gt;, and is thus very close to my heart.&lt;/p&gt;
&lt;p&gt;The competition itself is rather simple: You &lt;a href="http://www.webnotwar.ca/competition/register"&gt;register&lt;/a&gt;, think of an application that might be useful for non-profits (there&amp;#8217;s a &lt;a href="http://www.webnotwar.ca/competition/project-ideas/"&gt;list of ideas&lt;/a&gt; available if you&amp;#8217;re stuck), and the architect/code/design/innovate to your heart&amp;#8217;s content. As an added incentive, there&amp;#8217;s a &lt;a href="http://www.webnotwar.ca/competition/how-to-compete/"&gt;non-negligible chunk of cash&lt;/a&gt; given out to the teams that place in first and second. The only technological requirements are that you need to use either the Windows Azure clould platform, or deploy on Windows IIS as your webserver.&lt;/p&gt;
&lt;p&gt;While there&amp;#8217;s no requirement that the applications developed be made available under an &lt;a href="http://www.opensource.org/licenses/alphabetical"&gt;open source license&lt;/a&gt;, I&amp;#8217;m hopeful that many submissions will choose to go this route.&lt;/p&gt;
&lt;p&gt;The use of modern web technology stacks and applications in most non-profits is woefully lacking, and the space is ripe for innovation. I’m very excited to see what applications people develop!&lt;/p&gt;
&lt;p&gt;A few resources:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://twitter.com/#!/CodeYourArtOut"&gt;Twitter account&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.facebook.com/event.php?eid=175320262514766"&gt;Facebook Event page&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.facebook.com/pages/Code-Your-Art-Out-Competition/129146523825367?sk=info"&gt;Facebook Page&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.webnotwar.ca/competition/"&gt;&lt;img src="http://dl.dropbox.com/u/58324/images/code_your_art_out_white.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/nerderati/~4/QZKXqenr_LU" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://nerderati.com/2011/03/code-your-art-out-if-non-profits-and-tech-had-babies/#comments" thr:count="4" />
		<link rel="replies" type="application/atom+xml" href="http://nerderati.com/2011/03/code-your-art-out-if-non-profits-and-tech-had-babies/feed/atom/" thr:count="4" />
		<thr:total>4</thr:total>
	<feedburner:origLink>http://nerderati.com/2011/03/code-your-art-out-if-non-profits-and-tech-had-babies/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>jperras</name>
						<uri>http://nerderati.com</uri>
					</author>
		<title type="html"><![CDATA[Perpetual IRC &#8211; The Proxy Edition]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nerderati/~3/-Bv4vwOQ3dc/" />
		<id>http://nerderati.com/?p=432</id>
		<updated>2011-04-05T14:17:48Z</updated>
		<published>2010-11-29T19:08:02Z</published>
		<category scheme="http://nerderati.com" term="Programming" /><category scheme="http://nerderati.com" term="communication" /><category scheme="http://nerderati.com" term="irc" />		<summary type="html"><![CDATA[Last time, we looked at how one could maintain a persistent session in IRC through the use of a terminal multiplexer (such as screen or tmux) and SSH. While this has the advantage of being very easy to setup, there are a few very obvious disadvantages and trade-offs: You must be on a machine that [...]]]></summary>
		<content type="html" xml:base="http://nerderati.com/2010/11/perpetual-irc-the-proxy-edition/">&lt;p&gt;&lt;a href="http://nerderati.com/2010/09/perpetual-irc-the-multiplexer-edition/"&gt;Last time&lt;/a&gt;, we looked at how one could maintain a persistent session in IRC through the use of a terminal multiplexer (such as &lt;strong&gt;screen&lt;/strong&gt; or &lt;strong&gt;tmux&lt;/strong&gt;) and SSH. While this has the advantage of being very easy to setup, there are a few very obvious disadvantages and trade-offs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You must be on a machine that is able to SSH into your remote server.&lt;/li&gt;
&lt;li&gt;You are confined to using the command-line IRC client running in the remote session.&lt;/li&gt;
&lt;li&gt;Any scripts that attempt to interact with your ‘local’ desktop (e.g. Growl notifications), are painful to setup, if not impossible.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For many, including myself, the first two are deal-breakers. I use a variety of computing devices on a daily basis, and asking me to SSH into a remote server from my smartphone to then attach a &lt;strong&gt;screen&lt;/strong&gt; session is &lt;em&gt;not&lt;/em&gt; reasonable. Luckily, there does exist a method for establishing a ‘perpetual’ IRC session that does not suffer from any of the disadvantages brought on by the SSH + multiplexer approach.&lt;/p&gt;
&lt;h2&gt;Enter Bip&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://bip.milkypond.org/"&gt;Bip&lt;/a&gt; is an IRC proxy by Arnaud Cornet and Loïc Gomez, and is released under the GPLv2 license. From their about page:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
[Bip keeps you] connected to your preferred IRC servers, can store the logs for you, and even send them back to your IRC client(s) upon connection. You may want to use bip to keep your logfiles (in a unique format and on a unique computer) whatever your client is, when you connect from multiple workstations, or when you simply want to have a playback of what was said while you were away.
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Strangely, Bip does not seem to be very well known amongst people I would call &amp;#8220;heavy&amp;#8221; IRC users, despite it&amp;#8217;s very lengthy list of useful features and the relatively simple and straightforward setup.&lt;/p&gt;
&lt;h3&gt;Remote Server Setup&lt;/h3&gt;
&lt;p&gt;It may be possible to install Bip through a package manager, but we&amp;#8217;ll go right to building from source to ensure that everyone is on the same page. Feel free to skip this part if you are able to install bip through your distribution&amp;#8217;s package manager.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: You will need to have &lt;strong&gt;git&lt;/strong&gt;, &lt;strong&gt;make&lt;/strong&gt;, &lt;strong&gt;gcc&lt;/strong&gt;, &lt;strong&gt;lex&lt;/strong&gt; and &lt;strong&gt;yacc&lt;/strong&gt; (the latter two are for lexing/parsing the bip configuration file) to compile from source.&lt;/em&gt;&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;mkdir&lt;/span&gt; src &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; src&lt;br /&gt;
$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;git&lt;/span&gt; clone http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;rcs-git.duckcorp.org&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bip&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bip.git&lt;br /&gt;
$ &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; bip&lt;br /&gt;
$ .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bootstrap&lt;br /&gt;
$ .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;configure &lt;span style="color: #666666; font-style: italic;"&gt;# Use the --prefix option to install somewhere other than /usr/local&lt;/span&gt;&lt;br /&gt;
$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;make&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;make&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Assuming we have the proper dependencies installed and there were no errors, we should have two binaries &amp;mdash; &lt;strong&gt;bip&lt;/strong&gt; and &lt;strong&gt;bipmkpw&lt;/strong&gt; &amp;mdash; installed in &lt;strong&gt;/usr/local/bin/&lt;/strong&gt; (or whatever path was specified for the &lt;em&gt;&amp;dash;&amp;dash;prefix&lt;/em&gt; option during the configure phase. In case you decided to skip the &lt;strong&gt;make install&lt;/strong&gt; part of the above instructions, the compiled binaries are available in the &lt;strong&gt;src&lt;/strong&gt; folder of your bip source directory. Place these binaries in an appropriate location, preferably reachable via &lt;strong&gt;$PATH&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Configuration&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Note: Nearly all of this configuration information can be found in the &lt;strong&gt;README&lt;/strong&gt; file included with bip&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;For this configuration file to work, we need to create a directory to store a few things:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;mkdir&lt;/span&gt; &lt;span style="color: #660033;"&gt;-p&lt;/span&gt; ~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.bip&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Let&amp;#8217;s start off with the most bare-bones configuration file possible. Create a file named &lt;em&gt;bip.conf&lt;/em&gt; in your &lt;strong&gt;$HOME/.bip/&lt;/strong&gt; directory with the following contents:&lt;/p&gt;
&lt;script src="http://gist.github.com/714188.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;code class="gist"&gt;&lt;pre&gt;&lt;br /&gt;
# Remember to change out $HOME for your home directory (e.g. `/home/joel`) below.&lt;/p&gt;
&lt;p&gt;ip = &amp;#8220;0.0.0.0&amp;#8243;;&lt;br /&gt;
port = 6667;&lt;br /&gt;
log_level = 2;&lt;br /&gt;
log_root = &amp;#8220;$HOME/.bip/logs&amp;#8221;;&lt;br /&gt;
log_sync_interval = 5;&lt;/p&gt;
&lt;p&gt;# Network definition, a name and server info&lt;br /&gt;
network {&lt;br /&gt;
	name = &amp;#8220;freenode&amp;#8221;;&lt;br /&gt;
	server { host = &amp;#8220;irc.freenode.net&amp;#8221;; port = 6667; };&lt;br /&gt;
};&lt;/p&gt;
&lt;p&gt;user {&lt;br /&gt;
	name = &amp;#8220;joel&amp;#8221;;&lt;br /&gt;
	password = &amp;#8220;
&lt;password_hash_here&gt;&amp;#8220;;&lt;br /&gt;
	default_nick = &amp;#8220;jperras&amp;#8221;;&lt;br /&gt;
	default_user = &amp;#8220;jperras&amp;#8221;;&lt;br /&gt;
	default_realname = &amp;#8220;Joël&amp;#8221;;&lt;/p&gt;
&lt;p&gt;	backlog = true;		        # enable backlog&lt;br /&gt;
	backlog_lines = 200;		# number of lines in backlog, 0 means&lt;br /&gt;
					# no limit&lt;br /&gt;
	backlog_always = false;		# backlog even lines already backlogged&lt;br /&gt;
	backlog_reset_on_talk = false;&lt;br /&gt;
	backlog_reset_connection = false;&lt;br /&gt;
	backlog_msg_only = true;&lt;/p&gt;
&lt;p&gt;	connection {&lt;br /&gt;
		name = &amp;#8220;primary&amp;#8221;;		# used by bip only&lt;br /&gt;
		network = &amp;#8220;freenode&amp;#8221;;	# which ircnet to connect to&lt;/p&gt;
&lt;p&gt;		# Autojoined channels:&lt;br /&gt;
		channel { name = &amp;#8220;#awesome-channel&amp;#8221;; };&lt;br /&gt;
		channel { name = &amp;#8220;#secret-channel&amp;#8221;; key = &amp;#8220;passw0rd&amp;#8221;; };&lt;br /&gt;
		channel { name = &amp;#8220;#unimportant&amp;#8221;; backlog = false; };&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/noscript&gt;
&lt;p&gt;Alright, let&amp;#8217;s go through what these options actually do.&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;ip = &amp;quot;0.0.0.0&amp;quot;;&lt;br /&gt;
port = 6667;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;strong&gt;ip&lt;/strong&gt; string indicates from which IP bip should accept incoming connections, and &lt;strong&gt;port&lt;/strong&gt; is self-explanatory. By setting it to 0.0.0.0, bip will accept a connection from any IP, which is most likely what you want. Additionally, restricting incoming connections to certain IP addresses for particular ports is something that can (and should) be pushed to your firewall.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: Be sure that you have left an opening in your firewall for connecting to your proxy!&lt;/em&gt;&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;log_level = 2;&lt;br /&gt;
log_root = &amp;quot;$HOME/.bip/logs&amp;quot;;&lt;br /&gt;
log_sync_interval = 5;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A &lt;strong&gt;log_level&lt;/strong&gt; of 2 indicates that we want to log all errors and warnings, but ignore info and debug messages. The &lt;strong&gt;log_root&lt;/strong&gt; indicates where logs should be stored, and &lt;strong&gt;log_sync_interval&lt;/strong&gt; dictates at what time interval the log file is written to disk.&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;network {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; name = &amp;quot;freenode&amp;quot;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; server { host = &amp;quot;irc.freenode.net&amp;quot;; port = 6667; };&lt;br /&gt;
};&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Next, we define a network that we would like to connect to. You can specify an arbitrary &lt;strong&gt;name&lt;/strong&gt; &amp;mdash; I could have just as easily called this network &lt;em&gt;opensource&lt;/em&gt; &amp;mdash; and the relevant connection information in the &lt;strong&gt;server&lt;/strong&gt; key.&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;user {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; name = &amp;quot;joel&amp;quot;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; password = &amp;quot;&amp;lt;some_long_password_hash&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; default_nick = &amp;quot;jperras&amp;quot;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; default_user = &amp;quot;jperras&amp;quot;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; default_realname = &amp;quot;Joël&amp;quot;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # ...&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Here, we define a bip user named &amp;#8220;joel&amp;#8221; (this name is only used when you connect from your local client to your proxy), and a password. The password that you insert here should be created through the &lt;strong&gt;bipmkpw&lt;/strong&gt; binary, which will salt &amp;#038; hash an input string to produce the value that needs to be placed in the above &lt;strong&gt;user {}&lt;/strong&gt; block. The other three options of &lt;strong&gt;default_nick&lt;/strong&gt;, &lt;strong&gt;default_user&lt;/strong&gt;, and &lt;strong&gt;default_realname&lt;/strong&gt; should be self-evident if you have ever used IRC before.&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;&amp;nbsp; &amp;nbsp; backlog = true;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; backlog_lines = 200; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; backlog_always = false;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; backlog_reset_on_talk = false;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; backlog_reset_connection = false;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; backlog_msg_only = true;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now we start getting into the more interesting configuration options for bip. &lt;strong&gt;backlog = true&lt;/strong&gt; enables backlogging, which means that when your local client (e.g. smartphone, desktop client, web client) reconnects to your proxy, all the messages that have been logged since your last connection will be replayed to you. This is, in my opinion, the best reason to consider using an IRC proxy such as bip; you&amp;#8217;ll never miss a message, conversation or context again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;backlog_lines = 200 &lt;/strong&gt; sets an upper limit to the number of messages per channel that will be sent to your client upon reconnection.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;backlog_always = false &lt;/strong&gt; indicates that you don&amp;#8217;t want to receive backlog messages that you have already seen. By setting this option to &lt;strong&gt;true&lt;/strong&gt;, &lt;em&gt;every&lt;/em&gt; time you connect a client to your proxy you will receive &lt;strong&gt;backlog_lines&lt;/strong&gt; of backlog messages for each channel. If you do enable this option (which comes in handy when you regularly connect via two or more devices), make sure the value for &lt;strong&gt;backlog_lines&lt;/strong&gt; is something reasonable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;backlog_reset_on_talk&lt;/strong&gt; and &lt;strong&gt;backlog_reset_connection&lt;/strong&gt; indicate that the backlog marker should be reset every time you talk, scoped to the particular channel or entire connection, respectively.&lt;/p&gt;
&lt;p&gt;By setting &lt;strong&gt;backlog_msg_only = true&lt;/strong&gt;, we only log messages and ignore all IRC events, including joins/parts/quits/nick changes, and the like.&lt;/p&gt;
&lt;p&gt;On to the connection definition:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;&amp;nbsp; &amp;nbsp; connection {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; name = &amp;quot;freenode&amp;quot;;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # used by bip only&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; network = &amp;quot;freenode&amp;quot;; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # which IRC network to connect to&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # Autojoined channels:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; channel { name = &amp;quot;#awesome-channel&amp;quot;; };&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; channel { name = &amp;quot;#secret-channel&amp;quot;; key = &amp;quot;passw0rd&amp;quot;; };&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; channel { name = &amp;quot;#unimportant&amp;quot;; backlog = false; };&lt;br /&gt;
&amp;nbsp; &amp;nbsp; };&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;First, we give a &lt;strong&gt;name&lt;/strong&gt; to the connection (which will be useful in the following segment), and specify which &lt;strong&gt;network&lt;/strong&gt; (defined previously) that we wish to connect to.&lt;br /&gt;
Finally, we specify the channels that we wish to automatically connect to when first starting up the bip proxy. Note the use of &lt;strong&gt;key&lt;/strong&gt; for password protected channels, and the &lt;strong&gt;backlog = false&lt;/strong&gt; usage for channels that we never want to receive a backlog for. &lt;/p&gt;
&lt;p&gt;Note that these channels are auto-joined when the bip daemon &lt;em&gt;starts&lt;/em&gt;, and not each time your local client connects to the proxy. Once bip has started up and we connect to it, we are free to join/part channels at will, and these will be persisted between client connections.&lt;/p&gt;
&lt;h3&gt;Starting The Server&lt;/h3&gt;
&lt;p&gt;Alright, let&amp;#8217;s start the bip process:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ /usr/local/bin/bip -f /path/to/bip.conf&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Note: If things don&amp;#8217;t seem to be working as expected, tail&amp;#8217;ing the bip log file may yield some clues as to what is going wrong.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The bip process will daemonize itself by default; use the &lt;strong&gt;-n&lt;/strong&gt; option to have it remain in the foreground, if so desired.&lt;/p&gt;
&lt;p&gt;When you start the bip process, it initiates the IRC handshake &amp;#038; dance that normally occurs when you connect a local client to an IRC network. The channels that you defined in the bip configuration file are now connected to and being kept open by bip.&lt;/p&gt;
&lt;h3&gt;Connecting to the Proxy&lt;/h3&gt;
&lt;p&gt;Now that we&amp;#8217;ve started the bip proxy on our remote server, let&amp;#8217;s fire up an IRC client and configure the server connection information.&lt;/p&gt;
&lt;h4&gt;Examples&lt;/h4&gt;
&lt;p&gt;I&amp;#8217;ve included a few examples of how the server connection information should look like (given the example bip configuration that I&amp;#8217;ve provided above), in both a GUI-based client as well as a text-based one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; The password that must be used when connecting to your proxy must follow this pattern:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;username:unHashedPassword:network&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Where the &lt;strong&gt;username&lt;/strong&gt; portion corresponds to the value of the &lt;strong&gt;name&lt;/strong&gt; field in the &lt;strong&gt;user { }&lt;/strong&gt; block in your bip configuration, the &lt;strong&gt;unHashedPassword&lt;/strong&gt; portion is the un-hashed version of the password that you generated (using &lt;strong&gt;bipmkpw&lt;/strong&gt;) and pasted in your config, and &lt;strong&gt;network&lt;/strong&gt; is the name of the IRC network (also defined in your configuration) that you wish to connect to. &lt;/p&gt;
&lt;p&gt;An interesting thing to note is that, with this particular scheme, it&amp;#8217;s quite simple to connect to a different network, or to add a new user to the proxy.&lt;/p&gt;
&lt;h5&gt;Colloquy&lt;/h5&gt;
&lt;p&gt;&lt;img src="http://img.skitch.com/20101129-qcppy8r33ujh4asp18hx7gqq93.jpg" /&gt;&lt;/p&gt;
&lt;h5&gt;Irssi&lt;/h5&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;servers = (&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; address = &amp;quot;my-proxy-host.com&amp;quot;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; chatnet = &amp;quot;Proxy&amp;quot;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; port = &amp;quot;7778&amp;quot;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; password = &amp;quot;joel:myHashedPassword:freenode&amp;quot;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; autoconnect = &amp;quot;yes&amp;quot;;&lt;br /&gt;
&amp;nbsp; }&lt;/div&gt;&lt;/div&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;And that&amp;#8217;s it! We are now perpetually connected to IRC, and can connect to our proxy using an unlimited number of devices in a completely transparent and seamless manner. Moreover, the logs for all channels that we are connected to are saved and automatically rotated on our remote server, making for an easy to maintain archive in the absence of another external channel logging mechanism. Additionally, we can now generate an OpenSSL certificate for our remote server, and configure bip as well as our local clients to communicate with our proxy over a secured connection. This, along with many other features and options that I did not cover, are all documented in the &lt;em&gt;README&lt;/em&gt; and man pages that are installed alongside the bip binary; Please take a look for more information on using bip to it&amp;#8217;s full potential.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/nerderati/~4/-Bv4vwOQ3dc" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://nerderati.com/2010/11/perpetual-irc-the-proxy-edition/#comments" thr:count="3" />
		<link rel="replies" type="application/atom+xml" href="http://nerderati.com/2010/11/perpetual-irc-the-proxy-edition/feed/atom/" thr:count="3" />
		<thr:total>3</thr:total>
	<feedburner:origLink>http://nerderati.com/2010/11/perpetual-irc-the-proxy-edition/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>jperras</name>
						<uri>http://nerderati.com</uri>
					</author>
		<title type="html"><![CDATA[Perpetual IRC &#8211; The Multiplexer Edition]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nerderati/~3/v8vswgLuF0A/" />
		<id>http://nerderati.com/?p=401</id>
		<updated>2010-09-07T15:04:35Z</updated>
		<published>2010-09-07T15:04:35Z</published>
		<category scheme="http://nerderati.com" term="Programming" />		<summary type="html"><![CDATA[As is the case with most people involved in Open Source, I&#8217;m on IRC all day long. I can help people from around the world use some of the projects I&#8217;ve helped create, as well as some of the software that I use on a daily basis. Additionally, IRC is also the preferred form of [...]]]></summary>
		<content type="html" xml:base="http://nerderati.com/2010/09/perpetual-irc-the-multiplexer-edition/">&lt;p&gt;As is the case with most people involved in Open Source, I&amp;#8217;m on &lt;a href="http://en.wikipedia.org/wiki/Internet_Relay_Chat"&gt;IRC&lt;/a&gt; all day long. I can help people from around the world use some of the &lt;a href="http://lithify.me/"&gt;projects&lt;/a&gt; I&amp;#8217;ve helped create, as well as &lt;a href="http://cassandra.apache.org/"&gt;some of the&lt;/a&gt; &lt;a href="http://www.mongodb.org/"&gt;software&lt;/a&gt; that I use on a daily basis.&lt;/p&gt;
&lt;p&gt;Additionally, IRC is also the preferred form of group communication for the &lt;a href="http://individualdigital.com/"&gt;company&lt;/a&gt; I work for. One of the major advantages that IRC has over your ‘traditional’ instant messenger clients is that, with a minimum amount of effort and hardware, you can create a setup that will remain perpetually&lt;sup&gt;*&lt;/sup&gt; connected, even when you&amp;#8217;re not online. That means that you can keep logs of conversations, receive messages, catch up on what the current topic of discussion is when starting your day, and still be able to shut down your computer at night if you so choose.&lt;/p&gt;
&lt;p&gt;There are a few ways of achieving the status of perpetual IRC denizen. Note, however, that almost any method requires that you have access to a remote server in addition to your local machine. It doesn&amp;#8217;t need to be anything special &amp;#8211; a cheap VPS will do just fine, as long as you can install software packages and open the necessary ports in the firewall.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Simplest.&lt;/strong&gt; If you want to expend the least amount of effort, at the cost of some flexibility, the easiest method of achieving IRC immortality is with the use of a &lt;em&gt;terminal multiplexer&lt;/em&gt;, such as &lt;a href="http://www.bangmoney.org/presentations/screen.html"&gt;screen&lt;/a&gt; or &lt;a href="http://tmux.sourceforge.net/"&gt;tmux&lt;/a&gt; (my personal favourite), and a console-based IRC client, such as &lt;a href="http://www.irssi.org/"&gt;Irssi&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t know what a terminal multiplexer is? Here&amp;#8217;s a description, right from the &lt;strong&gt;screen&lt;/strong&gt; homepage:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Screen is a terminal multiplexer: it takes many different running processes and manages which of them gets displayed to the user. Think of it as a window manager for your console or terminal emulator. With screen, you can have interactive processes running on your home computer and connect to them from anywhere else to check on their progress.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s assume that you&amp;#8217;ve installed &lt;strong&gt;screen&lt;/strong&gt; and &lt;strong&gt;Irssi&lt;/strong&gt; on your remote server. What we want to do is start Irssi &lt;em&gt;inside&lt;/em&gt; a screen session:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;screen&lt;/span&gt; &lt;span style="color: #660033;"&gt;-S&lt;/span&gt; irc irssi &lt;span style="color: #666666; font-style: italic;"&gt;# name the session `irc` and start `irssi` in it&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Digression.&lt;/strong&gt; At this point, feel free to browse the &lt;a href="http://www.irssi.org/documentation"&gt;documentation&lt;/a&gt; on how to properly setup your preferred servers, channels and other configuration parameters for the IRC client. For a quick test, you can try the following at the Irssi prompt:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;/set nick YourNickName&lt;br /&gt;
/connect irc.freenode.net&lt;br /&gt;
/join #some-interesting-channel&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also automate the process, so that upon startup Irssi will auto-connect to the servers and channels you specify:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;/server add -auto -network Freenode irc.freenode.net 6667&lt;br /&gt;
/network add -nick YourNickName Freenode&lt;br /&gt;
/channel add -auto #some-interesting-channel Freenode&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you have a registered nickname, you can have it auto-identify as well:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;/network add -autosendcmd &amp;quot;/msg nickserv identify your_pasword_here ;wait 2000&amp;quot; Freenode&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And you&amp;#8217;ll probably want to cut down on the noise:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;/ignore #some-interesting-channel ALL -PUBLIC -ACTIONS&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;At this point, you should have a fully functioning IRC client inside of a screen session. You can &lt;em&gt;detach&lt;/em&gt; from the current session by pressing &lt;strong&gt;control-a d&lt;/strong&gt;, and re-attach with:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;screen&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;See where this is going? With this setup, you can simply maintain your IRC connection within a screen session on your remote server. When you want to &amp;#8220;log on&amp;#8221;, you simply SSH into your remote server, &lt;strong&gt;screen -r&lt;/strong&gt;, and voilà! Perpetual IRC.&lt;/p&gt;
&lt;p&gt;This approach, while simple, has some very obvious drawbacks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You must be on a machine that is able to SSH into your remote server.&lt;/li&gt;
&lt;li&gt;You are confined to using the command-line IRC client running in the remote session.&lt;/li&gt;
&lt;li&gt;Any scripts that attempt to interact with your &amp;#8216;local&amp;#8217; desktop (e.g. Growl notifications), are painful to setup, if not impossible.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Okay, so it&amp;#8217;s not completely ideal. But it does the job &amp;#8211; as long as your remote screen session remains operational, you&amp;#8217;ll be logged in to IRC.&lt;/p&gt;
&lt;p&gt;In my next post, we&amp;#8217;ll look at how you can achieve the same results, but without any of the aforementioned drawbacks, through the use of a specialized IRC proxy daemon.&lt;/p&gt;
&lt;hr /&gt;
&lt;sup&gt;*&lt;/sup&gt;: Of course, if the remote server running the terminal multiplexer session goes down, it&amp;#8217;s not really ‘perpetual’.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/nerderati/~4/v8vswgLuF0A" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://nerderati.com/2010/09/perpetual-irc-the-multiplexer-edition/#comments" thr:count="4" />
		<link rel="replies" type="application/atom+xml" href="http://nerderati.com/2010/09/perpetual-irc-the-multiplexer-edition/feed/atom/" thr:count="4" />
		<thr:total>4</thr:total>
	<feedburner:origLink>http://nerderati.com/2010/09/perpetual-irc-the-multiplexer-edition/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>jperras</name>
						<uri>http://nerderati.com</uri>
					</author>
		<title type="html"><![CDATA[Making Git Behave]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nerderati/~3/vnZAyhv0Xyk/" />
		<id>http://nerderati.com/?p=307</id>
		<updated>2010-08-04T17:08:03Z</updated>
		<published>2010-07-31T19:51:52Z</published>
		<category scheme="http://nerderati.com" term="Programming" /><category scheme="http://nerderati.com" term="git" /><category scheme="http://nerderati.com" term="project management" /><category scheme="http://nerderati.com" term="scm" />		<summary type="html"><![CDATA[It&#8217;s no secret that I&#8217;m a big fan of Git, and of distributed version control in general; they offer a compelling toolset and degree of flexibility that you would be hard pressed to find in a “traditional” centralized version control system. Instead of discussing the merits of a DVCS or performing feature comparisons between particular [...]]]></summary>
		<content type="html" xml:base="http://nerderati.com/2010/07/making-git-behave/">&lt;p&gt;It&amp;#8217;s no secret that I&amp;#8217;m a big fan of &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt;, and of distributed version control in general; they offer a compelling toolset and degree of flexibility that you would be hard pressed to find in a “traditional” centralized version control system. Instead of discussing the merits of a DVCS or performing feature comparisons between particular implementations &amp;#8212; there are enough of those already &amp;#8212; let&amp;#8217;s take a look at how you can bend Git to your will through configuration, and a few useful aliases. If you&amp;#8217;ve not encountered this before, you&amp;#8217;ll be surprised at how much can be accomplished with just a few lines in a configuration file.&lt;/p&gt;
&lt;h3&gt;Your .gitconfig&lt;/h3&gt;
&lt;p&gt;This is where the magic happens. Git, by default, will attempt to find a &lt;strong&gt;.gitconfig&lt;/strong&gt; file in three places: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;$GIT_DIR/config&lt;/strong&gt; for per-repository configurations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;~/.gitconfig&lt;/strong&gt; for user-specific configurations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;$(prefix)/etc/gitconfig&lt;/strong&gt; for system-wide configurations&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;Read up on the various &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-config.html"&gt;options and overrides&lt;/a&gt; that &lt;strong&gt;git-config&lt;/strong&gt; accepts, as well as alternative methods to interactively add/remove/replace configuration options.&lt;/em&gt; &lt;/p&gt;
&lt;p&gt;For the rest of this article we&amp;#8217;ll be adding configurations to &lt;strong&gt;~/.gitconfig&lt;/strong&gt;, but there&amp;#8217;s nothing stopping you from doing it in a per-repository (or even system-wide) configuration file instead.&lt;/p&gt;
&lt;p&gt;For reference, here is a simplified version of the config I use:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;[color]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; diff = auto&lt;br /&gt;
&amp;nbsp; &amp;nbsp; status = auto&lt;br /&gt;
&amp;nbsp; &amp;nbsp; branch = auto&lt;br /&gt;
[user]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; name = Joël Perras&lt;br /&gt;
&amp;nbsp; &amp;nbsp; email = joel.perras@gmail.com&lt;br /&gt;
[status]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; relativePaths = false&lt;br /&gt;
[core]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; excludesfile = /Users/joel/.gitignore&lt;br /&gt;
[alias]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; d &amp;nbsp;= diff&lt;br /&gt;
&amp;nbsp; &amp;nbsp; dc = diff --cached&lt;br /&gt;
&amp;nbsp; &amp;nbsp; lc = log ORIG_HEAD.. --stat --no-merges&lt;br /&gt;
&amp;nbsp; &amp;nbsp; gl = log --oneline --decorate --stat --graph&lt;br /&gt;
&amp;nbsp; &amp;nbsp; st = status -sb&lt;br /&gt;
&amp;nbsp; &amp;nbsp; prune-all = !git remote | xargs -n 1 git remote prune&lt;br /&gt;
&amp;nbsp; &amp;nbsp; whatis = show -s --pretty='tformat:%h (%s, %ad)' --date=short&lt;br /&gt;
&amp;nbsp; &amp;nbsp; whois = &amp;quot;!sh -c 'git log -i -1 --pretty=\&amp;quot;format:%an &amp;lt;%ae&amp;gt;\n\&amp;quot; --author=\&amp;quot;$1\&amp;quot;' -&amp;quot;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Also available as a &lt;a href="http://gist.github.com/502434"&gt;Gist&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now let&amp;#8217;s go through what these configuration options actually do.&lt;/p&gt;
&lt;h4&gt;[color]&lt;/h4&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;[color]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; diff = auto&lt;br /&gt;
&amp;nbsp; &amp;nbsp; status = auto&lt;br /&gt;
&amp;nbsp; &amp;nbsp; branch = auto&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;These were, in all likelihood, the first configuration options I setup once I had installed Git for the first time. I work in a terminal window all day, and having proper and consistent colourization makes all the difference when attempting to quickly determine the state of your repository:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://static.nerderati.com/wp-content/uploads/2010/07/joel@Nibbler_-120x20-ttys000-—-⌘1-2.jpg"&gt;&lt;img src="http://static.nerderati.com/wp-content/uploads/2010/07/joel@Nibbler_-120x20-ttys000-—-⌘1-2.jpg" alt="Colourized git status output" width="500px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With these options set, all &lt;strong&gt;diff&lt;/strong&gt;, &lt;strong&gt;status&lt;/strong&gt; and &lt;strong&gt;branch&lt;/strong&gt; commands will have (where appropriate) colourized output.&lt;/p&gt;
&lt;h4&gt;[user]&lt;/h4&gt;
&lt;p&gt;If you ever plan on making your repository available to other developers, these options are essential for identifying who you are. They&amp;#8217;re pretty self-explanatory:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;[user]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; name = Joël Perras&lt;br /&gt;
&amp;nbsp; &amp;nbsp; email = joel.perras@gmail.com&lt;/div&gt;&lt;/div&gt;
&lt;h4&gt;[status]&lt;/h4&gt;
&lt;p&gt;The sole configuration I have under this segment is something of a personal preference. When I&amp;#8217;m four folders deep into a repository and I invoke &lt;strong&gt;git status&lt;/strong&gt;, I don&amp;#8217;t need to see where the changed/added/deleted files are relative to where I invoked the command &amp;#8212; I&amp;#8217;m far more interested in their &lt;em&gt;absolute location relative to the repository root&lt;/em&gt;. That&amp;#8217;s where &lt;strong&gt;relativePaths = false&lt;/strong&gt; comes in handy:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;[status]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; relativePaths = false&lt;/div&gt;&lt;/div&gt;
&lt;h4&gt;[core]&lt;/h4&gt;
&lt;p&gt;There are some files you just never want to commit, no matter what project you&amp;#8217;re working on. As an avid &lt;a href="http://www.vim.org/"&gt;Vim&lt;/a&gt; user, I sometimes have a few &lt;strong&gt;*.swp&lt;/strong&gt; files lying around (mostly due to my own fault), which have no place in any project history. Instead of adding an ignore rule to each and every repository, I added this configuration directive to my &lt;strong&gt;~/.gitconfig&lt;/strong&gt;, indicating where my global never-track-any-of-these-file-patterns exists:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;[core]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; excludesfile = /Users/joel/.gitignore&lt;/div&gt;&lt;/div&gt;
&lt;h4&gt;[alias]&lt;/h4&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Now we get to the interesting stuff. Aliases in Git are exactly what you expect them to be: user-defined shortcuts that group together pre-existing git (and sometimes shell) commands and their options.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; As some people have pointed out, there are a few flags/commands that will &lt;em&gt;not&lt;/em&gt; work unless you have git 1.7.2 or above installed. Pardon the confusion.&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;[alias]&lt;br /&gt;
&amp;nbsp; &amp;nbsp; d &amp;nbsp;= diff&lt;br /&gt;
&amp;nbsp; &amp;nbsp; dc = diff --cached&lt;br /&gt;
&amp;nbsp; &amp;nbsp; lc = log ORIG_HEAD.. --stat --no-merges&lt;br /&gt;
&amp;nbsp; &amp;nbsp; gl = log --oneline --decorate --stat --graph&lt;br /&gt;
&amp;nbsp; &amp;nbsp; st = status -sb&lt;br /&gt;
&amp;nbsp; &amp;nbsp; serve = !git daemon --reuseaddr --verbose &amp;nbsp;--base-path=. --export-all ./.git&lt;br /&gt;
&amp;nbsp; &amp;nbsp; prune-all = !git remote | xargs -n 1 git remote prune&lt;br /&gt;
&amp;nbsp; &amp;nbsp; whatis = show -s --pretty='tformat:%h (%s, %ad)' --date=short&lt;br /&gt;
&amp;nbsp; &amp;nbsp; whois = &amp;quot;!sh -c 'git log -i -1 --pretty=\&amp;quot;format:%an &amp;lt;%ae&amp;gt;\n\&amp;quot; --author=\&amp;quot;$1\&amp;quot;' -&amp;quot;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Some explanations:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;strong&gt;git d&lt;/strong&gt; and &lt;strong&gt;git dc&lt;/strong&gt;&lt;/p&gt;
&lt;dd&gt;I&amp;#8217;m often taking diffs between different revisions in projects, so these two are quite heavily used.&lt;/p&gt;
&lt;dt&gt;&lt;strong&gt;git lc&lt;/strong&gt;&lt;/p&gt;
&lt;dd&gt;Lists all new commits after you fetched. This is especially useful when working on a very active project with multiple developers.&lt;/p&gt;
&lt;dt&gt;&lt;strong&gt;git gl&lt;/strong&gt;&lt;/p&gt;
&lt;dd&gt;This is the default command that I invoke when I wish to inspect the log. The output is concise as well as informative:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://static.nerderati.com/wp-content/uploads/2010/07/joel@Nibbler_-120x20-ttys000-—-⌘1.jpg"&gt;&lt;img src="http://static.nerderati.com/wp-content/uploads/2010/07/joel@Nibbler_-120x20-ttys000-—-⌘1.jpg" alt="Git formatted log output" width="500px"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;dt&gt;&lt;strong&gt;git st&lt;/strong&gt;&lt;/p&gt;
&lt;dd&gt;My preferred method of viewing the status of a repository, which gets rid of the fluff that usually accompanies the help-type text of &lt;strong&gt;git status&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://static.nerderati.com/wp-content/uploads/2010/07/joel@Nibbler_-120x20-ttys000-—-⌘1-1.jpg"&gt;&lt;img src="http://static.nerderati.com/wp-content/uploads/2010/07/joel@Nibbler_-120x20-ttys000-—-⌘1-1.jpg" alt="Formatted git status output" width="500px"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;dt&gt;&lt;strong&gt;git prune-all&lt;/strong&gt;&lt;/p&gt;
&lt;dd&gt;Since &lt;strong&gt;git remote prune&lt;/strong&gt; doesn&amp;#8217;t know how to prune all of your remotes at once, let&amp;#8217;s teach it that trick. This is especially useful if you&amp;#8217;re tracking many remotes from various contributors to a project where the branches get nuked/renamed on a regular basis.&lt;/p&gt;
&lt;dt&gt;&lt;strong&gt;git whatis &amp;lt;commit-ish&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;dd&gt;Pass this command a hash, branch name or tag, and it will give you a one-liner containing the commit message associated to it as well as the date it was committed on. Useful when &lt;strong&gt;git show&lt;/strong&gt; is more information than you need.&lt;/p&gt;
&lt;dt&gt;&lt;strong&gt;git whois &amp;lt;name|email&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;dd&gt;Another one of those useful commands when you&amp;#8217;re working on a project with a multitude of collaborators, and need to fish out an email address when all you remember is part of their name, or vice versa. Note that if the collaborator in question never configured their name and/or email address (as described above), then this command will not be very useful.
&lt;/dl&gt;
&lt;p&gt;And that&amp;#8217;s it! With nothing more than a few lines in a configuration file, we&amp;#8217;ve managed to make Git be more informative as well as more concise. &lt;/p&gt;
&lt;p&gt;If you have any tips/tricks/configs that you can&amp;#8217;t live without, leave a comment below.&lt;/p&gt;
&lt;hr /&gt;
Quite a few of the aliases and what I would consider &amp;#8220;sane&amp;#8221; configuration options have been lifted from the &lt;a href="https://git.wiki.kernel.org/index.php/Aliases"&gt;official wiki&lt;/a&gt; for Git. I highly recommend perusing it, once you&amp;#8217;ve become familiar with Git itself.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/nerderati/~4/vnZAyhv0Xyk" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://nerderati.com/2010/07/making-git-behave/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://nerderati.com/2010/07/making-git-behave/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	<feedburner:origLink>http://nerderati.com/2010/07/making-git-behave/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>jperras</name>
						<uri>http://nerderati.com</uri>
					</author>
		<title type="html"><![CDATA[Compiling Vim With Ruby Integration On Snow Leopard]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nerderati/~3/Ki8t8y0Slvw/" />
		<id>http://nerderati.com/?p=247</id>
		<updated>2010-08-24T13:51:17Z</updated>
		<published>2010-07-26T04:48:54Z</published>
		<category scheme="http://nerderati.com" term="Programming" /><category scheme="http://nerderati.com" term="autotools" /><category scheme="http://nerderati.com" term="compiling" /><category scheme="http://nerderati.com" term="editor" /><category scheme="http://nerderati.com" term="mercurial" /><category scheme="http://nerderati.com" term="ruby" /><category scheme="http://nerderati.com" term="vim" />		<summary type="html"><![CDATA[One of my favourite plugins for Vim is <a href="https://wincent.com/products/command-t/">Command-T</a>: <blockquote>an extremely fast, intuitive mechanism for opening files with a minimal number of keystrokes. It's named "Command-T" because it is inspired by the "Go to File" window bound to Command-T in TextMate.</blockquote>

Sadly, the default installation of Vim on Snow Leopard does <em>not</em> have support for the ruby interpreter compiled in, which is a pre-requisite for using the Command-T plugin. Luckily, that's easy enough to remedy, and in the process we'll learn a thing or two about compiling your own custom Vim binary.]]></summary>
		<content type="html" xml:base="http://nerderati.com/2010/07/compiling-vim-with-ruby-integration-on-snow-leopard/">&lt;p&gt;One of my favourite plugins for Vim is &lt;a href="https://wincent.com/products/command-t/"&gt;Command-T&lt;/a&gt;:&lt;br /&gt;
&lt;blockquote&gt;an extremely fast, intuitive mechanism for opening files with a minimal number of keystrokes. It&amp;#8217;s named &amp;#8220;Command-T&amp;#8221; because it is inspired by the &amp;#8220;Go to File&amp;#8221; window bound to Command-T in TextMate.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Sadly, the default installation of Vim on Snow Leopard does &lt;em&gt;not&lt;/em&gt; have support for the ruby interpreter compiled in, which is a pre-requisite for using the plugin. Luckily, that&amp;#8217;s easy enough to remedy, and in the process we&amp;#8217;ll learn a thing or two about compiling your own custom Vim binary.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s start off by getting the source code from the &lt;a href="http://www.vim.org/mercurial.php"&gt;official Mercurial repository&lt;/a&gt;:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ hg clone https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;vim.googlecode.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;hg&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;vim&lt;/span&gt;&lt;br /&gt;
$ &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;vim&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;(&lt;em&gt;Note: You don&amp;#8217;t need to use the Mercurial repository &amp;#8211; there are mirror sources for Subversion, CVS, as well as good ol&amp;#8217; tarballs with patches.&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;default&lt;/strong&gt; branch for the mercurial repository contains the code for Vim 7.2 at the time of this writing. There is also a &lt;strong&gt;vim73&lt;/strong&gt; branch available for those feeling a bit more adventurous and wishing to compile the beta release of the next version. For this article, we&amp;#8217;ll be sticking to the stable &lt;strong&gt;7.2&lt;/strong&gt; release in the &lt;strong&gt;default&lt;/strong&gt; branch.&lt;/p&gt;
&lt;p&gt;Now, let&amp;#8217;s take a look at the possible configuration options:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;configure &lt;span style="color: #660033;"&gt;--help&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;There are quite a few, and I suggest that you take the time to read through them &amp;#8211; most are quite self-explanatory. For &lt;strong&gt;Command-T&lt;/strong&gt;, the one that we are interested in is the&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;&lt;span style="color: #660033;"&gt;--enable-rubyinterp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;option.&lt;/p&gt;
&lt;p&gt;So let&amp;#8217;s take a shot at the simplest installation for terminal-based Vim usage, one without the GUI interface and (Linux) mouse daemon support:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;configure &lt;span style="color: #660033;"&gt;--prefix&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;my&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;install&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;prefix &lt;span style="color: #660033;"&gt;--enable-rubyinterp&lt;/span&gt; &lt;span style="color: #660033;"&gt;--enable-gui&lt;/span&gt;=no &lt;span style="color: #660033;"&gt;--disable-gpm&lt;/span&gt;&lt;br /&gt;
$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;make&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After the compilation process finishes (presumably with no errors), the first thing you&amp;#8217;ll want to do is ensure that the binary you just built functions as expected:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;vim&lt;/span&gt; &lt;span style="color: #660033;"&gt;--version&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; ruby&lt;br /&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# you should see a `+ruby` line entry&lt;/span&gt;&lt;br /&gt;
$ .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;vim&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you see the &lt;strong&gt;+ruby&lt;/strong&gt; entry in the &lt;strong&gt;&amp;#8211;version&lt;/strong&gt; output and the binary launches without any errors, rejoice in your own awesomeness. That&amp;#8217;s all there is to it.&lt;/p&gt;
&lt;p&gt;If, however, you see something similar to this:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;Vim: Caught deadly signal SEGV&lt;br /&gt;
Vim: Finished.&lt;br /&gt;
&lt;span style="color: #c20cb9; font-weight: bold;"&gt;zsh&lt;/span&gt;: segmentation fault &amp;nbsp;.&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;vim&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;you&amp;#8217;ve probably fallen prey to a (currently) not very well documented issue: Vim 7.2 does &lt;a href="http://groups.google.com/group/vim_dev/browse_thread/thread/a34ba9d02c57af9a/57ab7457327c81d8"&lt;em&gt;not&lt;/em&gt; support the integration of Ruby 1.9.x on Snow Leopard&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This means that if you&amp;#8217;ve used a package manager such as &lt;a href="http://github.com/mxcl/homebrew"&gt;Homebrew&lt;/a&gt;, &lt;a href="http://www.macports.org/"&gt;MacPorts&lt;/a&gt; or &lt;a href="http://www.finkproject.org/"&gt;Fink&lt;/a&gt; (&lt;em&gt;shudder&lt;/em&gt;) to install the latest version of Ruby, Vim will link to that latest version instead of the system default installation of ruby &lt;strong&gt;1.8.7&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s fix that.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re going to edit the &lt;strong&gt;src/auto/config.mk&lt;/strong&gt; generated by &lt;/strong&gt;configure&lt;/strong&gt; that was run earlier.  &lt;em&gt;Note that if you re-run &lt;strong&gt;configure&lt;/strong&gt; at a later time, your changes to &lt;strong&gt;config.mk&lt;/strong&gt; will be lost.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Find the lines that look like this:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;RUBY &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ruby&lt;br /&gt;
RUBY_SRC &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= if_ruby.c&lt;br /&gt;
RUBY_OBJ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= objects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;if_ruby.o&lt;br /&gt;
RUBY_PRO &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= if_ruby.pro&lt;br /&gt;
RUBY_CFLAGS &amp;nbsp; &amp;nbsp; = -I&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Cellar&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ruby&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;1.9.1-p378&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;include&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ruby-1.9.1 -I&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Cellar&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ruby&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;1.9.1-p378&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;include&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ruby-1.9.1&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;i386-darwin10.4.0 -DRUBY_VERSION=&lt;span style="color: #000000;"&gt;19&lt;/span&gt;&lt;br /&gt;
RUBY_LIBS &amp;nbsp; &amp;nbsp; &amp;nbsp; = &lt;span style="color: #660033;"&gt;-lruby&lt;/span&gt; &lt;span style="color: #660033;"&gt;-lpthread&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ldl&lt;/span&gt; &lt;span style="color: #660033;"&gt;-lobjc&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;(&lt;em&gt;Note: Your specific paths and/or versions may differ depending on the package manager that you are using. The above paths are actually not important, however, since we actually want to reset them to the system defaults.&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;and replace them with the following:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;RUBY &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ruby&lt;br /&gt;
RUBY_SRC &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= if_ruby.c&lt;br /&gt;
RUBY_OBJ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= objects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;if_ruby.o&lt;br /&gt;
RUBY_PRO &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= if_ruby.pro&lt;br /&gt;
RUBY_CFLAGS &amp;nbsp; &amp;nbsp; = -I&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;System&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Library&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Frameworks&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Ruby.framework&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Versions&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;1.8&lt;/span&gt; -I&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ruby&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;1.8&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;universal-darwin10.0&lt;br /&gt;
RUBY_LIBS &amp;nbsp; &amp;nbsp; &amp;nbsp; = &lt;span style="color: #660033;"&gt;-framework&lt;/span&gt; Ruby&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Alright, let&amp;#8217;s see if this worked.&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;make&lt;/span&gt; clean &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;make&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Before we check the binary as we did before, let&amp;#8217;s see if we linked to the correct ruby libraries:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ otool &lt;span style="color: #660033;"&gt;-L&lt;/span&gt; src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;vim&lt;/span&gt;&lt;br /&gt;
src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;vim&lt;/span&gt;:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;libSystem.B.dylib &lt;span style="color: #7a0874; font-weight: bold;"&gt;&amp;#40;&lt;/span&gt;compatibility version 1.0.0, current version 125.2.0&lt;span style="color: #7a0874; font-weight: bold;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;libncurses.5.4.dylib &lt;span style="color: #7a0874; font-weight: bold;"&gt;&amp;#40;&lt;/span&gt;compatibility version 5.4.0, current version 5.4.0&lt;span style="color: #7a0874; font-weight: bold;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;System&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Library&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Frameworks&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Ruby.framework&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Versions&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;1.8&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;libruby.1.dylib &lt;span style="color: #7a0874; font-weight: bold;"&gt;&amp;#40;&lt;/span&gt;compatibility version 1.8.0, current version 1.8.7&lt;span style="color: #7a0874; font-weight: bold;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;System&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Library&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Frameworks&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;CoreServices.framework&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Versions&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;A&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;CoreServices &lt;span style="color: #7a0874; font-weight: bold;"&gt;&amp;#40;&lt;/span&gt;compatibility version 1.0.0, current version 44.0.0&lt;span style="color: #7a0874; font-weight: bold;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;System&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Library&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Frameworks&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;CoreFoundation.framework&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Versions&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;A&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;CoreFoundation &lt;span style="color: #7a0874; font-weight: bold;"&gt;&amp;#40;&lt;/span&gt;compatibility version 150.0.0, current version 550.29.0&lt;span style="color: #7a0874; font-weight: bold;"&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Looking good so far &amp;#8211; the binary is linked to the framework version of Ruby that comes as a default on Snow Leopard.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s do a version check:&lt;/p&gt;
&lt;div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;vim&lt;/span&gt; &lt;span style="color: #660033;"&gt;--version&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; ruby&lt;br /&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# you should see a `+ruby` line entry&lt;/span&gt;&lt;br /&gt;
$ .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;vim&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And voilà: A custom-built Vim with ruby integration that will happily run the &lt;a href="https://wincent.com/products/command-t/"&gt;Command-T&lt;/a&gt; plugin. &lt;/p&gt;
&lt;p&gt;All that&amp;#8217;s left is to install it:&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;$ make install&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Assuming your &lt;strong&gt;PATH&lt;/strong&gt; is setup to correctly find the new Vim binary, you should be all set.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/nerderati/~4/Ki8t8y0Slvw" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://nerderati.com/2010/07/compiling-vim-with-ruby-integration-on-snow-leopard/#comments" thr:count="14" />
		<link rel="replies" type="application/atom+xml" href="http://nerderati.com/2010/07/compiling-vim-with-ruby-integration-on-snow-leopard/feed/atom/" thr:count="14" />
		<thr:total>14</thr:total>
	<feedburner:origLink>http://nerderati.com/2010/07/compiling-vim-with-ruby-integration-on-snow-leopard/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>jperras</name>
						<uri>http://nerderati.com</uri>
					</author>
		<title type="html"><![CDATA[WebNotWar]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nerderati/~3/h-swq9LsAz8/" />
		<id>http://nerderati.com/?p=241</id>
		<updated>2010-05-20T21:41:30Z</updated>
		<published>2010-05-20T21:41:30Z</published>
		<category scheme="http://nerderati.com" term="Programming" />		<summary type="html"><![CDATA[I&#8217;m quite happy to announce that I will be giving the keynote address at this year&#8217;s WebNotWar/For The Web conference, taking place on May 27th, 2010. First, it&#8217;s a free conference for attendees. Being an open-source kinda guy, I know &#038; love the word free. Second, the theme of the conference is &#8216;interoperability&#8217;, which is [...]]]></summary>
		<content type="html" xml:base="http://nerderati.com/2010/05/webnotwar/">&lt;p&gt;I&amp;#8217;m quite happy to announce that I will be giving the keynote address at this year&amp;#8217;s &lt;a href="http://www.webnotwar.ca/"&gt;WebNotWar/For The Web&lt;/a&gt; conference, taking place on May 27th, 2010.&lt;/p&gt;
&lt;p&gt;First, it&amp;#8217;s a free conference for attendees. Being an open-source kinda guy, I know &amp;#038; love the word &lt;em&gt;free&lt;/em&gt;. Second, the theme of the conference is &amp;#8216;interoperability&amp;#8217;, which is something very important to me, to my open source work, to my job, and to end users (I like to call them &amp;#8216;normies&amp;#8217;) &amp;#8211; so much so that my keynote will address this directly.&lt;/p&gt;
&lt;p&gt;The technological landscape of the web is diverse, and keeping track of new developments and projects is a full time job. Luckily, conferences like this one provide a great way to meet the people that make the web of tomorrow, and get a head start on what the next Big Thing is going to be.&lt;/p&gt;
&lt;p&gt;I hope to see you there!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/nerderati/~4/h-swq9LsAz8" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://nerderati.com/2010/05/webnotwar/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://nerderati.com/2010/05/webnotwar/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	<feedburner:origLink>http://nerderati.com/2010/05/webnotwar/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>jperras</name>
						<uri>http://nerderati.com</uri>
					</author>
		<title type="html"><![CDATA[Suggested Reading]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nerderati/~3/W-hwu_qGqdM/" />
		<id>http://nerderati.com/?p=229</id>
		<updated>2010-05-04T15:37:45Z</updated>
		<published>2010-05-04T15:36:05Z</published>
		<category scheme="http://nerderati.com" term="Nerdy" />		<summary type="html"><![CDATA[Some books that I think every self-respecting nerd should read.]]></summary>
		<content type="html" xml:base="http://nerderati.com/2010/05/suggested-reading/">&lt;p&gt;Some books that I think every self-respecting nerd should read:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Feynmans-Rainbow-Search-Beauty-Physics/dp/044653045X"&gt;Feynman&amp;#8217;s Rainbow&lt;/a&gt;, by Leonard Mlodinow.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Short-History-Nearly-Everything/dp/076790818X/ref=sr_1_1?ie=UTF8&amp;#038;s=books&amp;#038;qid=1272986930&amp;#038;sr=1-1"&gt;A Short History of Nearly Everything&lt;/a&gt; by Bill Bryson.&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://store.xkcd.com/xkcd/#xkcdvolume0"&gt;XKCD: Volume 0&lt;/a&gt; book.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Foundation-Novels-Isaac-Asimov/dp/0553382578/ref=sr_1_1?ie=UTF8&amp;#038;s=books&amp;#038;qid=1272986323&amp;#038;sr=1-1"&gt;The Foundation series&lt;/a&gt; by Isaac Asimov. Quite possibly the best  science-fiction series that has ever been written.&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://www.amazon.com/Revelation-Space-Alastair-Reynolds/dp/0441009425"&gt;Revelation Space&lt;/a&gt; series by Alastair Reynolds. If you enjoy &amp;#8220;hard&amp;#8221; sci-fi, then you&amp;#8217;ll love this series.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Yes, these are heavily science/physics/sci-fi biased, but would you expect anything different from someone like me?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: There are no affiliate codes attached to these links. I&amp;#8217;m not that much of a cheapskate.&lt;/em&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/nerderati/~4/W-hwu_qGqdM" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://nerderati.com/2010/05/suggested-reading/#comments" thr:count="2" />
		<link rel="replies" type="application/atom+xml" href="http://nerderati.com/2010/05/suggested-reading/feed/atom/" thr:count="2" />
		<thr:total>2</thr:total>
	<feedburner:origLink>http://nerderati.com/2010/05/suggested-reading/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>jperras</name>
						<uri>http://nerderati.com</uri>
					</author>
		<title type="html"><![CDATA[The Wonders and Simplicity of Redis Sets]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nerderati/~3/y2LLEsEQmyA/" />
		<id>http://nerderati.com/?p=199</id>
		<updated>2010-02-26T18:22:05Z</updated>
		<published>2010-02-26T18:21:18Z</published>
		<category scheme="http://nerderati.com" term="Programming" /><category scheme="http://nerderati.com" term="python" /><category scheme="http://nerderati.com" term="redis" />		<summary type="html"><![CDATA[If you were to apply a bijective function to each letter in each word of a language (e.g. English), how many pre-existing words would you obtain in the resulting image? Since that&#8217;s a pretty convoluted way of explaining things, let&#8217;s try a more concrete example. We&#8217;ll take the well-known rot13 substitution cipher (a simple example [...]]]></summary>
		<content type="html" xml:base="http://nerderati.com/2010/02/the-wonders-and-simplicity-of-redis-sets/">&lt;p&gt;If you were to apply a bijective function to each letter in each word of a language (e.g. English), how many pre-existing words would you obtain in the resulting image?&lt;/p&gt;
&lt;p&gt;Since that&amp;#8217;s a pretty convoluted way of explaining things, let&amp;#8217;s try a more concrete example. &lt;/p&gt;
&lt;p&gt;We&amp;#8217;ll take the well-known&lt;/p&gt;
&lt;div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"&gt;&lt;div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"&gt;rot13&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;substitution cipher (a simple example of a bijection between the set of letters in the English alphabet and itself), and apply it to every letter in a chosen word. For most words, the result will be non-sensical gibberish. There does exist, however, a subset of valid English words that map into other valid English words.&lt;/p&gt;
&lt;p&gt;Example:
&lt;pre&gt;rot13('sync') = 'flap'&lt;/pre&gt;
&lt;p&gt;How many of these words exist? To answer this, I wrote a small Python script that loads up the words in my system dictionary into a Redis set. Another set of the rot13&amp;#8242;ed words is then stored, and the set intersection of the original and transformed words is calculated:&lt;/p&gt;
&lt;script src="http://gist.github.com/311857.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;code class="gist"&gt;&lt;pre&gt;&lt;br /&gt;
import redis&lt;/p&gt;
&lt;p&gt;def encode(word):&lt;br /&gt;
    return word.encode(&amp;#8216;rot13&amp;#8242;)&lt;/p&gt;
&lt;p&gt;def cleanup():&lt;br /&gt;
    db.delete(&amp;#8216;eng&amp;#8217;)&lt;br /&gt;
    db.delete(&amp;#8216;eng-rot13&amp;#8242;)&lt;/p&gt;
&lt;p&gt;if __name__ == &amp;#8220;__main__&amp;#8221;:&lt;br /&gt;
    count = 0&lt;br /&gt;
    db = redis.Redis()&lt;br /&gt;
    cleanup()&lt;/p&gt;
&lt;p&gt;    for line in open(&amp;#8216;/usr/share/dict/words&amp;#8217;, &amp;#8216;r&amp;#8217;):&lt;br /&gt;
        count += 1&lt;br /&gt;
        db.sadd(&amp;#8216;eng&amp;#8217;, line)&lt;br /&gt;
        db.sadd(&amp;#8216;eng-rot13&amp;#8242;, encode(line))&lt;br /&gt;
        if (count % 10000 == 0):&lt;br /&gt;
            print &amp;#8220;Loaded %d words so far&amp;#8221; % count&lt;/p&gt;
&lt;p&gt;    db.sinterstore(&amp;#8216;eng-intersect&amp;#8217;, &amp;#8216;eng&amp;#8217;, &amp;#8216;eng-rot13&amp;#8242;)&lt;br /&gt;
    msg = &amp;#8220;English dictionary contains %d words, and %d rot13&amp;#8242;ed words&amp;#8221;&lt;br /&gt;
    print  msg % (db.scard(&amp;#8216;eng&amp;#8217;), db.scard(&amp;#8216;eng-rot13&amp;#8242;))&lt;br /&gt;
    print &amp;#8220;Cardinality of intersection: %d &amp;#8221; % db.scard(&amp;#8216;eng-intersect&amp;#8217;)&lt;br /&gt;
    cleanup()&lt;br /&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/noscript&gt;
&lt;p&gt;After a simple cardinality check, we have our answer: 256 words&lt;sup&gt;&lt;a href="#f1"&gt;[1]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;The great part about this little script is that nearly everything is done natively in Redis &amp;#8211; the only thing Python is needed for is loading the words into the database, and the implementation of the bijective function that we wish to apply.&lt;/p&gt;
&lt;p&gt;This is a very contrived example, but the ease with which I was able to map my thought process to code was fantastic. No need to think about tables, rows or joins &amp;#8211; just sets, and operations on sets. The simplicity of it is almost shocking.&lt;/p&gt;
&lt;p&gt;Pretty neat, eh?&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a name="f1"&gt;[1]&lt;/a&gt; This result does not discard any single letter words (e.g. &amp;#8220;a&amp;#8221;), which will always trivially map into another letter when using rot13.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/nerderati/~4/y2LLEsEQmyA" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://nerderati.com/2010/02/the-wonders-and-simplicity-of-redis-sets/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://nerderati.com/2010/02/the-wonders-and-simplicity-of-redis-sets/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	<feedburner:origLink>http://nerderati.com/2010/02/the-wonders-and-simplicity-of-redis-sets/</feedburner:origLink></entry>
	</feed><!-- Dynamic page generated in 0.573 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-10-20 16:44:25 --><!-- Compression = gzip -->
