Today, I Learned...

by Justin Campbell

< All

PROMPT_COMMAND, and a simpler git prompt

I love knowing my current git status. Knowing the current branch and what files have changed gives me great perspective on where I am, and what I need to do next.

I have a git prompt that I've been using for a while:

old git status

It's large (708 lines!) and I have no idea what it's doing. Sometimes it's really slow.

I began searching for a simpler solution. There's another script in git-contrib, but at >400 lines, it's not much simpler, especially since the other script also handles SVN and hg. There's also git-situational-awareness, which doesn't really show me enough.

So what do I want to see?

git status

(If you don't see color output, make sure you have git config --global color.ui true set.)

That's quite verbose. Looking at the git-status man page, there's an option called --short.

git status --short

Beautiful! But it doesn't tell us what branch we're on. So let's add --branch.

git status --short --branch

Perfect! So how do I get this above my prompt?

There's a bash environment variable called PROMPT_COMMAND:

PROMPT_COMMAND

Great! Let's put this in our ~/.profile:

PROMPT_COMMAND='git status --branch --short'

PROMPT_COMMAND can also call a bash function. We can put more complex code in a separate file and source that from ~/.profile. After some iterating, I ended up on the following code:

#!/bin/bash

prompt_command() {
  # Only run this if we have a .git directory
  [[ -d .git ]] &&
  # If we just ran `git status`, don't run it again
  [[ `history 1` != *'git status'* ]] &&
  # Don't show every untracked file in a directory
  git status --branch --short --untracked=normal
}

PROMPT_COMMAND='prompt_command'

Overall I like this a lot more than my previous script. It's a lot faster, and it even shows when my current branch is ahead or behind of the remote.

remote tracking status

Check out the full version I use with prettier colors, PS1 error codes, and rainbow prompts here: prompt.sh in justincampbell/.dotfiles.

October 24th, 2013