Global git config for tracking master against origin
Tired of doing a git push origin master when git push should be enough? Google tells you to add the following to your project’s .git/config file:
[branch "master"]
remote = origin
merge = refs/heads/master
While that works fine, it’s a bit of a pain to do every time I start working on a new project. Instead, you can set that globally like so:
git config --global branch.master.remote origin
git config --global branch.master.merge refs/heads/master
Now, running git push while in the master branch of your project will push the changes up to origin (which is most likely github).
While we’re in there, let’s tell git to always use --rebase when pulling into master, since we’re a bit hater of the merge commits:
git config --global branch.master.rebase true
Note: I have this configured locally, and the only issue I’ve found is when I also have the changes in my .git/config file. When I try to push, git complains thusly: fatal: The current branch master is tracking multiple branches, refusing to push. It’s a simple enough matter to remove the master configuration from the local .git/config file.
Engine Yard University: Zero to Rails 3
For the past few months, I’ve been working on something pretty exciting: Engine Yard University.
Engine Yard came to me to produce their training curriculum, and their first course, Zero to Rails 3 is now live. Zero to Rails 3 is a three day, hands on workshop in San Francisco taught by Randall Thomas and myself.
With technical help and direction from Yehuda Katz, Ezra Zygmuntowicz, and others, it covers everything you need to get your team started developing successful Rails 3 applications.

