Skip to content

Instantly share code, notes, and snippets.

@ticchen
Last active December 8, 2021 01:21
Show Gist options
  • Save ticchen/afaea1341084a91be37f to your computer and use it in GitHub Desktop.
Save ticchen/afaea1341084a91be37f to your computer and use it in GitHub Desktop.
gcd: it's "cd" command for git. It would change working directory based on git top directory.
#!/bin/bash
#
# gcd: It's "cd" command based on git top directory.
# It support fallback mode when current directory is no in a git repo.
# In fallback mode, it works as like as "cd" command.
#
# How to Use:
# enable gcd command by source this file in your ".bash_aliases" or ".bashrc".
# . gcd
# -- OR --
# source gcd
#
# Caution:
# Current implemention is based on bash complete for "cd" command.
# It would use _cd() funcion, which it may be defined in somewhere below:
# /etc/bash_completion
# /usr/share/bash-completion/bash_completion
export _cd
# check requirement
typeset -f _cd >/dev/null || return
command -v git >/dev/null || return
# complete function for gcd
_gcd_topdir()
{
local topdir
topdir="$(git rev-parse --show-toplevel 2>/dev/null)"
if [ -d "${topdir}" ]; then
echo "${topdir}"
return 0
fi
topdir="$(git rev-parse --git-dir 2>/dev/null)"
if [ -d "${topdir}" ]; then
readlink -f "${topdir}/../"
return 0
fi
}
## complete function
_gcd()
{
local topdir
topdir="$(_gcd_topdir)"
# save origin CDPATH
OLDCDPATH="${CDPATH}"
# hack CDPATH and do _cd
CDPATH="${topdir}:${CDPATH}"
_cd
# restore origin CDPATH
CDPATH="${OLDCDPATH}"
return 0
}
## command function
gcd()
{
local target_dir
local topdir
target_dir="${1}"
topdir="$(_gcd_topdir)"
if [ "${target_dir}" = "-" ]; then
# switch mode
cd - || return
elif [ -d "${topdir}" ] && [ -d "${topdir}/${target_dir}" ]; then
# git top mode
cd "${topdir}/${target_dir}" || return
else
# fallback mode
cd "${target_dir}" || return
fi
}
# enable auto complete
complete -o nospace -F _gcd gcd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment