Hardscrabble 🍫

By Max Jacobson

idempotent

29 Nov 2014

HTTP GET requests are supposed to be idempotent, but they often have the side effect of appending some request details to a log file, which can eventually grow so large that it fills the disk and takes down the server.

git fresh branch

28 Nov 2014

Tonight while clicking around the web I discovered tj/git-extras, a set of useful git tools maintained by TJ Holowaychuk1. Once installed, your git command is overloaded with a bunch of new, useful commands.

It’s easy to install, but it does add quite a lot of stuff, and I was worried for a moment that it would clobber some existing aliases of my own. One, git squash, comes dangerously close to my beloved git squasher, but doesn’t actually conflict.

If you are worried about it, you can safely pick and choose which extras you want by saving individual scripts and just making sure they’re all on your PATH and executable.

The readme explains their purposes nicely, but I want to emphasize one in particular: git fresh-branch <branch name> which does stuff I didn’t know was possible.

Let’s say you’re maintaining an open source library that has existed long enough to accumulate many commits and files. Let’s say you want to create a github page for that library to explain what it’s all about and how to use it. The way github pages works, you should create a new branch in the same repo with the branch name gh-pages, and on that branch you keep a set of assets that will become a static website. But when you create a new branch, it will have all of the code from your open source library, and an entire history of commmits. I can imagine doing something like this:

# create a new branch
git checkout -b gh-pages
# delete all of the existing files
git ls-files | xargs rm
# stage those deletes
git add -A
# commit the change
git commit -m 'BURN IT DOWN'

# create the first version of the site
echo 'hello! use my gem!' > index.html
git add index.html
git commit -m 'gh-pages init'
git push origin gh-pages

And then I’d wait for GitHub to do its magic and expect to see my great page online in a few minutes.

It’s kind of awkward having a ‘BURN IT DOWN’ commit, but I didn’t know there was an alternative. With git extras, that could look more like this:

# create a new branch WITH NO HISTORY AT ALL
# NOT ONE COMMIT
git fresh-branch gh-pages

# create the first version of the site
echo 'hello! use my gem!' > index.html
git add index.html
git commit -m 'gh-pages init'
git push origin gh-pages

How the heck does it work? We can look at the fresh-branch script online, but I’ll include the latest version here for reference:

#!/bin/sh

branch=$1

test -z $branch && echo "branch required." 1>&2 && exit 1

git symbolic-ref HEAD refs/heads/$branch
rm .git/index
git clean -fdx

I guess a lot of the work is being done by symbolic-ref.

While researching this post, I noticed that git-extras also offers a gh-pages script that is even more tailored to the use case from my example. Of course! :leaves:


edit: I probably should have slept on this post and actually explored more how it’s working under the hood. But I did not.

  1. Formerly ‘visionmedia’ on GitHub 

ruby-build, chruby, and yosemite

19 Oct 2014

A few months ago I stopped using rvm to install and manage my ruby installations on my computers. I don’t have a great reason, other than reading that Steve Klabnik uses something else and I felt like trying it one day.

What I use now:

ruby-build

This is how I install rubies:

  • brew install ruby-build – get ruby-build
  • mkdir ~/.rubies – this is where rubies and gems will go
  • ruby-build --definitions – shows you a list of all the available rubies. When new ones come out, you should be able to just brew update and brew upgrade ruby-build to get access to those new definitions
  • ruby-build 2.1.3 ~/.rubies/2.1.3 – first argument is the name of the definition from the previous step, and the second argument is where to install all the code
  • watch it install

chruby

This is how I switch between versions of ruby.

setup

The instructions in the readme are good. The gist is that you install a script and then source it from your ~/.bashrc so it will be included in your shell sessions. This exposes a chruby bash function, which you can thereafter reference from the shell to switch between rubies (eg chruby 2.1.2) or even later in your ~/.bashrc, to choose a ruby immediately upon starting a shell session. This will look in the ~/.rubies folder by default, which is why I install my rubies there.

Yosemite…

So this all stopped working on my laptop yesterday when I upgraded to Mac OS X 10.10 (Yosemite). I couldn’t run bundle install without getting a nasty error, and I became convinced that I needed to rebuild all of my rubies. So I thought “OK, I know how to do that” and ran rm -rf ~/.rubies and set about following those steps under “ruby-build” above.

It didn’t work, so I went to sleep.

Long story short, this fix worked: https://github.com/sstephenson/rbenv/issues/610#issuecomment-58804829

Where before you would have run ruby-build 2.1.3 ~/.rubies/2.1.3, now (until ruby-build makes a fix) you can run CC=clang ruby-build 2.1.3 ~/.rubies/2.1.3.

I don’t know if rvm had this problem. I wouldn’t be surprised if they did, and it was fixed quickly. But like. It’s kind of cool to use smaller tools sometimes.