Skip to content

Instantly share code, notes, and snippets.

@KeyAmam
Last active January 1, 2022 12:55
Show Gist options
  • Save KeyAmam/2cde31a9c2ca4b1af44251c3ac628dec to your computer and use it in GitHub Desktop.
Save KeyAmam/2cde31a9c2ca4b1af44251c3ac628dec to your computer and use it in GitHub Desktop.
Wrapper functions for cd and git to swtich SSH hosts on "git clone" depending on which directory you are in
# What this does
# Switch SSH hosts on "git clone" depending on where you run it:
# Run "git clone" in a subdirectory of "work" -> Your work account clones the repo
# Run "git clone" in a subdirectory of "private" -> Your private account clones the repo
# How to configure
# 1. Create directories ~/work and ~/private
# 2. Configure SSH hosts in ~/.ssh/config and set public keys to your Github accounts
# 3. Define these functions in an rc file (.bashrc or whatever you are using)
# 4. Modify environment variables below
# 5. (Optional) Create ~/.scripts/git-set-gpg-key.sh with https://gist.github.com/KeyAmam/74d4aefcd161410bf1487714b829a6ce and uncomment line 68 below.
# 6. Run source command (Nothing happens)
# You can run "type git" and "echo $GIT_PARENT_DIR_BASENAME" to see if those functions are configured properly
# Note
# This script doesn't work well with specifying a target directory on git clone
# Make sure you are in a directory you want to clone to and run git clone
# To prevent it from overriding the default behavior in ~/private and ~/work,
# use --force-url option like so:
# git clone --force-url [email protected]:some_user/some_repo.git
GIT_USER_NAME_WORK='work user'
GIT_USER_EMAIL_WORK='work email'
GIT_SSH_NAME_WORK='github_w'
GIT_USER_NAME_PRIVATE='KeyAmam'
GIT_USER_EMAIL_PRIVATE='[email protected]'
GIT_SSH_NAME_PRIVATE='github_p'
WORK_DIR_BASENAME='work'
PRIVATE_DIR_BASENAME='private'
function __clone() {
local git_parent_dir="$1"; shift
case $git_parent_dir in
work)
local git_user_name="$GIT_USER_NAME_WORK"
local git_user_email="$GIT_USER_EMAIL_WORK"
local git_ssh_name="$GIT_SSH_NAME_WORK"
;;
private)
local git_user_name="$GIT_USER_NAME_PRIVATE"
local git_user_email="$GIT_USER_EMAIL_PRIVATE"
local git_ssh_name="$GIT_SSH_NAME_PRIVATE"
;;
*)
;;
esac
if ! printf '%s\n' "$@" | grep -q '^--force-url$'; then
# Replace the first occurrence of "[email protected]" with GIT_SSH_NAME_REPLACED_WITH and reassign $@
# GIT_SSH_NAME_REPLACED_WITH is passed from define_git()
set -- $(echo "$@" | sed "s/[email protected]/$git_ssh_name/")
echo -e " URL overridden: git $@"
fi
# git clone
command git "$@" &&
# navigate to root dir of repo
cd $(basename ${1%.*}) &&
# configure .git/config
(
command git config --local user.name "$git_user_name"
command git config --local user.email "$git_user_email"
command git config --local url."$git_ssh_name".insteadOf "[email protected]"
# if you want to set gpg key to git, put this gist() to ~/.scripts/git-set-gpg-key.sh and uncomment below
# ~/.scripts/git-set-gpg-key.sh
)
}
function define_git() {
# defined globally since used in nested definition
GIT_PARENT_DIR_BASENAME="$1"
if [ -z "$GIT_PARENT_DIR_BASENAME" ]; then
# if GIT_SSH_NAME_REPLACED_WITH is not specified, put back to default behavior
function __git() {
command git "$@"
}
else
function __git() {
# $1 and $@ are different from those of define_git()
# When running git clone without --force-url
if [[ "$1" == "clone" ]]; then
__clone "$GIT_PARENT_DIR_BASENAME" "$@"
else
command git "$@"
fi
}
fi
alias git=__git
}
function __cd () {
command cd "$@"
# if subdirectory of "work"
if [[ "${PWD#$HOME/$WORK_DIR_BASENAME}" != "$PWD" ]]; then
define_git "$WORK_DIR_BASENAME"
# if subdirectory of "private"
elif [[ "${PWD#$HOME/$PRIVATE_DIR_BASENAME}" != "$PWD" ]]; then
define_git "$PRIVATE_DIR_BASENAME"
# unless subdirectory of "work" or "private"
else
# put back to default behavior
define_git
fi
}
alias cd=__cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment