Improving the Behavior of the cd Command in Git Repositories

| Comments

Most people are probably aware that calling the cd command without any arguments will take you back to your home directory. If you’re anything like me, you probably do this dozens of times each day.

I also end up working in git repositories quite a bit, and when I am working in a git repository I regularly find myself wanting to return to the root of the repository. Most of the time I am not buried too deep and it just takes one or two cd .. commands to climb up to where I want to be.

This seemed a bit silly to me. I’d rather not have to count how many levels deep I am. I decided that it would be a good idea to overload the cd command. Now, if I am in deep inside a git repository and call cd with no arguments, it will pop me straight up to the root. If I am at the root of a git repository or not in a repository at all, it will take the usual action and return me to my home directory.

screenshot of gitcd in action

Here is the code:

git_cd function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
_git_cd() {
  if [[ "$1" != "" ]]; then
    cd "$@"
  else
    local OUTPUT
    OUTPUT="$(git rev-parse --show-toplevel 2>/dev/null)"
    if [[ -e "$OUTPUT" ]]; then
      if [[ "$OUTPUT" != "$(pwd)" ]]; then
        cd "$OUTPUT"
      else
        cd
      fi
    else
      cd 
    fi
  fi
}

alias cd=_git_cd

Update 2012-11-13: I found more code!

I found another small, helpful shell function that I’ve been using to augment the cd command. I have no idea where this little function came from. It has probably been in my config for quite a long time.

Screenshot of improved gitcd in action

If cd is given an existing file as the argument, this function will change to the directory containing that file. If not, it will just do what cd would normally do. I’m ever so slightly surprised that this function plays nicely with _git_cd!

Here is (very simple) the “cd-to-file” function:

cd to file function
1
2
3
4
5
6
7
8
9
cd () {
  if [[ -f "$1" ]]; then
    builtin cd $(dirname "$1")
  elif [[ "$1" == "" ]]; then
    builtin cd
  else
    builtin cd "$1"
  fi
}

Both the cd function and _git_cd function work using zsh or bash.

Comments