Show the current Git, Mercurial, Subversion or Bazaar branch in your prompt

This bash script prefixes the prompt with the branch name whenever the working directory is in a Git, Mercurial, Subversion or Bazaar branch.  The code is part of my bash-environ package.  Here it is on Ubuntu Pastebin, and a plaint-text download.

The script modifies PS1 to reference the branch function which detects .git/.hg/.svn/.bzr version control systems and formats the branch name for the prompt.  branch minimises calls to external commands and avoids "bzr nick" entirely, so there should be no noticeable delay in displaying the prompt.

Using dirname-ng (cl_dirname) will provide dirname as a function which is 10x faster than /usr/bin/dirname, for slightly faster check for .bzr, .git, .hg, .svn directories.

Update: Added Subversion checkout detection
Update: Removed use of "bzr nick", examine branch.conf & location files directly
Update: Used __git_ps1 pointed out by Anon.  Removed env vars.
Update: Quoted all values to prevent word splitting when path contains spaces.

## Print nickname for git/hg/bzr/svn version control in CWD
## Optional $1 of format string for printf, default "(%s) "
function be_get_branch {
  local dir="$PWD"
  local vcs
  local nick
  while [[ "$dir" != "/" ]]; do
    for vcs in git hg svn bzr; do
      if [[ -d "$dir/.$vcs" ]] && hash "$vcs" &>/dev/null; then
        case "$vcs" in
          git) __git_ps1 "${1:-(%s) }"; return;;
          hg) nick=$(hg branch 2>/dev/null);;
          svn) nick=$(svn info 2>/dev/null\
                | grep -e '^Repository Root:'\
                | sed -e 's#.*/##');;
          bzr)
            local conf="${dir}/.bzr/branch/branch.conf" # normal branch
            [[ -f "$conf" ]] && nick=$(grep -E '^nickname =' "$conf" | cut -d' ' -f 3)
            conf="${dir}/.bzr/branch/location" # colo/lightweight branch
            [[ -z "$nick" ]] && [[ -f "$conf" ]] && nick="$(basename "$(< $conf)")"
            [[ -z "$nick" ]] && nick="$(basename "$(readlink -f "$dir")")";;
        esac
        [[ -n "$nick" ]] && printf "${1:-(%s) }" "$nick"
        return 0
      fi
    done
    dir="$(dirname "$dir")"
  done
}

## Add branch to PS1 (based on $PS1 or $1), formatted as $2
export GIT_PS1_SHOWDIRTYSTATE=yes
export PS1="\$(be_get_branch "$2")${PS1}";

Popular posts from this blog

Cutting down on clutter with the Outbox Method

A comparison of file synchronisation software