Engine Yard University courses are designed to get enterprise development teams up to speed quickly on Rails, JRuby, Agile development, and other technologies.
Engine Yard University is much more than just this first course. We’re working on a full curriculum for enterprise teams covering everything from Agile to Scaling, and for every member of the team from Ops to Management.
We’ll also be bringing the show to your door. Let us know if you’re interested in a custom, in-house workshop for your team.
The Modern Vim Config with Pathogen
Unix gets a whole lot right, but the way it dumps everything into the same filesystem isn’t one of them. Traditionally, every application you install will put files under /etc, /usr/bin, /var, /lib, and so on. This makes it impossible to confidently extract an installed application, and lead to the development of various package management tools.
Vim’s legacy
Unfortunately, Vim inherited that original philosophy. Terribly misguided attempts have been made in the past to create a package management system for Vim plugins. The Vimball format is particularly painful – non-standard file format, unusable from the commandline, and all files dropped under ~/.vim willy-nilly.
Pathogen
Thankfully, our hero Tim Pope has penned pathogen.vim – a sane package manager for Vim plugins. With pathogen, all of your plugins are stored in separate directories under ~/.vim/bundle:
~/.vim $ ls bundle
IndexedSearch vim-align vim-rails vim-surround
gist vim-cucumber vim-repeat vim-tcomment
jquery vim-fugitive vim-ruby vim-vividchalk
nerdtree vim-git vim-ruby-debugger
snipmate.vim vim-haml vim-shoulda
textile.vim vim-markdown vim-supertab
This means removing a plugin is as simple as deleting that directory. Just the way it should be.
Installation
To get started, I recommend moving your ~/.vim directory out of the way and starting fresh. Then make the ~/.vim/autoload directory and download the pathogen.vim file there.
~/.vim master $ ls autoload
pathogen.vim
Now call pathogen from your .vimrc like such:
" Needed on some linux distros.
" see http://www.adamlowe.me/2009/12/vim-destroys-all-other-rails-editors.html
filetype off
call pathogen#helptags()
call pathogen#runtime_append_all_bundles()
…and that’s it! This is the only plugin you’ll install directly into your ~/.vim directory. After that, any plugin you install into the ~/.vim/bundle directory will be seen by vim. At this point, you can start copying in the contents of your .vimrc and .gvimrc files, taking the time to clean them up as you go.
Automation
To make management of the bundle directory a little easier, I penned up a quick ruby script, which I saved as ~/.vim/update_bundles. Running this script will remove all plugins you’ve installed manually, and will update them to the latest versions.
#!/usr/bin/env ruby
git_bundles = [
"git://github.com/astashov/vim-ruby-debugger.git",
"git://github.com/msanders/snipmate.vim.git",
"git://github.com/scrooloose/nerdtree.git",
"git://github.com/timcharper/textile.vim.git",
"git://github.com/tpope/vim-cucumber.git",
"git://github.com/tpope/vim-fugitive.git",
"git://github.com/tpope/vim-git.git",
"git://github.com/tpope/vim-haml.git",
"git://github.com/tpope/vim-markdown.git",
"git://github.com/tpope/vim-rails.git",
"git://github.com/tpope/vim-repeat.git",
"git://github.com/tpope/vim-surround.git",
"git://github.com/tpope/vim-vividchalk.git",
"git://github.com/tsaleh/vim-align.git",
"git://github.com/tsaleh/vim-shoulda.git",
"git://github.com/tsaleh/vim-supertab.git",
"git://github.com/tsaleh/vim-tcomment.git",
"git://github.com/vim-ruby/vim-ruby.git",
]
vim_org_scripts = [
["IndexedSearch", "7062", "plugin"],
["gist", "12732", "plugin"],
["jquery", "12107", "syntax"],
]
require 'fileutils'
require 'open-uri'
bundles_dir = File.join(File.dirname(__FILE__), "bundle")
FileUtils.cd(bundles_dir)
puts "Trashing everything (lookout!)"
Dir["*"].each {|d| FileUtils.rm_rf d }
git_bundles.each do |url|
dir = url.split('/').last.sub(/\.git$/, '')
puts " Unpacking #{url} into #{dir}"
`git clone #{url} #{dir}`
FileUtils.rm_rf(File.join(dir, ".git"))
end
vim_org_scripts.each do |name, script_id, script_type|
puts " Downloading #{name}"
local_file = File.join(name, script_type, "#{name}.vim")
FileUtils.mkdir_p(File.dirname(local_file))
File.open(local_file, "w") do |file|
file << open("http://www.vim.org/scripts/download_script.php?src_id=#{script_id}").read
end
end
A Better RVM Bash Prompt
Not knowing where you are while using RVM can be a frustrating experience. Which version of ruby am I using? Which gemset? And using per-project .rvmrc files, while super-cool, makes the situation even worse.
RVM ships with the rvm-prompt script, which you can use in your $PS1 setup, but it neglects gemsets, and doesn’t skip default values.
Problem, meet Solution.
So, here’s a new bash prompt function that prints the RVM ruby version and gemset, but only if they’re different from the defaults.
function __git_dirty {
git diff --quiet HEAD &>/dev/null
[ $? == 1 ] && echo "!"
}
function __git_branch {
__git_ps1 " %s"
}
function __my_rvm_ruby_version {
local gemset=$(echo $GEM_HOME | awk -F'@' '{print $2}')
[ "$gemset" != "" ] && gemset="@$gemset"
local version=$(echo $MY_RUBY_HOME | awk -F'-' '{print $2}')
[ "$version" == "1.8.7" ] && version=""
local full="$version$gemset"
[ "$full" != "" ] && echo "$full "
}
bash_prompt() {
local NONE="\[\033[0m\]" # unsets color to term's fg color
# regular colors
local K="\[\033[0;30m\]" # black
local R="\[\033[0;31m\]" # red
local G="\[\033[0;32m\]" # green
local Y="\[\033[0;33m\]" # yellow
local B="\[\033[0;34m\]" # blue
local M="\[\033[0;35m\]" # magenta
local C="\[\033[0;36m\]" # cyan
local W="\[\033[0;37m\]" # white
# emphasized (bolded) colors
local EMK="\[\033[1;30m\]"
local EMR="\[\033[1;31m\]"
local EMG="\[\033[1;32m\]"
local EMY="\[\033[1;33m\]"
local EMB="\[\033[1;34m\]"
local EMM="\[\033[1;35m\]"
local EMC="\[\033[1;36m\]"
local EMW="\[\033[1;37m\]"
# background colors
local BGK="\[\033[40m\]"
local BGR="\[\033[41m\]"
local BGG="\[\033[42m\]"
local BGY="\[\033[43m\]"
local BGB="\[\033[44m\]"
local BGM="\[\033[45m\]"
local BGC="\[\033[46m\]"
local BGW="\[\033[47m\]"
local UC=$W # user's color
[ $UID -eq "0" ] && UC=$R # root's color
PS1="$B\$(__my_rvm_ruby_version)$Y\h$W:$EMY\w$EMW\$(__git_branch)$EMY\$(__git_dirty)${NONE} $ "
}
bash_prompt
unset bash_prompt
And here’s the result (minus my color codes):
tardis:~ $ rvm 1.9.1
1.9.1 tardis:~ $ rvm gemset use rail3
Now using gemset 'rail3'
1.9.1%rail3 tardis:~ $ rvm default
tardis:~ $
Update: Looks like I was a version behind on RVM, but the new rvm-prompt still doesn’t handle defaults. I’ve also updated the code to account for the change from % to @.
Upcoming Speaking Engagements
I’m booked to speak at two upcoming presentations. If you’re going to be coming to either the Scottish Ruby Conference or RailsConf 2010, then be sure to say hi!
Scottish Ruby Conference
At the Scottish Ruby Conference, I’ll be presenting “You’re Doing it Wrong,” an overview of Rails AntiPatterns I’ve seen in the wild, and ways to avoid or fix them. Here’s an interview I did with Seth Ladd of Aloha on Rails where I presented the same material:
RailsConf 2010
Chad Pytel and I will be running a three hour tutorial on Avoiding and Fixing Rails AntiPatterns at RailsConf 2010. This is a greatly expanded version of the presentation above, and will go into greater depth on specific AntiPatterns. We’ll also be taking attendee submissions during the class for fixing.
Both of these presentations are samples of the content from Chad and my upcoming Rails AntiPatterns book.
Easy iPhone telephone links in Rails
Some sites, when viewed through an iPhone, have clickable phone numbers, which can be dialed immediately.

Some sites, on the other hand, require the user to copy the phone number and paste it into the dialer manually.
Which ones do you think get more phone calls?
The secret to the clickable phone numbers lies in RFC 3966, which defines the tel: link format. Here’s a quick helper that makes tel: links a breeze.
module ApplicationHelper
def phone_number_link(text)
sets_of_numbers = text.scan(/[0-9]+/)
number = "+1-#{sets_of_numbers.join('-')}"
link_to text, "tel:#{number}"
end
end
Toss that in your app, and you can effortlessly make any phone number into a link. The helper pulls out the numbers and pushes them back together in the standard “+1-xxx-xxx-xxxx” format. …which means you can use it with a variety of strings:
I'd love to hear about your project. Give me a call at
= phone_number_link("(626) 841-0708,")
and we can discuss your needs.
Cheers!


