Enhanced Ass-Kicking with Git

Isn’t Git already great out of the box?

Well, yes.

But its interface was clearly designed by programmers. Its configuration almost makes up for this.

Almost.

Step 0: Before We Begin

Stay Up-To-Date

It helps to stay up-to-date, though. Things keep getting better with each release.

brew update
brew upgrade git

It also makes sense to keep your ~/.gitconfig in ~/Dropbox elsewhere shared among your computers.

You should keep all your dotfiles there or a Git project, but that's a topic for another day.

Save Your Fingers

You're going to type git a lot throughout the day. Why not make it a little easier?

Put this in your .bashrc, .profile, or wherever:

alias g=git 

Now you'll just need to type g to use Git: e.g., g config, g commit, and g clone.

Not Just Git, Either

You should make simple-to-remember aliases for all commands you type frequently throughout the day. Some examples:

Step 1: Git’s Config Files

Git to Know Your Config

You've already got one in ~/.gitconfig for global settings and .git/config in any Git project.

See What's There

g config --list to see all of the current settings.

g config --list --global to see just the settings from ~/.gitconfig.

g config --list --local to see just the settings from .git/config.

Add or update values with g config --global foo.bar baz to set foo.bar to baz.

Find Out More

g help config gives a fairly exhaustive list of available configuration options.

Some Nicer Defaults

Enable these settings by prefixing with g config --global.

Color in output (diffs, file status, etc.)
color.ui auto
Push tracking branch by default
push.default tracking
Use FileMerge for merging (comes with Xcode)
diff.tool opendiff
merge.tool opendiff
difftool.prompt false
mergetool.prompt false
Prettier, more useful log messages
format.pretty '%Cred%h%Creset %aN -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset'
8bc36cb Patrick Byrne - (origin/master, origin/HEAD, master) Update to new shared DB IP address (9 days ago)
Ignore Windows linefeeds
core.autocrlf input
Remember how I last handled this merge conflict
rerere.enabled true

Step 2: Aliases

What?

This is where you really make Git your own. Create custom commands to do exactly what you want.

Two Kinds of Aliases

Standard aliases

alias.co checkout

Essentially a find and replace. g co master expands to g checkout master.

Shell Aliases

alias.dm '!git diff | mate'

Aliases prefixed with with a bang are performed as if you'd typed them into the shell. This lets you perform more complex interactions with Git.

Why?

To make your most frequently used commands (e.g., push, pull, commit, merge, checkout, diff) even quicker and easier to type (e.g., p, u, c, m, co, d).

To make less frequently used commands easier to remember. For example, edit the last commit with g amend instead of g commit --amend or view everything about a specific commit with g details 43344a2 instead of log -n1 -p --format=fuller 43344a2

To allow for more complex functionality, not available within Git itself. View a list of commit messages (changelog-style) between two SHAs, branches, or tags with g changes master production by adding this alias: alias.changes "!f() { git log --pretty=format:'* %s' $1..$2; }; f"

Frequent Commands

Helpful Commands

g lg

sample output from 'g lg'

g details a237db5

sample output from 'g details a237db5'

Step 3: Git Add-Ons

Git Completion

Autocompletes branch names and commands by typing a few characters and hitting Tab. Simple(ish) to implement, too.

  1. Install bash-completion:

    brew install bash-completion
  2. And then add this to your Bash config to load completion scripts from Homebrew packages:

    [ -f `brew --prefix`/etc/bash_completion ] && . `brew -- prefix`/etc/bash_completion
  3. And enable completion for your g alias in addition to git:

    complete -o default -o nospace -F _git g

g co lac[TAB]

sample output from 'g co lac[TAB]'

__git_ps1

Another great part of Git’s completion is the __git_ps1 function. It spits out information about your Git repository, useful for putting in your $PS1 (your shell prompt).

\w $(rvm-prompt i v 2> /dev/null)\[\e[1m\] $(__git_ps1 2> /dev/null)\[\e[0m\] \n$
~/workspace/ngin ree-1.8.7 (master $=)
$

Configurable with environment variables.

g wtf

Emulates Mercurial’s hg incoming and hg outgoing commands. showing you unpushed commits and fetched commits which aren't yet merged. When __git_ps1 shows you > or <, g wtf gives you some more details.

Download from http://gitorious.org/willgit/mainline/blobs/master/bin/git-wtf and put it somewhere in your $PATH.

g wtf

sample output from 'g wtf'

git-extras

A nice third-party set of additional Git commands. Nothing life-changing, but some improved quality-of-life. For more details, check out its GitHub project page.

brew install git-extras

That’s about all I use, but there's loads more.

Questions?