<?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>UltraNurdage &#187; How-Tos</title>
	<atom:link href="http://blog.ultranurd.net/category/how-tos/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ultranurd.net</link>
	<description>Collected Commentary</description>
	<lastBuildDate>Wed, 01 Feb 2012 18:59:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Back That Thing Up</title>
		<link>http://blog.ultranurd.net/2010/09/09/back-that-thing-up/</link>
		<comments>http://blog.ultranurd.net/2010/09/09/back-that-thing-up/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 21:24:00 +0000</pubDate>
		<dc:creator>Nicolas Ward</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[backup tripod]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[carbon copy cloner]]></category>
		<category><![CDATA[dropbox]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[macs]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[time machine]]></category>

		<guid isPermaLink="false">http://blog.ultranurd.net/?p=818</guid>
		<description><![CDATA[Introduction Three Sundays ago, my primary Mac OS X hard drive failed. Those of you who follow me on Twitter got somewhat of a play-by-play as I discovered the depth of my drive failure I got home to the Spinning Pinwheel of Death (SPOD), and discovered quickly that my computer would not wake from screensaver [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Three Sundays ago, my primary Mac OS X hard drive failed. Those of you who follow me on Twitter got somewhat of a play-by-play as I discovered the depth of my drive failure I got home to the <a title="Spinning wait cursor on Wikipedia" href="http://en.wikipedia.org/wiki/Spinning_wait_cursor">Spinning Pinwheel of Death (SPOD)</a>, and discovered quickly that my computer would not wake from screensaver or boot. However, I didn&#8217;t panic. Why? Because I have what I believe to be a relatively robust backup system for home use.</p>
<p>I can&#8217;t stress enough how important regular backups are. Data loss is one of my personal nightmares (well, that, and Lego or <a title="Andrle on Twitter" href="http://twitter.com/andrle">Andrle</a> loss), since most of my life (professional and personal) is on the computer. Among other things, I&#8217;d lose every picture I&#8217;ve ever taken since freshman year of college, every homework assignment I&#8217;ve written on the computer since late 6th grade (when we got our first Mac), not to mention substantial configuration work and those precious saved games.</p>
<p>I sit atop what I call the Backup Tripod: regular clones to an external disk stored off-site, hourly incremental backups to a local disk or local network storage, and as-needed on-save synchronization to cloud storage. I&#8217;m sure there are many other articles out there that recommend a particular strategy, but this is my solution for Macs. I even convinced my parental units to use a similar setup. I&#8217;ll go into detail on what solutions I use and why (as well as recovery strategy) for each below the cut.</p>
<p>I can&#8217;t emphasize enough how important data backup is for the typical modern power user.</p>
<p><span id="more-818"></span></p>
<h2>Offsite Clones</h2>
<p>Why do an offsite clone? First, this is primarily to solve the &#8220;your apartment burned down&#8221; problem. You want to be able to recover as much of your data as possible, all at once, but you might be okay in that situation with a little bit of recent data loss. The latter can be mitigated of course by using the other two legs of the tripod in combination</p>
<p>I&#8217;ve been using the excellent <a title="Carbon Copy Cloner - Home" href="http://www.bombich.com/index.html">Carbon Copy Cloner</a> for several years to make cloned backups of my primary hard drive. It&#8217;s a Mac-specific solution that has seen regular improvements over that time, including a migration to launchd as part of updating for Mac OS 10.5 that enables some features I use, such as &#8220;initiate backup on mount&#8221;, which triggers my standard clone job as soon as my external drive is plugged in. Cloning the actual disk is of course only half of the solution: you need to be responsible for storing your backup drive in a safe location, and bringing it home for regular incremental updates, to minimize the annoyance during a recovery.</p>
<p>I store my home hard drive in a locked drawer in my office at work; my parents keep an old iPod with important files in their safe deposit box. I should also admit at this point that, for this particular failure, my clone backup was almost 4 months old, therefore making recovery a fair bit more annoying than it needed to be had I been keeping my clone more up-to-date.</p>
<h2>Incremental Local Backups</h2>
<p>Why do incremental backups? This is primarily to smooth out the frequency of your backups: now instead of a backup only as recent as the last time you remembered to bring your clone drive home, you can have one as recent as a few minutes ago. The other major advantage is that, when configured properly, they are completely automated. For the most part, you shouldn&#8217;t even care that they&#8217;re set up; they&#8217;ll just run silently in the background, and you&#8217;ll only notice their existence when you need them to perform a recovery. Note that in this context, by &#8220;local&#8221; I mean &#8220;in the same building&#8221;, not necessarily on the same machine, since some network solutions are viable here.</p>
<p>Being a Mac junkie, I use Apple&#8217;s <a title="Mac OS X - What is Time Machine?" href="http://www.apple.com/macosx/what-is-macosx/time-machine.html">Time Machine</a>. Given my experience with this recent near-loss of data, I can safely say that for me, this is now Apple&#8217;s most important product ever (no matter how magical and revolutionary the iPad may be, it hasn&#8217;t saved my bacon&#8230; yet). Since my primary computer is a Mac Pro desktop, I have Time Machine configured to back up to a second internal drive. My parental units, since they both have laptops, use a <a title="Apple - Time Capsule" href="http://www.apple.com/timecapsule/">Time Capsule</a> as their backup system (and primary wireless router).</p>
<p>I can&#8217;t from personal experience recommend a particular incremental backup solution for Windows or Linux, but TSOR <a title="Time machine for Ubuntu?" href="http://maketecheasier.com/time-machine-for-ubuntu-try-timevault-and-flyback/2008/03/07">suggests</a> <a title="TimeVault - GNOME Backup/Snapshot System" href="https://launchpad.net/timevault">TimeVault</a> for Ubuntu. At work they use a network version of <a title="Connected Backup for PC and Mac" href="http://backup.ironmountain.com/">IronMountain Connected Backup</a>, which is at least the fourth Windows backup solution IT has tried since I&#8217;ve worked there. So far it seems to have staying power, and I assume it&#8217;s working, but a running backup causes a massive performance hit on my Windows XP development machine, making it essentially unusable due to I/O when the backup is running. (I should add that in my experience, Time Machine does not cause a performance hit, even when playing a processor-intensive 3D game like World of Warcraft. I believe this has to do with Apple&#8217;s implementation using FSEvents, although <a title="Mac OS X 10.5 Leopard: the Ars Technica review" href="http://arstechnica.com/apple/reviews/2007/10/mac-os-x-10-5.ars/14">Siracusa&#8217;s review of Leopard</a> explains the underpinnings of Time Machine better than I.)</p>
<p>One of the major caveats of an incremental backup, as I learned the hard way during this particular recovery, is that they are bad at dealing with single large files that change often. In other words, databases of various sorts, as well as writeable disk images. Examples include the <a title="iTunes" href="http://www.apple.com/itunes/">iTunes</a> Music Library file, and the Mac OS 9 disk image used by the <a title="The Official SheepShaver Home Page" href="http://sheepshaver.cebix.net/">SheepShaver</a> PowerPC emulator. There are two problems that these files can cause: the first is that they may cause your backup to fail due to file locking (especially if the program using the particular file is currently running); the second is that, since most incremental backup systems operate at filesystem granularity, they have to back up the entire file even if only a small portion of its data has changed. The latter leads to your incremental backup disk getting filled with many version changes</p>
<p>This is where careful management of your incremental backup&#8217;s ignore list comes in: I had both of these files ignored in Time Machine, so I had to restore them from my clone drive. More on that in the Recovery section below.</p>
<h2>Cloud Storage</h2>
<p>Why use cloud storage? Or, in this case, a better question might be &#8220;Why not use a cloud backup service?&#8221;.</p>
<p>I&#8217;ll answer the second first: I don&#8217;t trust them. Maybe this is some bizarre geek control freak paranoia, but I just don&#8217;t believe that their service can actually deliver what they promise while simultaneously being sufficiently secure. There are at least three parts to this: the first is that I don&#8217;t believe that the service will necessarily be available when I need it (whether during backup or recovery), the second is that I don&#8217;t believe they&#8217;ll actually delete my data completely when I ask, and the third is that I don&#8217;t believe they can completely protect my data from an attack on their systems. To some extent, these factors are all true of existing cloud services I rely on (such as GMail), but that data is a lot less critical or private than the full contents of my hard drive (and, in the case of e-mail, I keep a full local cache). I haven&#8217;t used any of the major cloud backup services out there for full backups, so I don&#8217;t want to bash any of them by name, but I would argue that they all suffer from these potential problems.</p>
<p>That brings us to my (admittedly limited) use of the <a title="Dropbox - Home" href="http://www.dropbox.com/">Dropbox</a> service. I only use the free 2 GB level of service, and I use it primarily for temporary file transfer to my iPhone or iPad. However, for a handful of important files that I&#8217;m actively working on, I use it as a sort of temporary remote version control. That is, as I reach a point in a particular document that I want to make sure I don&#8217;t lose, I&#8217;ll save the file locally and then copy it to my Dropbox, generally not overwriting the previous copy. That means if I need to &#8220;restore&#8221;, I just retrieve the appropriate copy from my Dropbox. When I&#8217;m done, I delete that particular working folder.</p>
<h2>Recovery</h2>
<p>Since I refer to this setup as the Backup Tripod, then there is the platform being supported by the three legs described above: quick and relatively painless recovery of your lost data. How do you use these three levels of backup to restore your data after a disk failure? To a large extent this depends on the type of failure you experienced, and how broad it was.</p>
<p>If you&#8217;ve accidentally deleted a single file, or somehow produced a corrupted version, then pulling a previous copy from either your cloud storage or your hourly local backup is probably a sufficient level of recovery, particularly if the first iteration of the file was created since your last offsite backup. (Depending on what you&#8217;re working on, there may also be a place where a distributed version control system like <a title="Git - Fast Version Control System" href="http://git-scm.com/">git</a> can play a role.) Deciding how many past versions to keep over the course of a work session is up to your discretion (and the importance of the file). Of course, if the &#8220;single file&#8221; is one of the files described above as being difficult to backup incrementally, you will probably have to recover the version from your clone drive. Again, regular backups here are critical, in order to make recovery possible.</p>
<p>If you&#8217;ve lost the entire drive, you have two options, assuming you were using Time Machine as your incremental backup solution: you can restore from the last successful hourly backup, or you can restore from your clone (obviously both require purchasing a new drive and replacing the old one). Most likely you need to do a combination of the two: restore from the incremental backup first, to get the most recent version of various files, and then manually restore any files you keep on the ignore list such as virtual machine images or databases, plus any &#8220;high priority&#8221; files you have stored &#8220;in the cloud&#8221;.</p>
<p>For my particular recovery, in the case of the aforementioned VM image, this was fine, since I hadn&#8217;t used it since my last complete clone; in the case of my music library, I had to reimport a number of apps from the backed up iTunes data folders and eliminate duplicates and stale versions. This was mostly a task of synchronizing the state of the iTunes Library with the fully backed up on-disk state. Annoying, but avoidable/minimized by keeping more recent clones than I had. This was also a case where I didn&#8217;t need the cloud storage leg at all, since the failure occurred while I wasn&#8217;t home, so I wasn&#8217;t actively working on an important file that I wouldn&#8217;t have wanted to lose if I had a local disaster.</p>
<p>Incidentally, my hard drives would probably be the first thing out of my apartment in the event of a fire. <.<</p>
<h2>Conclusion</h2>
<p>Those are the three legs to the Backup Tripod, blending a balance of manual vs. automatic, offsite vs. local, and complete vs. incremental. I claim you need all of these features to insure a complete, up-to-date backup under a variety of failure conditions.</p>
<p>If you follow the general gist of this guide, and keep good backup habits, there&#8217;s a reasonable chance that a complete hard drive failure will be nothing more than a minor inconvenience.  You&#8217;ll have to order a new drive and wait for it to arrive (or pick one up at your favorite tech shop), and then most of the process is waiting several hours while your computer does the restore, during which time you can get outside or something. Maybe a little bit of manual file restoration. All in all, annoying, but not a massive tragedy that would be the loss of all your home data (and a hell of a lot cheaper than hiring a data recovery expert).</p>
<p>Seriously. Back. Up. DO EET NAOW!!!</p>
<p>(And while you&#8217;re at it, make sure the IT guys at your work are on top of this.)</p>
<div class='wb_fb_bottom'><div style="float:right;"></div></div>]]></content:encoded>
			<wfw:commentRss>http://blog.ultranurd.net/2010/09/09/back-that-thing-up/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Möbius Bagel</title>
		<link>http://blog.ultranurd.net/2009/12/08/mobius-bagel/</link>
		<comments>http://blog.ultranurd.net/2009/12/08/mobius-bagel/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 18:18:21 +0000</pubDate>
		<dc:creator>Nicolas Ward</dc:creator>
				<category><![CDATA[food]]></category>
		<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[bagels]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[maths]]></category>
		<category><![CDATA[topology]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://blog.ultranurd.net/?p=750</guid>
		<description><![CDATA[Via JWZ&#8217;s LiveJournal I found a method for slicing a bagel into two linked halves. I decided to try it. Video below the cut. I just did this freehand; this was my first try. Not as hard as the instructions make it sound. I think it&#8217;s pretty cool. Impress your nerdy friends!]]></description>
			<content:encoded><![CDATA[<p>Via <a title="jwz: Mobius Sliced Linked Bagel" href="http://jwz.livejournal.com/1134906.html">JWZ&#8217;s LiveJournal</a> I found <a title="Mathematically Correct Breakfast" href="http://www.georgehart.com/bagel/bagel.html">a method for slicing a bagel into two linked halves</a>. I decided to try it. Video below the cut.</p>
<p><span id="more-750"></span></p>
<p><center><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="220" height="320" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/Zu5z1BCC70s&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="220" height="320" src="http://www.youtube.com/v/Zu5z1BCC70s&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></center></p>
<p>I just did this freehand; this was my first try. Not as hard as the instructions make it sound.</p>
<p>I think it&#8217;s pretty cool. Impress your nerdy friends!</p>
<div class='wb_fb_bottom'><div style="float:right;"></div></div>]]></content:encoded>
			<wfw:commentRss>http://blog.ultranurd.net/2009/12/08/mobius-bagel/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Satisfy MacPorts Dependencies Locally</title>
		<link>http://blog.ultranurd.net/2009/07/22/satisfy-macports-dependencies-locally/</link>
		<comments>http://blog.ultranurd.net/2009/07/22/satisfy-macports-dependencies-locally/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 03:31:50 +0000</pubDate>
		<dc:creator>Nicolas Ward</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[macports]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[package management]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpmyadmin]]></category>
		<category><![CDATA[source compilation]]></category>

		<guid isPermaLink="false">http://blog.ultranurd.net/?p=679</guid>
		<description><![CDATA[Introduction Like many Unix geeks, I have software installed that I&#8217;ve built manually from source. A good example is my post on compiling django; a number of the relevant dependencies were built in /usr/local/src/ and installed in /usr/local/. I also like using package managers, because if I&#8217;m not doing any customization (and the package is [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Like many Unix geeks, I have software installed that I&#8217;ve built manually from source. A good example is my post on <a title="Compiling Django with Twitter Support as a Mac OS X Universal Binary" href="http://blog.ultranurd.net/2009/01/28/compiling-django-with-twitter-support-as-a-mac-os-x-universal-binary/">compiling django</a>; a number of the relevant dependencies were built in <code>/usr/local/src/</code> and installed in <code>/usr/local/</code>. I also like using package managers, because if I&#8217;m not doing any customization (and the package is common and not hard-to-find), I want to just get the latest version and slap it in the right place. The conflict between the two methodologies is when a managed package depends on software that is already installed on your system, either part of the default configuration (OS X ships with a fair bit of Unixy software included, especially if you install the Dev Tools, although not always a &#8220;standard&#8221; or particularly recent version) or custom-built.</p>
<p>I recently dumped <a title="Fink - Home" href="http://www.finkproject.org/">Fink</a> for <a title="The MacPorts Project - Home" href="http://www.macports.org/">MacPorts</a>; while I&#8217;ve used Fink for a long time, since an early version was available for Mac OS 10.2 Jaguar in fact, it&#8217;s just gotten in a messy state maintenance-wise. I&#8217;ve been familiar with apt since using Debian-based systems at the <a title="Swarthmore College Computer Society" href="http://www.sccs.swarthmore.edu/">SCCS</a>, but the mish-mash of binary and source items, the preponderance of out-of-date packages, and the apparent need to install 70 metric boatloads of GNOME just to satisfy a few dependencies was frustrating. Of course, MacPorts has its own weaknesses, as do almost all package managers; in particular, none of them seem to be able to track whether a package was installed explicitly by the user or merely to satisfy a dependency. My opinion is that the latter should get uninstalled when all of its dependents are uninstalled, but no package manager seems to agree with me on that. A rant on that probably merits a separate post.</p>
<p>Below the cut is a rough step-by-step guide to creating a local portindex and creating portfiles for your manual dependencies. Note that most MacPorts users would tell you this is a terrible idea, and you should just install all the port dependencies, but I already put the effort into these custom from-source builds and I just want to use them without duplicates getting dropped all over my hard drive.</p>
<p><span id="more-679"></span></p>
<h2>Create Local Portfile Repository</h2>
<p>These instructions are based on <a title="MacPorts Guide - 4.6 - Local Portfile Repositories" href="http://guide.macports.org/#development.local-repositories">Section 4.6 of the MacPorts Guide</a>.</p>
<ol>
<li>Create a directory that will serve as your portfile repository; I used <code>/usr/local/ports/</code></li>
<li>Add this directory to your MacPorts configuration. For me, that meant editing <code>/opt/local/etc/macports/sources.conf</code> to add the line <code>file:///usr/local/ports/</code> <strong>before</strong> the standard rsync line (for priority)</li>
<li>Update the port index. For me, I needed to run <code>sudo portindex</code> in <code>/usr/local/ports/</code> because of the way I have permissions set.</li>
</ol>
<p>Now, if you use any port command, it will look at your local source first.</p>
<h2>Create a Placeholder Portfile</h2>
<p>For this example, I&#8217;m focusing on installing the port phpmyadmin, but satisfying its runtime dependencies on MySQL and PHP using local builds.</p>
<ol>
<li>Check the dependencies of your target port: <code>port deps phpmyadmin</code>
<pre>phpmyadmin has runtime dependencies on:
	mysql5
	php5</pre>
</li>
<li>For each dependency, look it up using <a title="MacPorts Project - Available Ports" href="http://www.macports.org/ports.php">MacPorts search</a>, and then click on the link to view the checked-in portfile. In general this link will have the form <code>http://trac.macports.org/browser/trunk/dports/CATEGORY/PORT/Portfile</code>, where CATEGORY and PORT are the relevant names of the package you&#8217;re trying to replace
<ul>
<li><a title="mysql5 Portfile" href="http://trac.macports.org/browser/trunk/dports/databases/mysql5/Portfile">mysql5</a></li>
<li><a title="php5 Portfile" href="http://trac.macports.org/browser/trunk/dports/lang/php5/Portfile">php5</a></li>
</ul>
</li>
<li>Now you need to create a local placeholder portfile for each of these packages; in the port repository you created above, you&#8217;ll need to create a subdirectory for the CATEGORY and then open a file named PORT in that directory in your favorite text editor. For example:
<ul>
<li><code>cd /usr/local/ports/</code></li>
<li><code>sudo mkdir -p databases/mysql5</code></li>
<li><code>sudo touch databases/mysql5/Portfile</code></li>
<li><code>sudo emacs databases/mysql5/Portfile</code></li>
</ul>
</li>
<li>We only need a few variables in the portfile to trick MacPorts into accepting our dependency, some of which can be copied from the real portfile. Note that I added a mention of &#8220;placeholder&#8221; to the description, changed the version to match what I built locally (which is a newer version than what&#8217;s available in MacPorts), and added some information about the build. We also need to make MacPorts do a no-op for all port phases. Here&#8217;s what mine looks like:
<pre>PortSystem              1.0
name                    mysql5
version                 5.1.30
homepage                http://www.mysql.com/
categories              databases
platforms               darwin
distname                mysql-${version}

description \
    Placeholder for multithreaded SQL database server

long_description \
    MySQL is an open-source, multi-threaded SQL database \
    with a command syntax very similar to mSQL. \
    \
    This is a placeholder built from source in /usr/local/src/mysql-5.1.30/ \
    on 2009.01.27 using the options:\
    \
    ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex \
    --enable-thread-safe-client --enable-local-infile --disable-shared \
    --with-unix-socket-path=/usr/local/mysql/run/mysql_socket \
    --with-mysqld-user=_mysql --disable-dependency-tracking

fetch {}
checksum {}
extract {}
patch {}
configure {}
build {}
test {}
destroot {}
install {}
activate {}</pre>
</li>
<li>After creating and editing the relevant portfiles(s), you need to regenerate the portindex as above.</li>
<li>If you run port search mysql5, you&#8217;ll see both the real port and your placeholder listed with the short description, like this:
<pre>mysql5 @5.0.83 (databases)
    Multithreaded SQL database server

mysql5 @5.1.30 (databases)
    Placeholder for multithreaded SQL database server</pre>
</li>
<li>If you run port info mysql5, you&#8217;ll get a warning about multiple definitions, but see the long description of your custom placeholder:
<pre>Warning: Found 2 port mysql5 definitions, displaying first one.
mysql5 @5.1.30 (databases)
Variants:    universal

MySQL is an open-source, multi-threaded SQL database with a command syntax very
similar to mSQL. This is a placeholder built from source in
/usr/local/src/mysql-5.1.30/ on 2009.01.27 using the options: ./configure
--prefix=/usr/local/mysql --with-extra-charsets=complex
--enable-thread-safe-client --enable-local-infile --disable-shared
--with-unix-socket-path=/usr/local/mysql/run/mysql_socket
--with-mysqld-user=_mysql --disable-dependency-tracking
Homepage:    http://www.mysql.com/

Platforms:            darwin</pre>
</li>
</ol>
<h2>Undoing the Mess</h2>
<p>Pretty simple. Just uninstall the placeholder you created, remove its file from your local ports, rebuild the portindex, and reinstall the &#8220;real&#8221; package (or just leave it uninstalled, depending on what you&#8217;re trying to do). Alternatively, uninstall all the placeholders you created, and remove the offending line from your sources.conf before continuing.</p>
<h2>Conclusion</h2>
<p>I&#8217;ve only tested this with runtime dependencies so far, not build dependencies. I think the general idea is sound, but as I said, it&#8217;s probably a terrible idea. I&#8217;m curious if you can extend this process to get any other ports to install using system or local dependencies. I&#8217;d also welcome any suggestions for a better way to achieve or similar result. Feel free to just call me misguided and mad, as well!</p>
<div class='wb_fb_bottom'><div style="float:right;"></div></div>]]></content:encoded>
			<wfw:commentRss>http://blog.ultranurd.net/2009/07/22/satisfy-macports-dependencies-locally/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Nostromo Keybindings for WoW</title>
		<link>http://blog.ultranurd.net/2009/04/23/nostromo-keybindings-for-wow/</link>
		<comments>http://blog.ultranurd.net/2009/04/23/nostromo-keybindings-for-wow/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 02:24:46 +0000</pubDate>
		<dc:creator>Nicolas Ward</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[Reviews]]></category>
		<category><![CDATA[computer peripheral]]></category>
		<category><![CDATA[nostromo]]></category>
		<category><![CDATA[video game]]></category>
		<category><![CDATA[world of warcraft]]></category>

		<guid isPermaLink="false">http://blog.ultranurd.net/?p=608</guid>
		<description><![CDATA[Introduction As you may have gathered, I have a&#8230; healthy&#8230; relationship with everyone&#8217;s favorite MMO, World of Warcraft. I forget who originally planted the idea in my head (there&#8217;s a good chance it was Lilboo, formerly of the Daring Blades on Kirin Tor), but I decided that I wanted a dedicated game controller that was [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>As you may have gathered, I have a&#8230; healthy&#8230; relationship with everyone&#8217;s favorite MMO, <a title="World of Warcraft Homepage" href="http://www.worldofwarcraft.com">World of Warcraft</a>. I forget who originally planted the idea in my head (there&#8217;s a good chance it was Lilboo, formerly of the Daring Blades on Kirin Tor), but I decided that I wanted a dedicated game controller that was more than just the keyboard; there&#8217;s just too much going on in WoW for an FPS-like control layout, in my opinion. I settled on a Nostromo, and after a few weeks of adjusting, and very few changes to my bindings, I have gotten very used to what may be a very unusual control style.</p>
<p>Verbose explanation of how I use the device below the cut.</p>
<p><span id="more-608"></span></p>
<h2>Nostromo</h2>
<p>First, the product itself. I have the <a title="Belkin : Nostromo SpeedPad n52" href="http://catalog.belkin.com/IWCatProductPage.process?Product_Id=164714">Nostromo n52</a>, which gives you a D-pad, 14 programmable keys, a scrollwheel, and two thumb buttons. I&#8217;ve only seriously tried configuring it for World of Warcraft (and also for <a title="The Lord of the Rings Online Home" href="http://www.lotro.com">Lord of the Rings Online</a>, but I intentionally set that up to be almost identical to WoW).</p>
<p>Last year <a title="Belkin : Home" href="http://www.belkin.com/">Belkin</a> released the <a title="Belkin n52te" href="http://www.n52te.com/">Nostromo n52te</a> (Flash website), which as far as I can tell is the same product, costs twice as much, and has silly blue lights. Maybe they improved the &#8220;touch&#8221; of the keys, but the vanilla n52 works fine after hundreds of days of playtime (although the key labels have all worn off).</p>
<p>The Nostromo works with both PC and Mac, and the Mac software is one of the better ones for third-party peripherals; it&#8217;s implemented as a System Preferences pane, which is the &#8220;right&#8221; way of doing this sort of thing on a Mac (as opposed to a standalone application). Here&#8217;s what configuring it looks like on a Mac:</p>
<p> </p>
<div id="attachment_609" class="wp-caption aligncenter" style="width: 459px"><a href="http://blog.ultranurd.net/wp-content/uploads/2009/04/picture-23.png"><img class="size-full wp-image-609     " title="Nostromo Array (Mac)" src="http://blog.ultranurd.net/wp-content/uploads/2009/04/picture-23.png" alt="Configuring the Nostromo n52 on Mac OS X" width="449" height="374" /></a><p class="wp-caption-text">Configuring the Nostromo n52 on Mac OS X</p></div>
<p>Pretty straight-forward; you select the key on the Nostromo you want to configure, and then you can select a wide variety of actions (and add modifiers). I haven&#8217;t ever used any of the &#8220;turbo&#8221; functionality, I treat them all as normal keys, with the exception of the Shift buttons.</p>
<p>Here&#8217;s how configuring the Nostromo looks on Windows (and how it looked on the Mac before they wrote new drivers, as opposed to just porting the Windows ones):</p>
<p> </p>
<div id="attachment_614" class="wp-caption aligncenter" style="width: 414px"><a href="http://blog.ultranurd.net/wp-content/uploads/2009/04/picture-24.png"><img class="size-full wp-image-614 " title="Nostromo Array (Windows)" src="http://blog.ultranurd.net/wp-content/uploads/2009/04/picture-24.png" alt="Configuring the n52" width="404" height="347" /></a><p class="wp-caption-text">Configuring the Nostromo n52 on Windows 7</p></div>
<p>The same functionality, but the &#8220;cool looking&#8221; but non-standard UI I find a bit confusing. Both the Mac and Windows versions support some of the other Nostromo series products. The Windows version is a bit better at saving profiles for export; as far as I know, the current Mac version can&#8217;t do this (unless you want to dig around in OS X plist files).</p>
<p>Shifting is one of the really cool capabilities of the Nostromo: while there are only a few physical buttons, if you assign 3 of them to Red Shift, Blue Shift, and Green Shift, you effectively quadruple your available buttons (I definitely don&#8217;t use that many), as long as you&#8217;re willing to press multiple keys at once. This is usually called &#8220;chording&#8221;, and at this point it&#8217;s very well embedded in my muscle memory, as you&#8217;ll see below. This is what really gives you &#8220;speed at your fingertips&#8221; or whatever they put in the marketing literature &#8211; with only a few movements of your left hand, you basically get as many keybindings as a standard keyboard.</p>
<h2>n52 Keybindings</h2>
<p>As you can see below, I use the D-pad for strafe-based movement, since I use mouse turning. The orange button near the D-pad is hard to use with the D-pad, so I just use it as an auto-run toggle. The six buttons in the upper right are associated with the active action bar; either 1-6 or 7-12, depending on whether or not I&#8217;m red shifted. The mousewheel is used for applying target markers (skull, X, etc.). Most of the keys on the left periphery are lower priority things, since they&#8217;re hit by my pinky or by an extension of one of my other fingers.</p>
<p>The main functionality is with that block of 6 keys. Between the red shift on my thumb (button 15, below the D-pad), and shift (the literal keyboard key) on Button 11, in the lower left for my pinky, I can select any of my character&#8217;s actions with a three-fingered cord. Since I organize my action buttons in-game carefully (see the next section), most of my fast in-combat actions can be achieved by mashing one key with the relevant finger, possibly while pressing my thumb. I can press my thumb on the red shift key while using the D-pad to move, although in highly mobile fights I&#8217;m likely to use a combination of autorun and mouse movement.</p>
<p>Also, these bindings should be perfectly valid for a newer Nostromo n52te.</p>
<table border="0">
<tbody>
<tr>
<th>Key</th>
<th>No Shift</th>
<th><span style="color: #ff0000;">Red Shift</span></th>
<th><span style="color: #00ff00;">Green Shift</span></th>
<th><span style="color: #0000ff;">Blue Shift</span></th>
</tr>
<tr>
<th>Button 1</th>
<td><span style="color: #0000ff;">Blue Shift</span></td>
<td><span style="color: #0000ff;">Blue Shift</span></td>
<td><span style="color: #0000ff;">Blue Shift</span></td>
<td><span style="color: #0000ff;">Blue Shift</span></td>
</tr>
<tr>
<th>Button 2</th>
<td>Key (space)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (x)</td>
</tr>
<tr>
<th>Button 3</th>
<td>Key (5)</td>
<td>Key (-)</td>
<td>Key (F5)</td>
<td>Key (ctrl+5)</td>
</tr>
<tr>
<th>Button 4</th>
<td>Key (3)</td>
<td>Key (9)</td>
<td>Key (F3)</td>
<td>Key (ctrl+3)</td>
</tr>
<tr>
<th>Button 5</th>
<td>Key (1)</td>
<td>Key (7)</td>
<td>Key (F1)</td>
<td>Key (ctrl+1)</td>
</tr>
<tr>
<th>Button 6</th>
<td><span style="color: #00ff00;">Green Shift</span></td>
<td><span style="color: #00ff00;">Green Shift</span></td>
<td><span style="color: #00ff00;">Green Shift</span></td>
<td><span style="color: #00ff00;">Green Shift</span></td>
</tr>
<tr>
<th>Button 7</th>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>Button 8</th>
<td>Key (6)</td>
<td>Key (=)</td>
<td>Key (F6)</td>
<td>Key (ctrl+6)</td>
</tr>
<tr>
<th>Button 9</th>
<td>Key (4)</td>
<td>Key (0)</td>
<td>Key (F4)</td>
<td>Key (ctrl+4)</td>
</tr>
<tr>
<th>Button 10</th>
<td>Key (2)</td>
<td>Key (8)</td>
<td>Key (F2)</td>
<td>Key (ctrl+2)</td>
</tr>
<tr>
<th>Button 11</th>
<td>Press shift</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>Button 12</th>
<td>Key (c)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>Button 13</th>
<td>Key (m)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>Button 14</th>
<td>Key (shift+b)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>Button 15</th>
<td><span style="color: #ff0000;">Red Shift</span></td>
<td><span style="color: #ff0000;">Red Shift</span></td>
<td><span style="color: #ff0000;">Red Shift</span></td>
<td><span style="color: #ff0000;">Red Shift</span></td>
</tr>
<tr>
<th>Wheel Up</th>
<td>Key (opt+k)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>Wheel Down</th>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>Wheel Button</th>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>Circle Button</th>
<td>Key (num clear)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>DPad Up</th>
<td>Key (w)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>DPad Right</th>
<td>Key (e)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (d)</td>
</tr>
<tr>
<th>DPad Down</th>
<td>Key (s)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>DPad Left</th>
<td>Key (q)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (a)</td>
</tr>
<tr>
<th>DPad Up Right</th>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>DPad Down Right</th>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>DPad Down Left</th>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
<tr>
<th>DPad Up Left</th>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
<td>Key (none)</td>
</tr>
</tbody>
</table>
<p>The other keybindings are pretty boring: they open the character pane, my current favorite map mod, or my bag management mod. Green shift and Blue Shift are largely unused, although they focus on modifying the core 6 buttons; Green lets me target party members (function keys), including myself (I mostly rely on Grid and mouseover macros these days); Blue lets me activate pet/vehicle abilities (control + number keys).</p>
<p>Blue shift also modifies some other actions, such as making the D-pad turn instead of strafe, or making my flying mount go down instead of up (note that x and space are assigned to the same button, just shifted). There&#8217;s a lot of room for expansion, and the configuration is admittedly a bit haphazard&#8230; but I&#8217;ve been using it for over 2 years, so I&#8217;m very used to it. It&#8217;s all in muscle memory, and I can react very quickly to most in-game events without moving my hands at all (I use a <a title="Logitech Cordless Trackman Optical Product Information" href="http://www.logitech.com/index.cfm/mice_pointers/trackballs/devices/189&amp;cl=us,en">Logitech Cordless TrackMan® Optical</a> in my right hand).</p>
<h2>WoW Keybindings</h2>
<p>If it wasn&#8217;t obvious to most WoW players based on the bindings listed above, I keep the in-game keybindings set almost exclusively to the defaults (with the exception of a few additions, or tweaks to use particular mods in place of some default UI components). I also use only the default action bar; the shift-# bindings above select one of the six default action bar &#8220;pages&#8221;, and then 1 through = on the number row activate an action on the current bar. Thus my Nostromo configuration depends heavily on my bar configuration, since I memorize it</p>
<p>Without going into detail at the level of specific class abilities, here&#8217;s how I break down the six action bars:</p>
<ol>
<li>Primary abilities: attacks, anything with a short cooldown; in the case of my healers, geared towards soloing.</li>
<li>Panic buttons: potions, trinkets, class abilities like Evasion and Desperate Prayer</li>
<li>Secondary abilities: longer cooldown combat abilities; in the case of my healers, mouseover macros for their various group healing and cleansing spells</li>
<li>Crafting: maybe silly to have a whole bar dedicated, but I don&#8217;t otherwise need the space</li>
<li>Transportation: mounts, pets, and usable quest items</li>
<li>Buffs: poison hotkeys on my rogue, blessings on my Paladin, etc.</li>
</ol>
<p>I&#8217;m admittedly not 100% consistent in this, but that&#8217;s the general idea. Because of where 1 and 2 are bound on the Nostromo, the most important bars are under my pointer finger; similarly, within each bar (and related to the core 6 keys above when combined with Red Shift), the most important abilities are in slots 1, 2, 7, and 8, because these are again under my pointer finger.</p>
<p>Maybe a full description of my UI configuration, including button bar breakdowns by class, can come in a future post; the main takeaway from all of this is that I try very hard to keep things similar across characters, so my muscle memory doesn&#8217;t have to relearn much as I switch between the different roles on my various alts. Feel free to suggest any tweaks to this!</p>
<div class='wb_fb_bottom'><div style="float:right;"></div></div>]]></content:encoded>
			<wfw:commentRss>http://blog.ultranurd.net/2009/04/23/nostromo-keybindings-for-wow/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Amish Cinnamon Bread</title>
		<link>http://blog.ultranurd.net/2009/03/15/amish-cinnamon-bread/</link>
		<comments>http://blog.ultranurd.net/2009/03/15/amish-cinnamon-bread/#comments</comments>
		<pubDate>Sun, 15 Mar 2009 06:13:58 +0000</pubDate>
		<dc:creator>Nicolas Ward</dc:creator>
				<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[baking]]></category>
		<category><![CDATA[bread]]></category>
		<category><![CDATA[food]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[recipe]]></category>

		<guid isPermaLink="false">http://blog.ultranurd.net/?p=574</guid>
		<description><![CDATA[Introduction A coworker of mine gave me some live yeast bread starter two weekends ago, and I have proceeded to actually bake it into bread. This is, believe me, quite out of character. I am posting this recipe here (which, as far as I know, is relatively useless without the culture) both for my records [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>A coworker of mine gave me some live yeast bread starter two weekends ago, and I have proceeded to actually bake it into bread. This is, believe me, quite out of character. I am posting this recipe here (which, as far as I know, is relatively useless without the culture) both for my records and so I have a place to point people who need the recipe and may not want a printed copy, perhaps because they are, like me, allergic to paper.</p>
<p>If you live in Boston, I&#8217;m happy to provide you with some starter for free (I hear it&#8217;s like a cult); I&#8217;ll have 3-4 become available every week and a half or so.</p>
<p>I don&#8217;t know the origin of the recipe; Liz gave me a photocopied sheet with no authorship information. I&#8217;ll try to find out. I&#8217;ve made a few minor edits for my own clarification.</p>
<p>I&#8217;m also open to suggestions on a means of distribution other than plastic gallon ziploc bags; while they have the advantage of being air tight, and clearly indicating when the bag needs to be squeezed, it seems like a waste of plastic. I am reusing the ones I&#8217;ve received, and the ones I&#8217;m keeping for my own permanent starter, but it seems like there might be a better way.</p>
<h2>Caveats</h2>
<ul>
<li>Do NOT refrigerate the mixture (this will kill the yeast)</li>
<li>Air formation in the bag is normal (a byproduct of fermentation)</li>
<li>&#8220;Squeeze&#8221; means let the air out, and mix the starter a bit by squishing</li>
</ul>
<h2>Schedule</h2>
<p>For each day, from the date marked on the starter, do the listed step:</p>
<ol>
<li>Nothing</li>
<li>Squeeze</li>
<li>Squeeze</li>
<li>Squeeze</li>
<li>Squeeze</li>
<li>Add 1 cup flour, 1 cup sugar, and 1 cup milk. Squeeze.</li>
<li>Squeeze</li>
<li>Squeeze</li>
<li>Squeeze</li>
<li>Bake!</li>
</ol>
<h2>Baking</h2>
<p>In a large bowl, combine the batter with 1 cup flour, 1 cup sugar, and 1 cup milk. Mix.</p>
<p>Partition 1 cup of starter into four 1 gallon ziploc bags. Pass along to friends and family, along with a copy of these instructions or a link to this blog post: <a href="http://blog.ultranurd.net/2009/03/15/amish-cinnamon-bread/">http://blog.ultranurd.net/2009/03/15/amish-cinnamon-bread/</a></p>
<p>Add to the remaining batter in the bowl:</p>
<ul>
<li>2 cups flour</li>
<li>1 1/2 tsp baking powder</li>
<li>1/2 tsp baking soda</li>
<li>1/2 tsp salt</li>
<li>1 tsp cinnamon</li>
<li>2 small boxes instant vanilla pudding</li>
<li>1 cup sugar</li>
<li>1 cup oil</li>
<li>1 tsp vanilla extract</li>
<li>3 large eggs</li>
<li>1/2 cup milk</li>
</ul>
<p>Mix well.</p>
<p>In another bowl, mix 1 tsp cinnamon and 2 tsp sugar (or just use cinnamon-sugar if you have it). Sprinkle this into the bottom of two well-greased bread pans, then add the batter.</p>
<p>Bake the loaves at 325° for 1 hour, or until a toothpick inserted into the center comes out clean.</p>
<div class='wb_fb_bottom'><div style="float:right;"></div></div>]]></content:encoded>
			<wfw:commentRss>http://blog.ultranurd.net/2009/03/15/amish-cinnamon-bread/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Compiling Django with Twitter support as a Mac OS X Universal Binary</title>
		<link>http://blog.ultranurd.net/2009/01/28/compiling-django-with-twitter-support-as-a-mac-os-x-universal-binary/</link>
		<comments>http://blog.ultranurd.net/2009/01/28/compiling-django-with-twitter-support-as-a-mac-os-x-universal-binary/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 01:13:36 +0000</pubDate>
		<dc:creator>Nicolas Ward</dc:creator>
				<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[64-bit]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[mod_python]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://blog.ultranurd.net/?p=502</guid>
		<description><![CDATA[This post is a guide for building your own version of Apache's mod_python as a Universal Binary in order to support a custom Django install containing the Twitter libraries. As you can probably gather, this information is likely only useful to advanced Mac users who are comfortable in Terminal with compiling and installing software from source. If you're still interested, gird your loins, crack your knuckles, grab some Mountain Dew, and read on.]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>This post is a guide for building your own version of <a title="The Apache HTTP Server Project" href="http://httpd.apache.org/">Apache&#8217;s</a> <a title="mod_python - Apache/Python Integration" href="http://www.modpython.org/">mod_python</a> as a Universal Binary in order to support a custom <a title="Django | The Web framework for perfectionists with deadlines" href="http://www.djangoproject.com">Django</a> install containing the Twitter libraries. As you can probably gather, this information is likely only useful to advanced Mac users who are comfortable in Terminal with compiling and installing software from source. If you&#8217;re still interested, gird your loins, crack your knuckles, grab some Mountain Dew, and read on.</p>
<p>Mac OS X 10.5 &#8220;Leopard&#8221; is yet another step forward into the world of 64-bit. At the same time, Apple has to support both PowerPC and Intel architectures. This is no mean feat, and this is where &#8220;fat&#8221; or <a title="Wikipedia: Universal binary" href="http://en.wikipedia.org/wiki/Universal_binary">Universal binaries</a> come in.  Apple also has <a title="Apple: Universal Applications" href="http://www.apple.com/universal/">an explanation of Universal binaries</a>, although it&#8217;s heavy on PR. This is all well and good, but there is one problem: once you make this leap, all of your library dependencies must contain the architecture you&#8217;re running as. Much software is still built as 32-bit only; while it may be a &#8220;fat&#8221; binary, containing both Intel and PowerPC machine code, it only has the 32-bit versions thereof. For reference, the names of the various architecture flags:</p>
<table class="code" border="0">
<tbody>
<tr>
<th> </th>
<th>32-bit</th>
<th>64-bit</th>
</tr>
<tr>
<th>Intel</th>
<td>i386</td>
<td>x86_64</td>
</tr>
<tr>
<th>PowerPC</th>
<td>ppc7400</td>
<td>ppc64</td>
</tr>
</tbody>
</table>
<p>Huzzah naming conventions! There&#8217;s a lot of history in those names. I&#8217;ve linked to the relevant Wikipedia articles if you&#8217;re curious; these flags will be coming up again later when configuring various builds. The main thing to note is that most build configurations default to i386 on Intel Macs (even though Core 2 and Xeon processors are natively 64-bit), probably because most software is developed for 32-bit versions of Windows and Linux. As you&#8217;ll see, we&#8217;ll be overriding that default in several places to get this whole mess working.</p>
<p>Unfortunately, Universality is a cancer, which in my case starts with the Apple-shipped version of the Apache web server in 10.5, a universal binary. Everything it touches needs to be Universal as well, so that Apache can run as a 64-bit process by default. I wanted to add Django support on my web server via mod_python, specifically to play with the <a title="Twitter" href="http://twitter.com">Twitter</a> <a title="Twitter API Wiki" href="http://apiwiki.twitter.com/">API</a>, which meant I also needed to build python-twitter and its dependencies, as well as a MySQL python module to allow Django to talk to my database. None of these are included in the default Leopard version of Python 2.5.1.</p>
<p>After getting all of this set up, and trying to start my test Django app, mod_python was giving me errors about architecture. As it turns out, the included version of Python is only a &#8220;fat&#8221; 32-bit binary, not a Universal binary&#8230; which means all of the new Python modules I just compiled to support Twitter and Django were only 32-bit, which in turn means that the included Universal version of Apache and mod_python couldn&#8217;t use them. Yay.</p>
<p>Below the cut you&#8217;ll find my complete instructions for compiling all of the relevant components and their dependencies. I also took the opportunity to update to the latest release version of Python 2.6 and MySQL 5.1, and as a side effect my database server is now running as a 64-bit process. Progress has been made here. Feel free to comment or contact me if you have questions.</p>
<p><span id="more-502"></span></p>
<h2>Dependencies</h2>
<p>Here&#8217;s a simple tree view of the package dependencies, followed by the order in which we&#8217;ll be compiling packages, with links to the relevant download sites. I&#8217;m assuming that all source tarballs have been expanded in <code>/usr/local/src/</code>, but obviously any prefix will do. I&#8217;m not listing any included packages; pretty much everything here depends on the custom build of the Python Framework. I also assume you have the Developer Tools isntalled from your Leopard DVDs.</p>
<ul>
<li>mod_python
<ul>
<li>Python</li>
<li>Django
<ul>
<li>setuptools</li>
<li>MySQLdb
<ul>
<li>MySQL</li>
</ul>
</li>
</ul>
</li>
<li>python-twitter
<ul>
<li>simplejson</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Click the package name to jump to the step in the instructions. Click the package version to download the source. (If you&#8217;re wondering why most Python packages are being built from source instead of eggs, it&#8217;s because there aren&#8217;t Python 2.6 eggs available for a lot of packages yet.)</p>
<ol>
<li><a title="Subsection MySQL" href="#MySQL">MySQL</a> <a title="MySQL 5.1.30 gzipped tarball Mirrors Page" href="http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.30.tar.gz/from/pick">5.1.30</a></li>
<li><a title="Subsection Python" href="#Python">Python</a> <a title="Python 2.6.1 gzipped tarball" href="http://www.python.org/ftp/python/2.6.1/Python-2.6.1.tgz">2.6.1</a></li>
<li><a title="Subsection setuptools" href="#setuptools">setuptools</a> <a title="setuptools 0.6c9 Python 2.6 egg" href="http://pypi.python.org/packages/2.6/s/setuptools/setuptools-0.6c9-py2.6.egg#md5=ca37b1ff16fa2ede6e19383e7b59245a">0.6c9-py2.6</a></li>
<li><a title="Subsection MySQL-python" href="#MySQL_python">MySQL-python</a> <a title="MySQL-python 1.2.2 gzipped tarball Mirrors Page" href="http://downloads.sourceforge.net/mysql-python/MySQL-python-1.2.2.tar.gz?modtime=1172959928&amp;big_mirror=0">1.2.2</a></li>
<li><a title="Subsection Django" href="#Django">Django</a> <a title="Django 1.0.2-final gzipped tarball" href="http://www.djangoproject.com/download/1.0.2/tarball/">1.0.2-final</a></li>
<li><a title="Subsection simplejson" href="#simplejson">simplejson</a> <a title="simplejson 2.0.7 gzipped tarball" href="http://pypi.python.org/packages/source/s/simplejson/simplejson-2.0.7.tar.gz#md5=9d02273f8615b8e3fceda891ffff10d1">2.0.7</a></li>
<li><a title="Subsection python-twitter" href="#python_twitter">python-twitter</a> <a title="python-twitter 0.5 gzipped tarball" href="http://python-twitter.googlecode.com/files/python-twitter-0.5.tar.gz">0.5</a></li>
<li><a title="Subsection mod_python" href="#mod_python">mod_python</a> <a title="mod_python 3.3.1 gzipped tarball Mirrors Page" href="http://httpd.apache.org/modules/python-download.cgi">3.3.1</a></li>
</ol>
<h2>Tips</h2>
<p>In the sections below, you&#8217;ll see shell commands in &lt;blockquote&gt;s, one per line. If your browser and your shell cooperate, you should be able to copy-paste these without getting extraneous line breaks; just eyeball everything before you hit return. Triple-click to select the line should work.</p>
<p>If you&#8217;re unsure of whether or not you&#8217;re actually compiling as universal binaries, just use the <code>file</code> command to check what&#8217;s contained in a binary file. You should get five lines of output listing all four architectures, like this:</p>
<blockquote><p><code>% file /usr/libexec/apache2/mod_python.so<br />
/usr/libexec/apache2/mod_python.so: Mach-O universal binary with 4 architectures<br />
/usr/libexec/apache2/mod_python.so (for architecture i386):     Mach-O bundle i386<br />
/usr/libexec/apache2/mod_python.so (for architecture x86_64):   Mach-O 64-bit bundle x86_64<br />
/usr/libexec/apache2/mod_python.so (for architecture ppc):      Mach-O bundle ppc<br />
/usr/libexec/apache2/mod_python.so (for architecture ppc64):    Mach-O 64-bit bundle ppc64<br />
</code></p></blockquote>
<h2>Compilation</h2>
<p><a name="MySQL"></a></p>
<h3>MySQL</h3>
<p>One huge caveat for this step: I compiled MySQL from source over a year ago, and I don&#8217;t remember exactly what I did. I just reused the same ./configure line that I had cached in an old config.log. The addition of multiple -arch flags initially caused a problem with running the preprocessor, but <a title="Marc Liyanage's Home Page" href="http://www.entropy.ch/home/welcome.php">Marc Liyanage</a> proved to once again be a great resource <a title="Marc Liyanage - 4-Way Universal Binary MySQL for Leopard Configuration" href="http://www.entropy.ch/blog/Mac+OS+X/2007/11/14/4-Way-Universal-Binary-MySQL-for-Leopard-Configuration.html">explaining the need</a> for the <code>--disable-dependency-tracking</code> flag.</p>
<p>If you&#8217;re replacing an existing MySQL configuration, it wouldn&#8217;t hurt to have some sort of backup of your databases. I had no problems installing, and then killing mysqld. It restarted automagically as a 64-bit process.</p>
<blockquote><p><code>cd /usr/local/src/mysql-5.1.30/</code></p>
<p><code>MACOSX_DEPLOYMENT_TARGET=10.5 CFLAGS='-arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' LDFLAGS='-arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' CXXFLAGS='-arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --disable-shared --with-unix-socket-path=/usr/local/mysql/run/mysql_socket --with-mysqld-user=_mysql --disable-dependency-tracking</code></p>
<p><code>make all</code></p>
<p><code>make test</code></p>
<p><code>sudo make install</code></p></blockquote>
<p>Note the four architecture flags set for all compiler and linker options; you&#8217;ll see those a lot throughout this post. I only allow local connections to MySQL, hence the socket path; you may use different depending on your configuration.</p>
<p><a name="Python"></a></p>
<h3>Python</h3>
<p>While python.org provides a nice OS X Installer package for 2.6.1, it is compiled as a 32-bit &#8220;fat&#8221; binary, which doesn&#8217;t help us address the Universality problem. We&#8217;ll use their script for generating a package as well as installing the framework directly, after some minor changes, courtesy <a title="Python 2.6 fails on compiling &gt; Bug report" href="http://mail.python.org/pipermail/python-list/2009-January/523565.html">this mailing list post</a> by Ned Deily.</p>
<p>If you&#8217;re feeling particularly trustworthy, you can download the disk image containing the Installer package that I built <a title="Python 2.6.1 Mac OS X Leopard Installer Package Disk Image" href="http://www.ultranurd.net/code/python/python-2.6.1-macosx2009-01-27.dmg">from my website</a>. If not, you can make the changes yourself. Either way, Python.framework will be installed in /Library/Frameworks/.</p>
<p>In the Python 2.6.1 source directory, open the file <code>Mac/BuildScript/build-installer.py</code> in your favorite editor, and make the following changes on lines 1, 65, 68, 71, 633, and 1020:</p>
<blockquote><p><code>1c1<br />
&lt; #!/usr/bin/python2.3<br />
---<br />
&gt; #!/usr/bin/python<br />
65c65<br />
&lt; DEPSRC = os.path.expanduser('~/Universal/other-sources')<br />
---<br />
&gt; #DEPSRC = os.path.expanduser('~/Universal/other-sources')<br />
68c68<br />
&lt; SDKPATH = "/Developer/SDKs/MacOSX10.4u.sdk"<br />
---<br />
&gt; SDKPATH = "/Developer/SDKs/MacOSX10.5.sdk"<br />
71c71<br />
&lt; ARCHLIST = ('i386', 'ppc',)<br />
---<br />
&gt; ARCHLIST = ('i386', 'ppc', 'x86_64', 'ppc64')<br />
633c633<br />
&lt;     runCommand("%s -C --enable-framework --enable-universalsdk=%s LDFLAGS='-g -L%s/libraries/usr/local/lib' OPT='-g -O3 -I%s/libraries/usr/local/include' 2&gt;&amp;1"%(<br />
---<br />
&gt;     runCommand("%s -C --enable-framework --enable-universalsdk=%s --with-universal-archs=all LDFLAGS='-g -L%s/libraries/usr/local/lib' OPT='-g -O3 -I%s/libraries/usr/local/include' 2&gt;&amp;1"%(<br />
1020c1020<br />
&lt;     os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.3'<br />
---<br />
&gt;     os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.5'<br />
</code></p></blockquote>
<p>You&#8217;ll note that some of the changes migrate this script to 10.5 (the hashbang path to Python, the deployment target and SDK version), and some of the changes add support for a Universal binary (adding to the architecture list. It&#8217;s possible that some of these changes will be fixed in a future source release of Python 2.6, but I&#8217;d guess that most efforts are focused on Python 3.0 at this point.</p>
<p>Once you&#8217;ve made the changes, just run the script. You need to be in the BuildScript subdirectory, unless you want to change some of the tmp paths the script uses. This script will do everything, build the framework, download and build any dependencies, install the framework, and generate a disk image. Just sit back and wait!</p>
<blockquote><p><code>cd /usr/local/src/Python-2.6.1/Mac/BuildScript/</code></p>
<p><code>./build-installer.py<br />
</code></p></blockquote>
<p>Depending on your shell configuration, you may need to make changes. In my <code>$PATH</code> <code>/usr/local/bin/</code> trumps <code>/usr/bin/</code>, and I want to keep the Leopard system install of Python 2.5 in place in <code>/System/Library/</code> and <code>/usr/bin/</code>. Here&#8217;s what I did:</p>
<blockquote><p><code>cd /usr/local/bin/</code></p>
<p><code>for py in `find /Library/Frameworks/Python.framework/Versions/2.6/bin -name py*`; do ln -s $py; done;</code></p></blockquote>
<p>This creates a symlink in <code>/usr/local/bin/</code> for each of the various just-build Python binaries inside the framework (you&#8217;ll not that this is equivalent to the system install). If you run <code>which python</code> now, it should return <code>/usr/local/bin/python</code>. If not, adjust your $PATH as needed in your shell configuration file. This is beyond the scope of this post.</p>
<p><a name="setuptools"></a></p>
<h3>setuptools</h3>
<p>This one is easy. Just execute the downloaded egg file as a shell script to add setuptools to your shiny new Python installation:</p>
<blockquote><p><code>cd /usr/local/src/</code></p>
<p><code>sh setuptools-0.6c9-py2.6.egg</code></p></blockquote>
<p><a name="MySQL_python"></a></p>
<h3>MySQL-python</h3>
<p>MySQL-python installs using setuptools, as with most Python packages these days; however, we&#8217;ll need to make a few changes to get the C part of the extension to compile on OS X. I followed mickeyckm&#8217;s <a title="Installing Python MySQLdb 1.2.2 on Mac OS X" href="http://www.mangoorange.com/2008/08/01/installing-python-mysqldb-122-on-mac-os-x/">guide</a> over at <a title="MangoOrange - Home of the Most Downloaded Mac WordPress Theme" href="http://www.mangoorange.com/">MangoOrange</a>, which I&#8217;ve modified here to support all four architectures after looking at <a title="Re: Huge problem gettng MySQLdb to work on my mac mini running Macosx 10.5 Leopard" href="http://www.opensubscriber.com/message/python-list@python.org/8833601.html">suggestions from Geert</a> on the Python mailing list. Note that his manual compilation step isn&#8217;t necessary, from what I can tell.</p>
<p>First, you&#8217;ll need to modify <code>site.cfg</code> to point to the custom build of MySQL we created above; just uncomment and change the value of <code>mysql_config</code> on line 13 to match its actual install path as follows:</p>
<blockquote><p><code>13c13<br />
&lt; #mysql_config = /usr/local/bin/mysql_config<br />
---<br />
&gt; mysql_config = /usr/local/mysql/bin/mysql_config<br />
</code></p></blockquote>
<p>The setup script for MySQL-python uses this tool to retrieve the compilation flags used with MySQL; since we built our own, this will automatically have all four architecture flags. You can run <code>mysql_config</code> directly and view the output if you don&#8217;t believe me.</p>
<p><code><span style="font-family: Georgia;">Next, we need to make a small correction to <code>_mysql.c</code> in order to avoid a type conflict on OS X by deleting lines 37-39 and replacing <code>uint</code> with <code>unsigned int</code> on lines 484 and 485:</span></code></p>
<blockquote><p><code>37,39d36<br />
&lt; #ifndef uint<br />
&lt; #define uint unsigned int<br />
&lt; #endif<br />
484,485c481,482<br />
&lt;       uint port = MYSQL_PORT;<br />
&lt;       uint client_flag = 0;<br />
---<br />
&gt;       unsigned int port = MYSQL_PORT;<br />
&gt;       unsigned int client_flag = 0;<br />
</code></p></blockquote>
<p>Now we&#8217;re ready to build and install. Just run the standard setuptools procedure:</p>
<blockquote><p><code>cd /usr/local/src/MySQL-python-1.2.2/</code></p>
<p><code>python setup.py build</code></p>
<p><code>sudo python setup.py install</code></p></blockquote>
<p><a name="Django"></a></p>
<h3>Django</h3>
<p> </p>
<p>No special instructions here. Just run the standard setuptools procedure:</p>
<blockquote><p><code>cd /usr/local/src/Django-1.0.2-final/</code></p>
<p><code>python setup.py build</code></p>
<p><code>sudo python setup.py install</code></p></blockquote>
<p><a name="simplejson"></a></p>
<h3>simplejson</h3>
<p>No special instructions here either. Just run the standard setuptools procedure:</p>
<blockquote><p><code>cd /usr/local/src/simplejson-2.0.7/</code></p>
<p><code>python setup.py build</code></p>
<p><code>python setup.py test</code></p>
<p><code>sudo python setup.py install</code></p></blockquote>
<p><a name="python_twitter"></a></p>
<h3>python-twitter</h3>
<p>Don&#8217;t you love it when how-tos get easier as you go along? Just run the standard setuptools procedure:</p>
<blockquote><p><code>cd /usr/local/src/python-twitter-0.5/</code></p>
<p><code>python setup.py build</code></p>
<p><code>sudo python setup.py install</code></p></blockquote>
<p><a name="mod_python"></a></p>
<h3>mod_python</h3>
<p>Sadly, we end with some pain. Long story short, <code>mod_python</code> relies on <code>apxs</code> (the <a title="APache eXtenSion tool" href="http://httpd.apache.org/docs/2.2/programs/apxs.html">APache eXtenSion tool</a>, best abbreviation ever) to configure its build, and does not obey any amount of environment variable manipulation to pass in multiple architectures. <code>apxs</code> retrieves useful compiler options, apparently based on the ones used to build your local copy apache&#8230; and herein lies the problem. <code>apxs</code> reads those flags from <code>/usr/share/httpd/build/config_vars.mk</code>, and if you inspect that file, you&#8217;ll see that there are no <code>CFLAGS</code> or <code>LDFLAGS</code> specified. This is particularly odd, considering that <code>httpd</code> is clearly running as a 64-bit process (according to Activity Monitor), and <code>file</code> reports that all of my other shared objects in <code>/usr/libexec/apache2/</code> are Universal binaries.</p>
<p>This next bit is my idea, since I couldn&#8217;t find any suggestions by googling around. I know perl, so I just read the <code>apxs</code> script to figure out what it was doing, and how it was passing arguments to <code>libtool</code>.</p>
<p><strong>This is probably a terrible idea.</strong></p>
<p>Make a backup of <code>config_vars.mk</code> before adding the four architecture flags to <code>CFLAGS</code> and <code>LDFLAGS</code> on lines 59 and 62:</p>
<blockquote><p><code>59c59<br />
< CFLAGS =<br />
---<br />
> CFLAGS = -arch i386 -arch x86_64 -arch ppc7400 -arch ppc64<br />
62c62<br />
< LDFLAGS =<br />
---<br />
> LDFLAGS = -arch i386 -arch x86_64 -arch ppc7400 -arch ppc64<br />
</code></p></blockquote>
<p>If you run <code>apxs -q CFLAGS</code> or <code>apxs -q LDFLAGS</code>, you&#8217;ll see these values, instead of empty strings.</p>
<p>Now just run the standard autoconf procedure to build and  install <code>mod_python.so</code> in <code>/usr/libexec/apache2/</code>:</p>
<blockquote><p><code>cd /usr/local/src/mod_python-3.3.1/</code></p>
<p><code>./configure</code></p>
<p><code>make</code></p>
<p><code>cd test</code></p>
<p><code>python test.py</code></p>
<p><code>cd ..</code></p>
<p><code>make</code></p>
<p><code>sudo make install</code></p></blockquote>
<h2>Conclusion</h2>
<p>At this point, you need to enable <code>mod_python</code> in your <code>httpd.conf</code>. If you passed the tests for it above, you shouldn&#8217;t need to worry about module issues, just double-check your configuration with <code>sudo apachectl -t</code>. When you&#8217;re ready to go, <code>sudo apachectl restart</code>, and welcome to the world of 64-bit.</p>
<p>If you have corrections to any of this, or need assistance, feel free to comment and I&#8217;ll try to get back to you with suggestions and/or edits.</p>
<div class='wb_fb_bottom'><div style="float:right;"></div></div>]]></content:encoded>
			<wfw:commentRss>http://blog.ultranurd.net/2009/01/28/compiling-django-with-twitter-support-as-a-mac-os-x-universal-binary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Local Version Control With Git</title>
		<link>http://blog.ultranurd.net/2009/01/21/local-version-control-with-git/</link>
		<comments>http://blog.ultranurd.net/2009/01/21/local-version-control-with-git/#comments</comments>
		<pubDate>Wed, 21 Jan 2009 18:46:36 +0000</pubDate>
		<dc:creator>Nicolas Ward</dc:creator>
				<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[version control]]></category>

		<guid isPermaLink="false">http://blog.ultranurd.net/?p=481</guid>
		<description><![CDATA[Introduction I&#8217;ve recently become obsessed with git for version control. I know that there are many git tutorials out there; this is probably redundant, but it focuses on only the simplest operations for my own reference. The git man pages themselves are extremely well written. This post is an adaptation of an article I wrote for our [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>I&#8217;ve recently become obsessed with <a title="Git Homepage" href="http://git-scm.com/">git</a> for version control. I know that there are <a title="git-tutorial man page" href="http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html">many</a> <a title="Git-SVN Crash Course" href="http://git.or.cz/course/svn.html">git</a> <a title="Using Git Without Feeling Stupid" href="http://smalltalk.gnu.org/blog/bonzinip/using-git-without-feeling-stupid-part-1">tutorials</a> out there; this is probably redundant, but it focuses on only the simplest operations for my own reference. The git man pages themselves are extremely well written. This post is an adaptation of an article I wrote for our department wiki, targeted at some of my fellow researchers who have probably never heard of git. I removed all of the references to our internal projects.</p>
<p>Unfortunately, one of our major codebases at work is stored in a <a title="Visual SourceSafe 2005" href="http://msdn.microsoft.com/en-us/vstudio/aa718670.aspx">Microsoft Visual SourceSafe</a> repository; it has been for years, and there&#8217;s enough momentum that we likely won&#8217;t move to a better version control system any time soon. If the motivation sounds odd, I mostly write research code, so we are regularly creating totally new code that may be used once or twice and then never again.</p>
<p>Visual SourceSafe has limited branching capabilities, so many users keep large subsets of the codebase checked out onto their development machine. When a major experimental change is feature-complete, dealing with merges in VSS is a pain that typically involves face-to-face negotiations of who checks in what when, or one person spending a day or two fixing conflicts in WinMerge or a similar tool. This article demonstrates how to use git, a modern distributed version control system used by the Linux kernel (among others), to manage smaller-scale changes to VSS code trees on Windows without having to risk checking in files that &#8220;break&#8221; functionality for other users.</p>
<p>The main point of using a local version control repository inside of a VSS checkout is three-fold:</p>
<ol>
<li>Commit more often</li>
<li>Easy branching for experimental code (whether or not it pans out)</li>
<li>More detailed history/self-documentation of recent changes</li>
</ol>
<p>I&#8217;ve found that my development habits have gotten much better using git; in particular, I commit just about every successful compile-and-test, and I try to isolate commits by functionality as much as possible, so that it&#8217;s trivial to cherry pick experimental changes that should be kept or not.</p>
<p><span id="more-481"></span></p>
<h2>Setup</h2>
<h3><span class="mw-headline">Install Git</span></h3>
<p>You&#8217;ll only need to do these steps once on your development machine.</p>
<ol>
<li>Get git
<ol>
<li>If you don&#8217;t have it archived, get the latest version of Cygwin&#8217;s <a class="external text" title="http://www.cygwin.com/setup.exe" rel="nofollow" href="http://www.cygwin.com/setup.exe">setup.exe</a>.</li>
<li>Run setup.exe, accept the cached repository and install locations</li>
<li>Find git in the list (in category Devel), and set it to install</li>
<li>Accept and finish the Cygwin incremental install</li>
</ol>
</li>
<li>Configure git
<ol>
<li>Open a Cygwin shell</li>
<li>Run these git setup commands to set authorship:</li>
<p><code> $ git config --global user.name "Your Name"<br />
$ git config --global user.email "yname@you.com"</code></p>
<li>Run these git setup commands to avoid choking on Windows newlines</li>
<p><code> $ git config --global core.autocrlf true</code></ol>
</li>
</ol>
<h3>Create Git Repository</h3>
<p>You&#8217;ll do this once for each working directory you create as per above. The commands below assume that you&#8217;re working in c:/Projects/HelloWorld/.</p>
<ol>
<li>Create Repository</li>
<p><code> $ cd c:/Projects/<br />
$ mkdir HelloWorld<br />
$ cd HelloWorld<br />
$ git init<br />
Initialized empty Git repository in c:/Projects/HelloWorld/.git/</code></p>
<li>Configure Repository
<ol>
<li>Tell git to ignore certain Visual Studio/SourceSafe files that change constantly</li>
<p><code> $ echo -e "*.user\n*.ncb\n*.suo" &gt;&gt; .git/info/exclude</code></p>
<li>See man git-config for more options</li>
</ol>
</li>
<li>Initial check-in
<ol>
<li>Tell git which files you&#8217;re checking in</li>
<p><code> $ git add &lt;project subdirs&gt;</code></p>
<li>Commit all files (this may take a minute or two)</li>
<p><code> $ git commit -m "Initial check-in"</code></ol>
</li>
</ol>
<h2>Usage</h2>
<p>This section is divided into common operations. One important note: the commands can be run from any subdirectory of the repository you created above, but most operations apply to the entire tree. The git manpages are excellent, and can explain further. There are a ton of options, but these get at the core functionality you&#8217;re likely to use working on most codebases.</p>
<h3>View Changes</h3>
<p>There are two commands useful here:<br />
<code> $ git status<br />
$ git diff</code><br />
One conceptual caveat: files that are pending a commit get added to the repository&#8217;s index. They&#8217;ll be listed in the status, but won&#8217;t appear in diffs. Be especially careful about using wildcards with the add command, because you generally don&#8217;t want to commit binaries or intermediate build files.</p>
<p>status will tell you which branch you are on, which files have been added to the index but not yet commited, which files have changed since the last commit but haven&#8217;t been added to the index, and which files aren&#8217;t being tracked by git. New files you create will appear in this list, among build directories you&#8217;re probably ignoring. For each file it will tell you if it&#8217;s been added, deleted, or modified.</p>
<p>diff will pass the output of diff for each file that has changed since the last commit but hasn&#8217;t been added yet to the index. This is a very detailed view, I generally use this to make sure that I&#8217;ve added everything I want before committing.</p>
<h3>Commit Changes</h3>
<p>This is one of the big advantages to local version control: you can commit after even the most trivial change, at least once you&#8217;re sure it works.</p>
<p>There are two commands that you&#8217;ll use for this process:<br />
<code> $ git add &lt;file/dir to add&gt; ...<br />
 $ git commit -m "Message for log"</code><br />
Be very careful specifying directories when adding; git will add any unknown file contained in all subdirectories, which might end up adding a bunch of build files you don&#8217;t want.</p>
<p>In general, I use status and diff (described under View Changes above) to see what I&#8217;ve changed since the last commit, and to make sure I&#8217;ve added everything relevant before committing.</p>
<h3>Tag</h3>
<p>By default, tagging always applies to the most recent commit. If you have uncommitted changes, they won&#8217;t be under the tag. Tags can&#8217;t have spaces.</p>
<p>The usage is simple:<br />
<code> $ git tag -m "Message for log" "my-tag-name"</code></p>
<h3>Move/Rename/Delete Files</h3>
<p>It is very important that you <strong>never</strong> use rm or mv inside of a git repository, because git is likely to get confused about what happened to the files. This includes renaming files inside of Visual Studio, since VS2005 effectively performs a mv behind the scenes. It&#8217;s not the end of the world if you do it, you just clobber the file history (git sees it as a delete followed by an unrelated create).</p>
<p>The commands for doing this are:<br />
<code> $ git rm &lt;file to remove&gt; ...<br />
 $ git mv &lt;source path&gt; &lt;destination path&gt;</code><br />
They otherwise work exactly like the shell command, they just inform the repository of the change. The changes are automatically added to the index, ready for committing; if you further change a moved file, you&#8217;ll still need to add it from its new location.</p>
<h3>Use Branches</h3>
<p>Let&#8217;s say you&#8217;re trying out some new functionality, but it&#8217;s just not going anywhere. Maybe you&#8217;re adding some new functionality, but you need to hop back to the last working commit to build but you don&#8217;t want to lose your work. These are just a few of the cases where you might want to branch. You can also branch preemptively.</p>
<ul>
<li>Create a new branch to contain current/future changes</li>
<p><code> $ git checkout -b &lt;branch name&gt;<br />
(edit file, if necessary)<br />
$ git add &lt;broken files&gt;<br />
$ git commit -m "Stuff I broke"</code></p>
<li>Switch between branches (this will replace files, make sure your changes are committed to the correct branch)</li>
<p><code> $ git checkout master<br />
(in master branch)<br />
$ git checkout experimental<br />
(in experimental branch)</code></p>
<li>List all branches (* indicates current branch)</li>
<p><code> $ git branch<br />
  experimental<br />
* master</code></p>
<li>There are two ways to delete a branch:
<ul>
<li>-d makes sure that the changes have been committed to the master branch</li>
<li>-D just nukes the entire branch and all of its changes, committed or not</li>
</ul>
<p><code> $ git branch -d &lt;branch name&gt;<br />
$ git branch -D &lt;branch name&gt;</code></li>
<li>Merging between branches is also easy:</li>
<p><code> $ git checkout target<br />
(in target branch)<br />
$ git merge source<br />
(all non-conflicting commits from source will be added to target)</code></ul>
<h3>Sharing Repositories</h3>
<p>Just make your working directory accessible as a shared folder, and another person on the network can get your complete working tree (with commit history and branches) by creating a new repository and pulling from your repository.<br />
<code> $ cd c:/Projects<br />
$ mkdir HelloWorld<br />
$ cd HelloWorld<br />
$ git init<br />
$ git pull //yourcomputer/Projects/HelloWorld/</code></p>
<div class='wb_fb_bottom'><div style="float:right;"></div></div>]]></content:encoded>
			<wfw:commentRss>http://blog.ultranurd.net/2009/01/21/local-version-control-with-git/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Vortex Cannon</title>
		<link>http://blog.ultranurd.net/2009/01/18/vortex-cannon/</link>
		<comments>http://blog.ultranurd.net/2009/01/18/vortex-cannon/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 05:57:08 +0000</pubDate>
		<dc:creator>Nicolas Ward</dc:creator>
				<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[big brother]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[science]]></category>

		<guid isPermaLink="false">http://blog.ultranurd.net/?p=473</guid>
		<description><![CDATA[Introduction I generally do Big Brother on Saturday afternoons from about 2 to 6 at Patrick&#8217;s house near Central Square. Sometimes we go out for a museum (a trip to the Museum of Science is likely next week), or a movie, but this week I didn&#8217;t have any ideas. Patrick had previously showed me some [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>I generally do Big Brother on Saturday afternoons from about 2 to 6 at Patrick&#8217;s house near Central Square. Sometimes we go out for a museum (a trip to the Museum of Science is likely next week), or a movie, but this week I didn&#8217;t have any ideas. Patrick had previously showed me some YouTube videos of  <a title="Water Balls Demonstration" href="http://www.youtube.com/watch?v=eNvZLTkj2kw">water balls</a>, and we&#8217;ve done &#8220;kitchen science&#8221; before, so I was looking into that this morning&#8230; but it looked like the listed materials would be hard to obtain, and a number of comments claimed that the video was fake. However, in the related videos, I stumbled across <a title="Vortex Cannon" href="http://www.thenakedscientists.com/HTML/content/kitchenscience/exp/vortex-cannon/">this page on vortex cannons</a>, and decided that would make a fun quick activity. Unfortunately, because I&#8217;m an idiot, I didn&#8217;t take any pictures &gt;.&lt;.</p>
<h2>Materials</h2>
<p>Due to the supplies at hand, we had to use a slightly different procedure, but the visual effect was pretty impressive.</p>
<ul>
<li>One (1) 1-liter plastic bottle, empty and dry</li>
<li>One (1) tea candle target</li>
<li>One (1) fog machine</li>
<li>Matches (or some other candle-lighting device)</li>
<li>A room with still air</li>
</ul>
<h2>Procedure</h2>
<p>We found two techniques worked pretty well, but produced very different results. One, when combined with the fog machine, allowed us to really visualize what was happen, and gave me the opportunity to explain some of the science to Patrick; the other actually put the candle out.</p>
<p>We first tried it without the fog machine, but couldn&#8217;t get the candle to blow out; it turned out that our aim was a bit off. The chemical fog stuff (part of an old Halloween setup) allowed us to actually see and aim the smoke rings, and see the vortices forming.</p>
<p>Grabbing the bottle with both hands and squeezing in a quick pulse produces a large, slow-moving smoke ring, with a long-lasting vortex that you can watch stretch as the ring expands. If you squeeze too hard, you just get a turbulent puff; too soft and you get nothing. It takes some trial and error. While these were nifty to look at, they couldn&#8217;t put out the candle, even from only a few centimeters away.</p>
<p>I found tapping one side of the bottle with just two fingertips, very firmly, produced a small but fast burst that formed a very fast-moving smoke ring. You could barely tell it was a ring at that speed. They moved fairly straight (as opposed to the slower-moving rings that tended to drift a bit), but were a bit touchy to aim. Once you connected with the candle flame, it went right out, without any guttering as you would see when trying to blow it out manually. We were able to successfully put the candle out at about a meter.</p>
<h2> Conclusion</h2>
<p>This was a very fun demonstration, and only took a few minutes to set up. It also requires no cleanup, and you can hypothetically sneak up on your little sister and blow smoke rings at her. Not that I would encourage that sort of sibling mischief&#8230;</p>
<p>One thing I needed was a concrete example of why this is important science, and not just a toy demonstration. It&#8217;s hard to explain fluid dynamics to a ten year old. Patrick enjoyed it as a project, though.</p>
<div class='wb_fb_bottom'><div style="float:right;"></div></div>]]></content:encoded>
			<wfw:commentRss>http://blog.ultranurd.net/2009/01/18/vortex-cannon/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
