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

<channel>
	<title>Kevin&#039;s random thoughts &#187; tech</title>
	<atom:link href="http://kbullock.ringworld.org/category/tech/feed/" rel="self" type="application/rss+xml" />
	<link>http://kbullock.ringworld.org</link>
	<description>god, tech, and other geekery</description>
	<lastBuildDate>Tue, 02 Feb 2010 18:11:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Better bash completion for rake</title>
		<link>http://kbullock.ringworld.org/2009/12/14/better-bash-completion-for-rake/</link>
		<comments>http://kbullock.ringworld.org/2009/12/14/better-bash-completion-for-rake/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 20:55:20 +0000</pubDate>
		<dc:creator>kbullock</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[bash completion]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[completion]]></category>
		<category><![CDATA[rake]]></category>

		<guid isPermaLink="false">http://kbullock.ringworld.org/?p=1462</guid>
		<description><![CDATA[A while ago, I started searching for decent bash completion for rake. At the time I was disappointed by the available solutions, so I hacked together my own and have been steadily improving it since then. It&#8217;s available at gist.github.

I think it still has some advantages over other solutions that have been posted:




It completes long [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago, I started searching for decent <a href="http://freshmeat.net/projects/bashcompletion">bash completion</a> for <a href="http://rake.rubyforge.org/">rake</a>. At the time I was disappointed by the <a href="http://townx.org/blog/elliot/rake-command-completion-bash-shell">available solutions</a>, so I hacked together my own and have been steadily improving it since then. It&#8217;s <a href="http://gist.github.com/184657">available at gist.github</a>.</p>

<p>I think it still has some advantages over other solutions that have been posted:</p>

<p><span id="more-1462"></span></p>

<ul>
<li><p>It completes long options (<code>--trace</code>, <code>--execute-print</code>, etc.).</p></li>
<li><p>It falls back to completing filenames. I find this most useful for running just one set of tests, e.g.:</p>

<pre><code>$ rake test:units TEST=test/unit/<TAB><TAB>
bar_test.rb  foo_test.rb  helpers/</code></pre></li>
<li><p>It handles colons for namespaced tasks correctly, <a href="http://pastie.org/217324">without resorting to</a> <a href="http://github.com/sgruhier/rake_cap_bash_autocomplete">setting COMP_WORDBREAKS globally</a>.</p></li>
<li><p>It doesn&#8217;t <a href="http://onrails.org/articles/2006/08/30/namespaces-and-rake-command-completion">rely on an external script</a>, which means it only has to fire up <strong>one</strong> Ruby interpreter (to run <code>rake</code>) instead of two (to run a Ruby completion script that runs <code>rake</code>).</p></li>
</ul>

<p>It doesn&#8217;t <a href="http://rhnh.net/2008/06/08/rake-tab-completion-with-caching-and-namespace-support">cache the task list</a>, so it still requires a call to <code>rake --tasks</code> on every <code>&lt;TAB&gt;</code>. I may add caching support later.</p>

<p>Here it is for your inspection and enjoyment:</p>

<script src="http://gist.github.com/184657.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://kbullock.ringworld.org/2009/12/14/better-bash-completion-for-rake/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LiveJournal cross-posting</title>
		<link>http://kbullock.ringworld.org/2009/10/09/livejournal-cross-posting/</link>
		<comments>http://kbullock.ringworld.org/2009/10/09/livejournal-cross-posting/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 05:02:08 +0000</pubDate>
		<dc:creator>kbullock</dc:creator>
				<category><![CDATA[life]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[livejournal]]></category>
		<category><![CDATA[meta]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://kbullock-dev.ringworld.org/?p=1374</guid>
		<description><![CDATA[Thrice a-year-and-a-day later, I&#8217;ve gotten my main blog (kbullock.ringworld.org) cross-posting to my LJ. In the process I&#8217;ve migrated it over to WordPress, using these instructions. Thank you intarwebs!

LiveJournal peeps, I&#8217;m back.

Update 10 Oct 2009: Feed URLs are now redirected to their new locations.
]]></description>
			<content:encoded><![CDATA[<p>Thrice a-year-and-a-day <a title="That _other_ blog..." href="http://krbullock.livejournal.com/16201.html">later</a>, I&#8217;ve gotten my main blog (<a href="http://kbullock.ringworld.org/">kbullock.ringworld.org</a>) cross-posting to my LJ. In the process I&#8217;ve migrated it over to WordPress, using <a href="http://jayunit.net/2008/04/16/mephisto-to-wordpress/">these instructions</a>. Thank you intarwebs!</p>

<p>LiveJournal peeps, I&#8217;m back.</p>

<p><strong>Update 10 Oct 2009:</strong> Feed URLs are now redirected to their new locations.</p>
]]></content:encoded>
			<wfw:commentRss>http://kbullock.ringworld.org/2009/10/09/livejournal-cross-posting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Snow Leopard, Fink, and Ruby</title>
		<link>http://kbullock.ringworld.org/2009/09/17/snow-leopard-fink-and-ruby/</link>
		<comments>http://kbullock.ringworld.org/2009/09/17/snow-leopard-fink-and-ruby/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 01:07:00 +0000</pubDate>
		<dc:creator>kbullock</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[64bit]]></category>
		<category><![CDATA[boost]]></category>
		<category><![CDATA[fink]]></category>
		<category><![CDATA[imagemagick]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pango]]></category>
		<category><![CDATA[rmagick]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[snow leopard]]></category>

		<guid isPermaLink="false">/2009/09/19/snow-leopard-fink-and-ruby</guid>
		<description><![CDATA[Here&#8217;s some tips based on my experience trying to get all my fink packages updated and all my gems working again under Snow Leopard. I use /usr/bin/ruby, that is, the Ruby that comes with Snow Leopard, since Apple has (mostly) gotten it right as of Leopard. I also use fink to install my Unixy stuff, [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s some tips based on my experience trying to get all my <a href="http://finkproject.org/">fink</a> packages updated and all my <a href="http://rubygems.org/">gems</a> working again under Snow Leopard. I use <code>/usr/bin/ruby</code>, that is, the Ruby that comes with Snow Leopard, since Apple has (mostly) gotten it right as of Leopard. I also use <a href="http://finkproject.org/">fink</a> to install my Unixy stuff, unlike every other Rubyist I know who all use <a href="http://www.macports.org/">MacPorts</a>. These facts conspired to lead me down a previously untrodden path&mdash;bring the machete, it&#8217;s a thick jungle.</p>

<p><strong>Update:</strong> I&#8217;ve successfully built the <code>mysql</code> gem against MySQL installed via a 64-bit fink as described below. Here&#8217;s the incantation I used:</p>

<pre><code>$ sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- \
    --with-mysql-dir=/sw64
</code></pre>

<pre><code>        &lt;span id="more-1373"&gt;&lt;/span&gt;

        &lt;h3&gt;Updating Fink&lt;/h3&gt;
</code></pre>

<p>Since I was upgrading from Leopard, I already had a 32-bit install in /sw. Following the <a href="http://finkproject.org/news/index.php#2009-08-28%20Fink%20on%2010.6.">upgrade instructions</a> made what I already had work again. Updating my installed packages was another matter. Here&#8217;s the issues I ran into on a <code>fink update-all</code>, and how I solved them:</p>

<ol>
<li><p><code>pango1-xft2-ft219</code> ran into some <a href="http://www.mail-archive.com/fink-users@lists.sourceforge.net/msg30693.html">issues with missing .la files</a>. The <a href="http://www.mail-archive.com/fink-users@lists.sourceforge.net/msg30706.html">fix suggested on the fink-users list</a> worked for me, although I can&#8217;t guarantee it won&#8217;t break something later.</p></li>
<li><p><code>boost1.35.nopython</code> passes <code>-Wno-long-double</code> to GCC. The version of GCC in Snow Leopard <a href="http://trac.macports.org/ticket/17788">doesn&#8217;t have that flag</a>, and errors out if you try to use it. I fixed it by copying fink&#8217;s package info (<code>boost1.35.info</code> and <code>boost1.35.patch</code>) to the <code>local/main</code> package tree (<code>/sw/fink/dists/local/main/finkinfo/</code>), and fixing the patch to remove the <code>-Wno-long-double</code> option.</p>

<p>The result is <a href="http://bitbucket.org/krbullock/finkinfo">available on bitbucket</a>. Just copy <code>32bit/boost1.35.*</code> into the aforementioned <code>local/main</code> package tree on your fink install, run <code>fink index</code>, and then <code>fink install boost1.35-nopython</code>.</p></li>
</ol>

<h3>Installing a 64-bit Fink</h3>

<p>Next up was getting my gems, in particular <a href="http://rmagick.rubyforge.org/">RMagick</a>, working with Snow Leopard&#8217;s shiny new 64-bit Ruby. Since it&#8217;s 64-bit, you can&#8217;t build gems against your 32-bit libraries installed through fink. But no matter&mdash;it turns out to be possible (even relatively easy) to set up <em>two</em> fink installs, one 32-bit and one 64-bit. Here&#8217;s how to do it:</p>

<ol>
<li><p>Follow the <a href="http://finkproject.org/news/index.php#2009-08-28%20Fink%20on%2010.6.">instructions from the fink website</a> to bootstrap a 64-bit install into <code>/sw64</code>, <strong>leaving the existing 32-bit install alone.</strong></p></li>
<li><p><strong>Skip</strong> adding <code>. /sw64/bin/init.sh</code> to your login scripts, leaving the 32-bit install as the default. Instead, when you want to use the 64-bit version, execute that line from the terminal. Now just that terminal window will default to 64-bit fink.</p></li>
</ol>

<p>Once I&#8217;d done the above, it was just a matter of running <code>fink install imagemagick</code>, and then <code>sudo gem install RMagick</code>&hellip; oh, but wait, no.</p>

<p>See, RMagick is picky about the <code>configure</code> options you use to build ImageMagick; it doesn&#8217;t work with HDRI support enabled (whatever that is). Fink&#8217;s <code>imagemagick</code> package has it enabled by default, so I again took to customizing the Fink package info and putting it in the <code>local/main</code> repository (in this case at <code>/sw64/fink/dists/local/main/finkinfo/</code>), changing <code>--enable-hdri</code> to <code>--disable-hdri</code>. Once again, the result is <a href="http://bitbucket.org/krbullock/finkinfo">available on bitbucket</a> in <code>64bit/imagemagick*</code>.</p>

<p>So once I&#8217;d finished that, I ran <code>fink index</code> and <code>fink install imagemagick</code> again, and the RMagick gem installed fine. Yay!</p>

<p>My next endeavor will be to try to install a 64-bit MySQL thru fink, but for now I&#8217;ve handled that by installing <a href="http://dev.mysql.com/downloads/mysql/5.1.html">the MySQL 5.1 package from mysql.com</a>.</p>

<p>Also note: I haven&#8217;t tested any X11 apps under fink64 yet. Not installing the fink64 xinitrc might break things horribly.</p>
]]></content:encoded>
			<wfw:commentRss>http://kbullock.ringworld.org/2009/09/17/snow-leopard-fink-and-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mirroring Hg repositories on GitHub</title>
		<link>http://kbullock.ringworld.org/2009/09/16/github-and-hg-git/</link>
		<comments>http://kbullock.ringworld.org/2009/09/16/github-and-hg-git/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 05:51:00 +0000</pubDate>
		<dc:creator>kbullock</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[mercurial]]></category>

		<guid isPermaLink="false">/2009/09/16/github-and-hg-git</guid>
		<description><![CDATA[$ hg push github
pushing to git+ssh://git@github.com/krbullock/vlad-merb.git
importing Hg objects into Git
creating and sending data
    github::refs/tags/rel-2.0.0 =&#62; GIT:521e1f66
    github::refs/heads/master =&#62; GIT:2c352a82
$ _


I&#8217;ve been playing with hg-git for the past couple weeks off-and-on (Abderrahim Kitouni&#8217;s fork&#8212;and so should you). Today I decided to try to use it to provide git mirrors of [...]]]></description>
			<content:encoded><![CDATA[<pre><code>$ hg push github
pushing to git+ssh://git@github.com/krbullock/vlad-merb.git
importing Hg objects into Git
creating and sending data
    github::refs/tags/rel-2.0.0 =&gt; GIT:521e1f66
    github::refs/heads/master =&gt; GIT:2c352a82
$ _
</code></pre>

<p>I&#8217;ve been playing with <a href="http://bitbucket.org/abderrahim/hg-git/">hg-git</a> for the past couple weeks off-and-on (Abderrahim Kitouni&#8217;s fork&mdash;<a href="http://article.gmane.org/gmane.comp.version-control.mercurial.general/15241">and so should you</a>). Today I decided to try to use it to provide <a href="http://github.com/krbullock">git mirrors of my projects</a>. It took a bit of futzing around to figure out how to set it up, but as you can see above, it&#8217;s smooth like buttah. Here&#8217;s how I did it.</p>

<pre><code>        &lt;span id="more-1366"&gt;&lt;/span&gt;

        &lt;ol&gt;
</code></pre>

<p><li><p>Install <code>hg-git</code> (and <a href="http://pypi.python.org/pypi/dulwich/"><code>dulwich</code></a>, which it depends on). In a terminal:</p></p>

<pre><code>$ wget http://samba.org/~jelmer/dulwich/dulwich-0.3.3.tar.gz
$ tar xvzf dulwich-0.3.3.tar.gz
$ (cd dulwich-0.3.3 &amp;&amp; sudo /usr/bin/python setup.py install)


$ wget -O hg-git.tar.gz http://bitbucket.org/abderrahim/hg-git/get/tip.gz
$ (cd /path/to/hgext &amp;&amp; tar xvzf /path/to/download/hg-git.tar.gz)
</code></pre>

<p>Then add <code>hg-git</code> into your <code>~/.hgrc</code>:</p>

<p><pre><code>[extensions]
hg_git = /path/to/hgext/hg-git
</code></pre></li>
<li><p>On GitHub, create a repo for your project.</p></li>
<li><p>Translate the GitHub clone URL, like this:</p></p>

<pre><code>git@github.com:krbullock/vlad-merb.git
</code></pre>

<p>into an <code>hg-git</code>-friendly <code>git+ssh</code> URL, like this:</p>

<p><pre><code>git+ssh://git@github.com/krbullock/vlad-merb.git
</code></pre></li>
<li><p>Put that URL into your Mercurial repository&#8217;s <code>hgrc</code>:</p></p>

<p><pre><code>[paths]
github = git+ssh://git@github.com/krbullock/vlad-merb.git
</code></pre></li>
<li><p>Push to GitHub:</p></p>

<p><pre><code>$ hg push github
</code></pre></li>
</ol></p>

<p>Boom. Done. <img src='http://kbullock.ringworld.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://kbullock.ringworld.org/2009/09/16/github-and-hg-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vlad-merb released</title>
		<link>http://kbullock.ringworld.org/2009/09/06/vlad-merb-released/</link>
		<comments>http://kbullock.ringworld.org/2009/09/06/vlad-merb-released/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 10:47:00 +0000</pubDate>
		<dc:creator>kbullock</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[vlad]]></category>
		<category><![CDATA[vlad-merb]]></category>

		<guid isPermaLink="false">/2009/09/06/vlad-merb-released</guid>
		<description><![CDATA[I&#8217;ve now taken over another bit of code that disappeared from Vlad 2.0.0, namely the Merb support. I expect this plugin will no longer be needed once Rails 3 appears, but until then, all of you deploying Merb apps with Vlad (without Passenger) can have the vlad:start_app and vlad:stop_app tasks back.

Description:

Merb support for Vlad. Prior [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve now taken over another bit of code that disappeared from Vlad 2.0.0, namely the Merb support. I expect this plugin will no longer be needed <a href="http://yehudakatz.com/2008/12/23/rails-and-merb-merge/">once Rails 3 appears</a>, but until then, all of you deploying Merb apps with Vlad (without Passenger) can have the <code>vlad:start_app</code> and <code>vlad:stop_app</code> tasks back.</p>

<p>Description:</p>

<p>Merb support for Vlad. Prior to 2.0.0, Vlad included support to make vlad:start and vlad:stop work with Merb; this plugin adds Merb support back in, and makes it a bit more robust.</p>

<p>Changes:</p>

<h3>2.0.0 / 2009-09-05</h3>

<ul>
<li><p>3 major enhancements</p>

<ul>
<li><p>Birthday!</p></li>
<li><p>Bring Merb support up to speed with recent versions of Merb.</p></li>
<li><p>Add deploy variables to run Merb as another user, and to be able to use
sudo.</p></li>
</ul></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://kbullock.ringworld.org/2009/09/06/vlad-merb-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why git isn&#8217;t better</title>
		<link>http://kbullock.ringworld.org/2009/08/20/why-git-isn-t-better/</link>
		<comments>http://kbullock.ringworld.org/2009/08/20/why-git-isn-t-better/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 02:45:00 +0000</pubDate>
		<dc:creator>kbullock</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[fanboy]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[hg]]></category>

		<guid isPermaLink="false">/2009/10/03/why-git-isn-t-better</guid>
		<description><![CDATA[Scott Chacon should know better than to maintain a site like http://whygitisbetterthanx.com/. He&#8217;s the author of hg-git.

If you&#8217;re not using either Git or Mercurial (hg) (or Bazaar or some other appropriate DVCS), you should be. I prefer hg, but I think git is generally fine. Scott Chacon, however, thinks that git is unquestionably better than [...]]]></description>
			<content:encoded><![CDATA[<p>Scott Chacon should know better than to maintain a site like <a href="http://whygitisbetterthanx.com/">http://whygitisbetterthanx.com/</a>. He&#8217;s the author of <a href="http://hg-git.github.com/">hg-git</a>.</p>

<p>If you&#8217;re not using either <a href="http://git-scm.com/">Git</a> or <a href="http://mercurial.selenic.com/">Mercurial (hg)</a> (or Bazaar or some other appropriate <a href="http://en.wikipedia.org/wiki/Distributed_revision_control"><acronym title="Distributed Version Control System">DVCS</acronym></a>), you should be. I prefer hg, but I think git is generally fine. Scott Chacon, however, thinks that git is unquestionably better than hg, for <a href="http://whygitisbetterthanx.com/#hg">three specific reasons</a> I intend to counter here, with reference to Geoffrey Grosenbach&#8217;s recent <a href="http://nubyonrails.com/articles/five-features-from-mercurial-that-would-make-git-suck-less">post on the matter</a>.</p>

<p><strong>Update 2 Sep 2009:</strong> See <a href="http://stevelosh.com/blog/entry/2009/8/30/a-guide-to-branching-in-mercurial/">this post</a> by Steve Losh for more on the branching issue.</p>

<p><strong>Update 2 Oct 2009:</strong> Scott Chacon <a href="http://schacon.github.com/bitbucket.html">is not an idiot</a> (nor did I mean to even imply that he was!), and has demonstrated his not-idiotness by apologizing &#8220;for being a tool&#8221; (his words).</p>

<pre><code>        &lt;span id="more-1325"&gt;&lt;/span&gt;

        &lt;ol&gt;
</code></pre>

<p><li><p>Cheap Local Branching</p></p>

<p>Really? This is supposed to be an advantage git has over hg? I&#8217;ll just point to the Branches Everywhere section of <a href="http://nubyonrails.com/articles/five-features-from-mercurial-that-would-make-git-suck-less">Geoffrey&#8217;s post:</a>:</p>

<blockquote>
    <p>Mercurial branches are not only easy to make, they are also easy to use! They go everywhere the repository does. You don’t have to worry about tracking branches or weird pushes to get them onto your remote repository. &hellip;</p>

    <p>Once you’re done, close the branch and they disappear.</p>
</blockquote>

<p><p>And that only describes <em>named</em> branches, which you don&#8217;t need to use. Bare clones are (disk-space and wall-time) cheap.</p></li>
<li><p>The Staging Area</p></p>

<p>This one is a great example of git making the common case more complex than the less-frequent case. Most often, when I complete a feature or bugfix, I want to check in all the files I&#8217;ve just been working on. Having to &#8217;stage&#8217; them all gets in the way&mdash;even if it is a single-letter command-line switch.</p>

<p>The case of wanting to check in only some changes in a file is handled nicely by the <a href="http://mercurial.selenic.com/wiki/ShelveExtension">shelve extension</a>. Just shelve the ones you don&#8217;t want to appear in the commit, then unshelve them afterwards. This has the added advantage of avoiding the serious issue that <a href="http://nubyonrails.com/articles/five-features-from-mercurial-that-would-make-git-suck-less">Geoffrey brings up</a>:</p>

<blockquote>
    <p>&hellip; being able to commit just one part of a file &hellip; means you’re committing a changeset that you’ve never used, never run tests against.</p>
</blockquote>

<p><p>If you shelve the unwanted changes instead, you can run your tests against what you&#8217;ll <em>actually be committing.</em></p></li>
<li><p>GitHub</p></p>

<p><a href="http://bitbucket.org/">bitbucket</a>.</p>

<p><p>Yes, it&#8217;s a clone of GitHub for hg. But it also rocks. In particular, Scott&#8217;s claim that &#8220;this type of community is simply not available with any of the other SCMs&#8221; is proven false by bitbucket&#8217;s existence.</p></li>
</ol></p>

<p>I <em>don&#8217;t</em> mean to say that hg is better than git. It has its weaknesses as well&mdash;but these aren&#8217;t them.</p>
]]></content:encoded>
			<wfw:commentRss>http://kbullock.ringworld.org/2009/08/20/why-git-isn-t-better/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vlad-hg released</title>
		<link>http://kbullock.ringworld.org/2009/08/20/vlad-hg-released/</link>
		<comments>http://kbullock.ringworld.org/2009/08/20/vlad-hg-released/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 10:31:00 +0000</pubDate>
		<dc:creator>kbullock</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[vlad]]></category>
		<category><![CDATA[vlad-hg]]></category>

		<guid isPermaLink="false">/2009/08/20/vlad-hg-released</guid>
		<description><![CDATA[Update: vlad-hg is now a part of the hitsquad project, at version 2.0.1. The bump in version is just to switch which project it&#8217;s released through&#8212;no actual changes except to the README.

I&#8217;ve taken over development of Mercurial support for Vlad, and with the latest release (2.0.0), it&#8217;s been split out into a plugin (along with [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Update:</strong> vlad-hg is now a part of the <a href="http://rubyforge.org/projects/hitsquad">hitsquad project</a>, at version 2.0.1. The bump in version is just to switch which project it&#8217;s released through&mdash;no actual changes except to the README.</em></p>

<p>I&#8217;ve taken over development of <a href="http://mercurial.selenic.com/">Mercurial</a> support for <a href="http://rubyhitsquad.com/Vlad_the_Deployer.html">Vlad</a>, and with the <a href="http://blog.zenspider.com/2009/08/vlad-version-200-has-been-rele.html">latest release</a> (2.0.0), it&#8217;s been split out into a plugin (along with <a href="http://blog.zenspider.com/2009/08/vlad-perforce-version-200-has.html">Perforce support</a>, with more to come). So, to get Mercurial support back, just</p>

<pre><code>$ gem install vlad-hg
</code></pre>

<p>and continue to use your existing deployment recipes.</p>

<p>We&#8217;ll likely be moving vlad-hg from its own lonely home into the <a href="http://rubyforge.org/projects/hitsquad">hitsquad RubyForge project</a>, so Vlad and all its plugins will be available from the same location. Stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://kbullock.ringworld.org/2009/08/20/vlad-hg-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Couches, DBs, and pr0n, oh my!</title>
		<link>http://kbullock.ringworld.org/2009/05/01/feminist-ruby/</link>
		<comments>http://kbullock.ringworld.org/2009/05/01/feminist-ruby/#comments</comments>
		<pubDate>Fri, 01 May 2009 21:12:00 +0000</pubDate>
		<dc:creator>kbullock</dc:creator>
				<category><![CDATA[politics]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[feminism]]></category>
		<category><![CDATA[pr0n]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">/2009/05/01/feminist-ruby</guid>
		<description><![CDATA[I work to end violence against women. My part of that movement involves writing Web apps in Ruby. Following suit with Nick Seiger&#8217;s post on the matter, this post is me standing to be counted.

The Ruby community, in my view, should welcome and include everyone who shares the hacker spirit. It should also continue, in [...]]]></description>
			<content:encoded><![CDATA[<p>I work to <a href="http://www.mincava.umn.edu/" title="Minnesota Center Against Violence and Abuse">end violence against women</a>. My part of that movement involves writing <a href="http://rubyonrails.org/">Web</a> <a href="http://merbivore.com/">apps</a> in <a href="http://www.ruby-lang.org/">Ruby</a>. Following suit with <a href="http://blog.nicksieger.com/articles/2009/04/30/stand-and-be-counted">Nick Seiger&#8217;s post</a> on the matter, this post is me standing to be counted.</p>

<p>The Ruby community, in my view, should welcome and include everyone who shares the hacker spirit. It should also continue, in the hacker spirit, to be <strong>edgy, playful, anti-corporate,</strong> and <strong>always in favor of freedom.</strong></p>

<p>All of us being human, sometimes we&#8217;ll be edgy in ways, like the now-infamous CouchDB presentation, that make some members or would-be members of the community <a href="http://www.sarahmei.com/blog/?p=46">feel starkly unwelcome</a>. When that happens, those of us who notice it should absolutely call it out, and I, like Nick, pledge myself to do so. Those of us who make the mistakes should learn from them, and I think Matt Aimonetti is doing so. (I&#8217;m not sure that DHH gets it yet.)</p>

<pre><code>        &lt;span id="more-1146"&gt;&lt;/span&gt;

        &lt;p&gt;I won't summarize or analyze the specific issue with Matt's slides (Martin Fowler has &lt;a href="http://martinfowler.com/bliki/SmutOnRails.html"&gt;done a good job of that already&lt;/a&gt;, q.v., and quoted below), except to say this: the &lt;strong&gt;effect&lt;/strong&gt; was that the pictures used, in the context of a room full of a hundred or more men and six women, reinforced some really icky cultural norms about power dynamics between men and women. &lt;strong&gt;It wasn't intentional,&lt;/strong&gt; but it was real. From an anti-sexual-violence perspective, those are the same norms that, in the minds of some, make rape &lt;a href="http://www.nytimes.com/2009/04/30/opinion/30kristof.html"&gt;not a serious enough crime to bother processing the evidence&lt;/a&gt;.&lt;/p&gt;
</code></pre>

<p>I say that to underscore the seriousness of the matter. I <strong>don&#8217;t</strong> say it to demonize Matt Aimonetti (or DHH). Any of us could have misjudged the interaction of imagery and context as Matt did, and the effect could&#8217;ve been racist, classist, homophobic or any number of other things instead of sexist (<strong>the effect</strong>, not the presenter). How we handle it as fellow members of a community sets the tone going forward:</p>

<blockquote>
    <p>How about a community where women are valued for their ability to program and not by the thickness of their skin? How about a community that edgily pushes new boundaries without reinforcing long running evils? Perhaps even a community where women reach equal numbers?
    &mdash;<a href="http://martinfowler.com/bliki/SmutOnRails.html">Martin Fowler</a></p>
</blockquote>

<p>Although the presentation in question makes me sad, I&#8217;m frankly thrilled at the discussion that it&#8217;s sparked and how it&#8217;s been conducted. I&#8217;m glad to see other men in the community <a href="http://hackety.org/2009/04/29/aSelectionOfThoughtsFromActualWomen.html">listening to what women are saying about it</a>, understanding, and responding. (Incidentally, why don&#8217;t I regularly read any women Rubyists&#8217; blogs?) Most of the dialog across Twitter and blogs has been pretty constructive. Some conflict and defensiveness notwithstanding, as a self-identified feminist, I&#8217;m pretty proud of the Ruby community.</p>
]]></content:encoded>
			<wfw:commentRss>http://kbullock.ringworld.org/2009/05/01/feminist-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On rebasing</title>
		<link>http://kbullock.ringworld.org/2009/04/24/on-rebasing/</link>
		<comments>http://kbullock.ringworld.org/2009/04/24/on-rebasing/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 23:02:00 +0000</pubDate>
		<dc:creator>kbullock</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[rebase]]></category>
		<category><![CDATA[scm]]></category>
		<category><![CDATA[vcs]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">/2009/04/30/on-rebasing</guid>
		<description><![CDATA[Let&#8217;s start by setting up a straw man: Git&#8217;s rebase gives it an inherent advantage over Mercurial.

I&#8217;ve become a regular Mercurial user in the past year, whereas I&#8217;ve only dabbled in Git, mostly when contributing to other projects. Most of the Ruby Web development world (i.e. Rails, etc.), on the other hand, has switched full-bore [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s start by setting up a straw man: <a href="http://git-scm.com/">Git</a>&#8217;s <code>rebase</code> gives it an inherent advantage over <a href="http://www.selenic.com/mercurial/">Mercurial</a>.</p>

<p>I&#8217;ve become a regular Mercurial user in the past year, whereas I&#8217;ve only dabbled in Git, mostly when contributing to other projects. Most of the Ruby Web development world (i.e. Rails, <a href="http://www.juixe.com/techknow/index.php/2008/04/14/ruby-web-frameworks/">etc.</a>), on the other hand, has switched full-bore to Git. Advocates of git sing the virtues of the branch-implement-rebase workflow; its detractors <a href="http://changelog.complete.org/archives/586-rebase-considered-harmful">proclaim rebase harmful</a>.</p>

<p>Rather than waste bits talking Git down or making apologia for Mercurial, though, I&#8217;ll describe how I use Mercurial to achieve the same workflows that Git users seem to espouse. I think the Mercurial way is cleaner, but I&#8217;m also pretty sure that we&#8217;re <em>all</em> newbies in the <a href="http://en.wikipedia.org/wiki/Distributed_Version_Control_System">DVCS</a> game.</p>

<p><strong>Update:</strong> There was some <a href="http://markmail.org/thread/7ubjqw7dhsvjps3t">good discussion</a> on the <a href="http://www.selenic.com/mailman/listinfo/mercurial/">Mercurial mailing list</a> about this.</p>

<pre><code>        &lt;span id="more-1135"&gt;&lt;/span&gt;

        &lt;h2&gt;Small topic branches against a changing trunk/master/default&lt;/h2&gt;
</code></pre>

<p>The seemingly most-quoted use of <code>rebase</code> is this: you create a &#8220;topic&#8221; branch, i.e. a short-lived branch to develop a particular feature, and start implementing. Meanwhile, the master branch (or trunk to Subversion users, default branch to Mercurial users) has some changes committed to it that you want to pull in.</p>

<p>Now, when you finally finish implementing your feature, you want to submit a clear, linear patch set upstream. (See <a href="http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html"><code>git-rebase(1)</code></a> for a fuller description.) In Subversion, you would just refrain from committing any changes until your implementation work was finished. In Git, you&#8217;d commit as you go, then rebase your repository against the current master, and then push your changes upstream.</p>

<p>The first thing to do when you have the urge to do this is to ask yourself, do I actually need to push a linear revision history? If you&#8217;re working on a branch to implement more than one feature, or doing a major subsystem rewrite, you should probably just fork off a named branch and let the revision graph make some cross-connects. On the other hand, if you&#8217;re working on a small, quick-to-implement patch that you&#8217;ll submit via e-mail, you probably do want this workflow.</p>

<p>In Mercurial, you would use the <a href="http://www.selenic.com/mercurial/wiki/index.cgi/MqExtension">Mercurial Queues extension</a> (<code>mq</code>, distributed with Mercurial ) to do this. What I do is as follows; for an alternate (probably better) strategy, see <a href="http://www.selenic.com/mercurial/wiki/index.cgi/MqMerge">MqMerge</a> on the Mercurial wiki.</p>

<pre><code># get working copy if we haven't already
$ hg clone http://example.com/upstream/repo

# initialize patch queue
$ hg qinit

# prepare to implement new feature.
# -m gives the commit message to be used.
$ hg qnew -m 'implement feature X' feature_x.patch

(edit/test/etc.)

# update the patch from our changes
$ hg qrefresh

# pop all patches and pull upstream changes
$ hg qpop -a
$ hg pull -u

# push our patches back on top of the updated tree
$ hg push -a
</code></pre>

<p>To me, this is a cleaner solution than rebasing. Using <code>rebase</code>, your local topic branch can&#8217;t be cloned by anyone else, or you&#8217;ll risk corrupting the version history. <code>mq</code> builds in this understanding. It won&#8217;t let you push changes upstream unless you either pop or finish (commit as real changesets) all your patches. Moreover, you can safely let others clone your repository by first popping all patches. They get your clean repository and none of your patches.</p>

<p>If you <em>want</em> to share your patches, you can use <code>hg qinit -c</code> to make the patch queue a repository in its own right. Then others can clone your repository, and then clone your patch queue, to help you test your patches.</p>

<h2>Migrating a topic branch from one upstream branch to another</h2>

<p>A second common use of <code>git rebase</code> is to migrate a set of changes on one branch to another. This is the example for <code>rebase --onto</code> used in <a href="http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html"><code>git-rebase(1)</code></a>.</p>

<p>In Mercurial, you&#8217;d use the <a href="http://www.selenic.com/mercurial/wiki/index.cgi/TransplantExtension"><code>transplant</code> extension</a> (also distributed with Mercurial) to do this. Using the example from <code>git-rebase(1)</code>, say you have this:</p>

<pre><code>o---o---o---o---o  default
     \
      o---o---o---o---o  next
                       \
                        o---o---o  topic
</code></pre>

<p>and you want to move the changesets in the <code>topic</code> branch back onto <code>default</code>. I&#8217;d do this:</p>

<pre><code>$ hg clone http://example.com/upstream/repo
$ hg update default
$ hg transplant --branch topic
</code></pre>

<p>If one of the changesets causes a conflict, <code>transplant</code> will bail out to let you fix the merge by hand. You can then continue the in-progress transplant:</p>

<pre><code>$ hg transplant --continue    # or -c
</code></pre>

<h2>Problems and other cases</h2>

<p>There are some unresolved issues with the above. Using <code>mq</code> requires that you plan your next commit before you start implementing it; I find this to be extra mental overhead that&#8217;s not really necessary. It&#8217;s also not particularly obvious how to collaborate safely on shared patch queues. I think what you&#8217;d end up doing is having patches that alter the effects of previous patches, all stacked together. Since each patch is a commit, this is effectively the same as a normal revision history, but I don&#8217;t know if the patch-queue-as-repository setup works as I think it would in this case.</p>

<p>There also appears to be no <code>--abort</code> switch for the <code>transplant</code> command. One could be implemented easily, using the <code>strip</code> command from <code>mq</code>.</p>

<p>Finally, I&#8217;m sure there are more use cases for <code>git rebase</code> than the two I&#8217;ve mentioned here. I&#8217;m hoping to see some comments from you, dear readers, exploring edge cases and challenging new solutions.</p>
]]></content:encoded>
			<wfw:commentRss>http://kbullock.ringworld.org/2009/04/24/on-rebasing/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Announcing __hg_ps1</title>
		<link>http://kbullock.ringworld.org/2009/04/14/announcing-hg-ps1/</link>
		<comments>http://kbullock.ringworld.org/2009/04/14/announcing-hg-ps1/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 23:04:00 +0000</pubDate>
		<dc:creator>kbullock</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[prompt]]></category>
		<category><![CDATA[scm]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">/2009/10/04/announcing-hg-ps1</guid>
		<description><![CDATA[You may know that Git&#8217;s bash completion defines a function, __git_ps1, designed to be called from your shell prompt string. If you happen to be in a git repository, it spits out what branch you&#8217;re on.

Similar things for Mercurial have been written up, but they call hg repeatedly from bash functions. That means for each [...]]]></description>
			<content:encoded><![CDATA[<p>You may know that Git&#8217;s bash completion defines a function, <code>__git_ps1</code>, designed to be called from your shell prompt string. If you happen to be in a git repository, it spits out what branch you&#8217;re on.</p>

<p>Similar things for <a href="http://www.selenic.com/mercurial/">Mercurial</a> have been <a href="http://stevelosh.com/blog/entry/2009/3/17/mercurial-bash-prompts/">written up</a>, but they call <code>hg</code> repeatedly from bash functions. That means for each time your prompt is printed, the Python interpreter gets fired up three or four times. My implementation is written in Python using Mercurial&#8217;s API, so it only starts <em>one</em> external process.</p>

<p>Find it on bitbucket: <a href="http://bitbucket.org/krbullock/hg_ps1">http://bitbucket.org/krbullock/hg_ps1</a>. Feel free to submit issues there, or write patches and submit pull requests.</p>

<p><strong>Update 4 Oct 2009:</strong> Steve Losh went and one-upped me with a Mercurial extension, <a href="http://bitbucket.org/sjl/hg-prompt/"><code>hg-prompt</code></a>. It&#8217;s much more flexible than what I did with <code>__hg_ps1</code>, and last night I took the time to add MQ support to it. I&#8217;d recommend switching to it if you&#8217;re using <code>__hg_ps1</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://kbullock.ringworld.org/2009/04/14/announcing-hg-ps1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
