geewax.org home blog projects open source

git Workspace Magic in bash

I have lots of projects in PyDev in Eclipse all of which I navigate through with the terminal in Ubuntu (this blog’s source is one of them), so just recently with the help of a couple co-workers I put together some bash methods for moving around my projects easily.

I found that the common pattern was:

jj@im-jj:~$ cd workspace/dashboard/src/
jj@im-jj:~/workspace/dashboard/src$ source environment/bin/activate
(environment)jj@im-jj:~/workspace/dashboard/src$ deactivate 
jj@im-jj:~/workspace/dashboard/src$ cd ../../reportingdb/src/
jj@im-jj:~/workspace/reportingdb/src$ source environment/bin/activate
(environment)jj@im-jj:~/workspace/reportingdb/src$ 

The first thing I wanted was to know which project I was in and which branch in git that I was on. With a couple of helper methods this is actually pretty easy and just involves overwriting the PS1 environment variable.

# Git stuff:
function get_repository {
    pwd | grep $HOME'/workspace/.*/src.*' | awk -F/ '{print "("$5")"}'
}
function get_branch {
    git branch 2> /dev/null | grep \* | awk '{print "("$2")"}'
}

# Update PS1
PS1="\[\033[01;34m\]\$(get_repository)\[\033[31m\]\$(get_branch)\[\033[37m\]\[\033[00m\]\[\033[38m\]\u@\h:\w$ "

Now my prompt lets me know pretty acurately where I am in my source:

(environment)(dashboard)(master)jj@im-jj:~/workspace/dashboard/src$ git branch test
(environment)(dashboard)(master)jj@im-jj:~/workspace/dashboard/src$ git checkout test
Switched to branch 'test'
(environment)(dashboard)(test)jj@im-jj:~/workspace/dashboard/src$ 

The next thing I decided to add in was a command called `jumpto` which would deactivate whatever environment I’m in, jump into the proper directory, and then activate the current virtual environment for me to start working. Also, I wanted just `jumpto` with no arguments to bring me back to my home directory and exit out of any virtual environments.

The end result of this was the following:

function jumpto {
    if [ -z "$1" ]; then
        deactivate 2>/dev/null
        cd $HOME
        return 0
    fi

    local DIRECTORY=$HOME/workspace/$1/src

    if [ -d $DIRECTORY ]; then
        deactivate 2>/dev/null
        cd $DIRECTORY
        if [ -d $DIRECTORY/environment ]; then
            source $DIRECTORY/environment/bin/activate
        fi
    else
        echo "Invalid workspace! ($1)"
    fi
}

This made moving around pretty easy:

jj@im-jj:~$ jumpto dashboard
(environment)(dashboard)(master)jj@im-jj:~/workspace/dashboard/src$ jumpto reportingdb
(environment)(reportingdb)(master)jj@im-jj:~/workspace/reportingdb/src$ jumpto 
jj@im-jj:~$ 

The next thing I wanted was to do tab-completion based on the projects that I had set up in my `~/workspace/` directory. After some research on how tab completion works in the first place, I ended up with the following:

_jumpto() {
    local IFS=$'\t\n'
    local dirs=("$HOME/workspace/")

    COMPREPLY=( $(
        for dir in "${dirs}"; do
            cd "$dir" 2 >/dev/null &&
            compgen -d -- "${COMP_WORDS[COMP_CWORD]}"
        done
    ) )
    return 0
}

complete -o filenames -o nospace -F _jumpto jumpto

This lets me do things like `ju[tab] das[tab]` and end up in the dashboard project with the virtual environment all set up and ready to go.

I hope this helps somebody else out who’s working with lots of git projects with lots of different branches and virtual environments for each of them.

Posted on 15 Nov 2009